This commit is contained in:
2026-01-06 08:03:04 +00:00
parent 84e0c00b6b
commit a1bafcf578
169 changed files with 10810 additions and 8723 deletions

View File

@@ -1,48 +1,17 @@
---
name: block-ignore-preexisting
enabled: true
event: stop
event: assistant
action: block
pattern: .*
pattern: (this\s+(is\s+a\s+)?pre-existing|already\s+existed\s+before|not\s+introduced\s+by\s+(this|my)|was\s+there\s+before\s+(I|my)|unrelated\s+to\s+(current|my)\s+changes|that('s|\s+is)\s+out\s+of\s+scope|skip(ping)?\s+.{0,20}(pre-existing|existed)|ignor(e|ing)\s+.{0,20}(pre-existing|existed))
---
🚫 **Policy Violation: Pre-existing Issues Cannot Be Ignored**
You MUST NOT dismiss or ignore issues because they existed before your changes. This includes:
- Lint errors
- Type errors
- Test failures
- Code quality warnings
- Any other reported issues
You cannot dismiss issues because they "existed before." All visible issues must be:
**Forbidden phrases (what triggered this):**
- "pre-existing issue"
- "already existed"
- "not introduced by this change"
- "was there before"
- "unrelated to current changes"
- "out of scope"
1. **Fixed immediately** (simple issues)
2. **Added to TodoWrite** (complex issues)
3. **Assigned to subagent** (parallelizable fixes)
**Required actions when encountering issues:**
1. **Add to task list** (preferred for complex issues):
```
Use TodoWrite to add the issue as a pending task
```
2. **Launch subagent to fix** (for parallelizable fixes):
```
Use Task tool with appropriate subagent to fix asynchronously
```
3. **Fix immediately** (for simple issues):
```
Address the issue as part of current work
```
**Project policy:** ALL issues visible during a session must be either fixed or tracked. Claiming something is "pre-existing" is not a valid reason to ignore it.
**If the issue is truly out of scope:**
- Still add it to the todo list with status "pending"
- Or create a triage note in docs/triage.md
- NEVER just dismiss it
**Project policy:** Claiming "pre-existing" is NOT a valid reason to ignore issues.

View File

@@ -2,36 +2,18 @@
name: require-make-quality
enabled: true
event: stop
action: block
action: warn
pattern: .*
---
🛑 **Quality Gate: Run `make quality` Before Completing**
⚠️ **Quality Gate Reminder**
You MUST run the quality checks before ending this conversation turn.
If you made **any code changes** during this session (Edit, Write, MultiEdit, or spawned subagents), ensure you ran:
**Required command:**
```bash
cd /home/trav/repos/noteflow && make quality
make quality
```
**This is required when:**
- ✅ Any code changes were made (Edit, Write, MultiEdit)
- ✅ Any subagent was spawned (Task tool)
- ✅ Any file modifications occurred
**This checks:** basedpyright, ruff, tests/quality/
**What `make quality` checks:**
- Type checking (basedpyright/mypy)
- Linting (ruff)
- Test smell detection (tests/quality/)
- Code formatting verification
**If quality checks fail:**
1. Fix the reported issues
2. Run `make quality` again
3. Only then complete the conversation turn
**If no code changes were made:**
You can acknowledge this reminder and proceed - but verify no files were modified.
**Project policy:** All code changes must pass quality gates before completion. This prevents broken code from being committed.
**If you only did reads/research/dialog:** This reminder can be ignored.

View File

@@ -1,766 +1,13 @@
{
"version": "1.36.1",
"time": "1767655241469",
"generalDiagnostics": [
{
"file": "/home/trav/repos/noteflow/src/noteflow/application/services/meeting_service.py",
"severity": "error",
"message": "Type of \"key_points\" is partially unknown\n  Type of \"key_points\" is \"Any | list[Unknown]\"",
"range": {
"start": {
"line": 227,
"character": 8
},
"end": {
"line": 227,
"character": 18
}
},
"rule": "reportUnknownVariableType"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/application/services/meeting_service.py",
"severity": "error",
"message": "Type of \"action_items\" is partially unknown\n  Type of \"action_items\" is \"Any | list[Unknown]\"",
"range": {
"start": {
"line": 228,
"character": 8
},
"end": {
"line": 228,
"character": 20
}
},
"rule": "reportUnknownVariableType"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/application/services/meeting_service.py",
"severity": "error",
"message": "Argument type is partially unknown\n  Argument corresponds to parameter \"key_points\" in function \"__init__\"\n  Argument type is \"Any | list[Unknown]\"",
"range": {
"start": {
"line": 234,
"character": 23
},
"end": {
"line": 234,
"character": 33
}
},
"rule": "reportUnknownArgumentType"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/application/services/meeting_service.py",
"severity": "error",
"message": "Argument type is partially unknown\n  Argument corresponds to parameter \"action_items\" in function \"__init__\"\n  Argument type is \"Any | list[Unknown]\"",
"range": {
"start": {
"line": 235,
"character": 25
},
"end": {
"line": 235,
"character": 37
}
},
"rule": "reportUnknownArgumentType"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/application/services/meeting_service.py",
"severity": "error",
"message": "Type of \"annotation_type\" is unknown",
"range": {
"start": {
"line": 276,
"character": 8
},
"end": {
"line": 276,
"character": 23
}
},
"rule": "reportUnknownVariableType"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/application/services/meeting_service.py",
"severity": "error",
"message": "Type of \"start_time\" is unknown",
"range": {
"start": {
"line": 278,
"character": 8
},
"end": {
"line": 278,
"character": 18
}
},
"rule": "reportUnknownVariableType"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/application/services/meeting_service.py",
"severity": "error",
"message": "Type of \"end_time\" is unknown",
"range": {
"start": {
"line": 279,
"character": 8
},
"end": {
"line": 279,
"character": 16
}
},
"rule": "reportUnknownVariableType"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/application/services/meeting_service.py",
"severity": "error",
"message": "Type of \"segment_ids\" is partially unknown\n  Type of \"segment_ids\" is \"Any | list[Unknown]\"",
"range": {
"start": {
"line": 280,
"character": 8
},
"end": {
"line": 280,
"character": 19
}
},
"rule": "reportUnknownVariableType"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/application/services/meeting_service.py",
"severity": "error",
"message": "Argument type is unknown\n  Argument corresponds to parameter \"annotation_type\" in function \"__init__\"",
"range": {
"start": {
"line": 284,
"character": 28
},
"end": {
"line": 284,
"character": 43
}
},
"rule": "reportUnknownArgumentType"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/application/services/meeting_service.py",
"severity": "error",
"message": "Argument type is unknown\n  Argument corresponds to parameter \"start_time\" in function \"__init__\"",
"range": {
"start": {
"line": 286,
"character": 23
},
"end": {
"line": 286,
"character": 33
}
},
"rule": "reportUnknownArgumentType"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/application/services/meeting_service.py",
"severity": "error",
"message": "Argument type is unknown\n  Argument corresponds to parameter \"end_time\" in function \"__init__\"",
"range": {
"start": {
"line": 287,
"character": 21
},
"end": {
"line": 287,
"character": 29
}
},
"rule": "reportUnknownArgumentType"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/application/services/meeting_service.py",
"severity": "error",
"message": "Argument type is partially unknown\n  Argument corresponds to parameter \"segment_ids\" in function \"__init__\"\n  Argument type is \"Any | list[Unknown]\"",
"range": {
"start": {
"line": 288,
"character": 24
},
"end": {
"line": 288,
"character": 35
}
},
"rule": "reportUnknownArgumentType"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/application/services/meeting_service.py",
"severity": "error",
"message": "Type of \"value\" is unknown",
"range": {
"start": {
"line": 298,
"character": 32
},
"end": {
"line": 298,
"character": 53
}
},
"rule": "reportUnknownMemberType"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/domain/entities/named_entity.py",
"severity": "error",
"message": "Type of \"segment_ids\" is unknown",
"range": {
"start": {
"line": 118,
"character": 8
},
"end": {
"line": 118,
"character": 19
}
},
"rule": "reportUnknownVariableType"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/domain/entities/named_entity.py",
"severity": "error",
"message": "Type of \"unique_segments\" is partially unknown\n  Type of \"unique_segments\" is \"list[Unknown]\"",
"range": {
"start": {
"line": 127,
"character": 8
},
"end": {
"line": 127,
"character": 23
}
},
"rule": "reportUnknownVariableType"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/domain/entities/named_entity.py",
"severity": "error",
"message": "Argument type is partially unknown\n  Argument corresponds to parameter \"iterable\" in function \"sorted\"\n  Argument type is \"set[Unknown]\"",
"range": {
"start": {
"line": 127,
"character": 33
},
"end": {
"line": 127,
"character": 49
}
},
"rule": "reportUnknownArgumentType"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/domain/entities/named_entity.py",
"severity": "error",
"message": "Argument type is unknown\n  Argument corresponds to parameter \"iterable\" in function \"__init__\"",
"range": {
"start": {
"line": 127,
"character": 37
},
"end": {
"line": 127,
"character": 48
}
},
"rule": "reportUnknownArgumentType"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/domain/entities/named_entity.py",
"severity": "error",
"message": "Argument type is partially unknown\n  Argument corresponds to parameter \"segment_ids\" in function \"__init__\"\n  Argument type is \"list[Unknown]\"",
"range": {
"start": {
"line": 133,
"character": 24
},
"end": {
"line": 133,
"character": 39
}
},
"rule": "reportUnknownArgumentType"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/domain/ports/__init__.py",
"severity": "error",
"message": "Operation on \"__all__\" is not supported, so exported symbol list may be incorrect",
"range": {
"start": {
"line": 27,
"character": 0
},
"end": {
"line": 46,
"character": 1
}
},
"rule": "reportUnsupportedDunderAll"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/domain/ports/repositories/__init__.py",
"severity": "error",
"message": "Operation on \"__all__\" is not supported, so exported symbol list may be incorrect",
"range": {
"start": {
"line": 35,
"character": 0
},
"end": {
"line": 51,
"character": 1
}
},
"rule": "reportUnsupportedDunderAll"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/domain/ports/repositories/identity/__init__.py",
"severity": "error",
"message": "Operation on \"__all__\" is not supported, so exported symbol list may be incorrect",
"range": {
"start": {
"line": 13,
"character": 0
},
"end": {
"line": 18,
"character": 1
}
},
"rule": "reportUnsupportedDunderAll"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/grpc/_client_mixins/annotation.py",
"severity": "error",
"message": "Type of \"annotation_type\" is unknown",
"range": {
"start": {
"line": 64,
"character": 12
},
"end": {
"line": 64,
"character": 27
}
},
"rule": "reportUnknownVariableType"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/grpc/_client_mixins/annotation.py",
"severity": "error",
"message": "Type of \"start_time\" is unknown",
"range": {
"start": {
"line": 66,
"character": 12
},
"end": {
"line": 66,
"character": 22
}
},
"rule": "reportUnknownVariableType"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/grpc/_client_mixins/annotation.py",
"severity": "error",
"message": "Type of \"end_time\" is unknown",
"range": {
"start": {
"line": 67,
"character": 12
},
"end": {
"line": 67,
"character": 20
}
},
"rule": "reportUnknownVariableType"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/grpc/_client_mixins/annotation.py",
"severity": "error",
"message": "Type of \"segment_ids\" is partially unknown\n  Type of \"segment_ids\" is \"Any | list[Unknown]\"",
"range": {
"start": {
"line": 68,
"character": 12
},
"end": {
"line": 68,
"character": 23
}
},
"rule": "reportUnknownVariableType"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/grpc/_client_mixins/annotation.py",
"severity": "error",
"message": "Argument type is unknown\n  Argument corresponds to parameter \"annotation_type\" in function \"annotation_type_to_proto\"",
"range": {
"start": {
"line": 69,
"character": 50
},
"end": {
"line": 69,
"character": 65
}
},
"rule": "reportUnknownArgumentType"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/grpc/_client_mixins/annotation.py",
"severity": "error",
"message": "Argument type is unknown\n  Argument corresponds to parameter \"start_time\" in function \"__init__\"",
"range": {
"start": {
"line": 74,
"character": 27
},
"end": {
"line": 74,
"character": 37
}
},
"rule": "reportUnknownArgumentType"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/grpc/_client_mixins/annotation.py",
"severity": "error",
"message": "Argument type is unknown\n  Argument corresponds to parameter \"end_time\" in function \"__init__\"",
"range": {
"start": {
"line": 75,
"character": 25
},
"end": {
"line": 75,
"character": 33
}
},
"rule": "reportUnknownArgumentType"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/grpc/_client_mixins/annotation.py",
"severity": "error",
"message": "Argument type is partially unknown\n  Argument corresponds to parameter \"segment_ids\" in function \"__init__\"\n  Argument type is \"Any | list[Unknown]\"",
"range": {
"start": {
"line": 76,
"character": 28
},
"end": {
"line": 76,
"character": 39
}
},
"rule": "reportUnknownArgumentType"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/grpc/_mixins/errors/__init__.py",
"severity": "error",
"message": "Import \"MeetingId\" is not accessed",
"range": {
"start": {
"line": 62,
"character": 46
},
"end": {
"line": 62,
"character": 55
}
},
"rule": "reportUnusedImport"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/grpc/_mixins/protocols.py",
"severity": "error",
"message": "Import \"ExportRepositoryProvider\" is not accessed",
"range": {
"start": {
"line": 21,
"character": 56
},
"end": {
"line": 21,
"character": 80
}
},
"rule": "reportUnusedImport"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/infrastructure/persistence/models/__init__.py",
"severity": "error",
"message": "Import \"MeetingModel\" is not accessed",
"range": {
"start": {
"line": 31,
"character": 4
},
"end": {
"line": 31,
"character": 16
}
},
"rule": "reportUnusedImport"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/infrastructure/persistence/models/__init__.py",
"severity": "error",
"message": "Import \"UserModel\" is not accessed",
"range": {
"start": {
"line": 50,
"character": 4
},
"end": {
"line": 50,
"character": 13
}
},
"rule": "reportUnusedImport"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/infrastructure/persistence/models/__init__.py",
"severity": "error",
"message": "Import \"WorkspaceModel\" is not accessed",
"range": {
"start": {
"line": 53,
"character": 4
},
"end": {
"line": 53,
"character": 18
}
},
"rule": "reportUnusedImport"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/infrastructure/persistence/models/__init__.py",
"severity": "error",
"message": "Import \"IntegrationModel\" is not accessed",
"range": {
"start": {
"line": 60,
"character": 4
},
"end": {
"line": 60,
"character": 20
}
},
"rule": "reportUnusedImport"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/infrastructure/persistence/models/__init__.py",
"severity": "error",
"message": "Import \"TaskModel\" is not accessed",
"range": {
"start": {
"line": 72,
"character": 4
},
"end": {
"line": 72,
"character": 13
}
},
"rule": "reportUnusedImport"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/infrastructure/persistence/models/__init__.py",
"severity": "error",
"message": "Operation on \"__all__\" is not supported, so exported symbol list may be incorrect",
"range": {
"start": {
"line": 75,
"character": 0
},
"end": {
"line": 116,
"character": 1
}
},
"rule": "reportUnsupportedDunderAll"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/infrastructure/persistence/models/core/__init__.py",
"severity": "error",
"message": "Import \"MeetingModel\" is not accessed",
"range": {
"start": {
"line": 8,
"character": 4
},
"end": {
"line": 8,
"character": 16
}
},
"rule": "reportUnusedImport"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/infrastructure/persistence/models/core/__init__.py",
"severity": "error",
"message": "Operation on \"__all__\" is not supported, so exported symbol list may be incorrect",
"range": {
"start": {
"line": 19,
"character": 0
},
"end": {
"line": 29,
"character": 1
}
},
"rule": "reportUnsupportedDunderAll"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/infrastructure/persistence/models/entities/__init__.py",
"severity": "error",
"message": "Operation on \"__all__\" is not supported, so exported symbol list may be incorrect",
"range": {
"start": {
"line": 10,
"character": 0
},
"end": {
"line": 14,
"character": 1
}
},
"rule": "reportUnsupportedDunderAll"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/infrastructure/persistence/models/identity/__init__.py",
"severity": "error",
"message": "Import \"UserModel\" is not accessed",
"range": {
"start": {
"line": 5,
"character": 4
},
"end": {
"line": 5,
"character": 13
}
},
"rule": "reportUnusedImport"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/infrastructure/persistence/models/identity/__init__.py",
"severity": "error",
"message": "Import \"WorkspaceModel\" is not accessed",
"range": {
"start": {
"line": 7,
"character": 4
},
"end": {
"line": 7,
"character": 18
}
},
"rule": "reportUnusedImport"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/infrastructure/persistence/models/identity/__init__.py",
"severity": "error",
"message": "Operation on \"__all__\" is not supported, so exported symbol list may be incorrect",
"range": {
"start": {
"line": 15,
"character": 0
},
"end": {
"line": 23,
"character": 1
}
},
"rule": "reportUnsupportedDunderAll"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/infrastructure/persistence/models/integrations/__init__.py",
"severity": "error",
"message": "Import \"IntegrationModel\" is not accessed",
"range": {
"start": {
"line": 5,
"character": 4
},
"end": {
"line": 5,
"character": 20
}
},
"rule": "reportUnusedImport"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/infrastructure/persistence/models/integrations/__init__.py",
"severity": "error",
"message": "Operation on \"__all__\" is not supported, so exported symbol list may be incorrect",
"range": {
"start": {
"line": 16,
"character": 0
},
"end": {
"line": 25,
"character": 1
}
},
"rule": "reportUnsupportedDunderAll"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/infrastructure/persistence/models/organization/__init__.py",
"severity": "error",
"message": "Import \"TaskModel\" is not accessed",
"range": {
"start": {
"line": 6,
"character": 73
},
"end": {
"line": 6,
"character": 82
}
},
"rule": "reportUnusedImport"
},
{
"file": "/home/trav/repos/noteflow/src/noteflow/infrastructure/persistence/models/organization/__init__.py",
"severity": "error",
"message": "Operation on \"__all__\" is not supported, so exported symbol list may be incorrect",
"range": {
"start": {
"line": 9,
"character": 0
},
"end": {
"line": 13,
"character": 1
}
},
"rule": "reportUnsupportedDunderAll"
}
],
"time": "1767682617470",
"generalDiagnostics": [],
"summary": {
"filesAnalyzed": 529,
"errorCount": 47,
"filesAnalyzed": 547,
"errorCount": 0,
"warningCount": 0,
"informationCount": 0,
"timeInSec": 11.468
"timeInSec": 11.403
}
}

View File

@@ -1 +1 @@
{"summary":{"changed":0,"unchanged":341,"matches":0,"duration":{"secs":0,"nanos":76836164},"scannerDuration":{"secs":0,"nanos":2707651},"errors":0,"warnings":1,"infos":0,"skipped":0,"suggestedFixesSkipped":0,"diagnosticsNotPrinted":0},"diagnostics":[{"category":"internalError/fs","severity":"warning","description":"Dereferenced symlink.","message":[{"elements":[],"content":"Dereferenced symlink."}],"advices":{"advices":[{"log":["info",[{"elements":[],"content":"Biome encountered a file system entry that is a broken symbolic link."}]]}]},"verboseAdvices":{"advices":[]},"location":{"path":{"file":"tauri-driver"},"span":null,"sourceCode":null},"tags":[],"source":null}],"command":"lint"}
{"summary":{"changed":0,"unchanged":357,"matches":0,"duration":{"secs":0,"nanos":78109890},"scannerDuration":{"secs":0,"nanos":2626195},"errors":0,"warnings":1,"infos":1,"skipped":0,"suggestedFixesSkipped":0,"diagnosticsNotPrinted":0},"diagnostics":[{"category":"lint/complexity/noUselessEmptyExport","severity":"information","description":"This empty export is useless because there's another export or import.","message":[{"elements":[],"content":"This empty "},{"elements":["Emphasis"],"content":"export"},{"elements":[],"content":" is useless because there's another "},{"elements":["Emphasis"],"content":"export"},{"elements":[],"content":" or "},{"elements":["Emphasis"],"content":"import"},{"elements":[],"content":"."}],"advices":{"advices":[{"log":["info",[{"elements":[],"content":"This "},{"elements":["Emphasis"],"content":"import"},{"elements":[],"content":" makes useless the empty export."}]]},{"frame":{"path":null,"span":[0,6],"sourceCode":"import type { getConnectionState } from '@/api/connection-state';\nimport type { NoteFlowAPI } from '@/api/interface';\n\ndeclare global {\n interface Window {\n __NOTEFLOW_API__?: NoteFlowAPI;\n __NOTEFLOW_CONNECTION__?: { getConnectionState: typeof getConnectionState };\n }\n}\n\nexport {};\n"}},{"log":["info",[{"elements":[],"content":"Safe fix: Remove this useless empty export."}]]},{"diff":{"dictionary":"import type { getConnectionState } from '@/api/connection-state';\nimport type { NoteFlowAPI } from '@/api/interface';\n __NOTEFLOW_CONNECTION__?: { getConnectionState: typeof getConnectionState };\n }\n}\n\nexport {};","ops":[{"diffOp":{"equal":{"range":[0,118]}}},{"equalLines":{"line_count":3}},{"diffOp":{"equal":{"range":[118,204]}}},{"diffOp":{"delete":{"range":[204,216]}}},{"diffOp":{"equal":{"range":[204,205]}}}]}}]},"verboseAdvices":{"advices":[]},"location":{"path":{"file":"src/types/window.d.ts"},"span":[281,291],"sourceCode":"import type { getConnectionState } from '@/api/connection-state';\nimport type { NoteFlowAPI } from '@/api/interface';\n\ndeclare global {\n interface Window {\n __NOTEFLOW_API__?: NoteFlowAPI;\n __NOTEFLOW_CONNECTION__?: { getConnectionState: typeof getConnectionState };\n }\n}\n\nexport {};\n"},"tags":["fixable"],"source":null},{"category":"internalError/fs","severity":"warning","description":"Dereferenced symlink.","message":[{"elements":[],"content":"Dereferenced symlink."}],"advices":{"advices":[{"log":["info",[{"elements":[],"content":"Biome encountered a file system entry that is a broken symbolic link."}]]}]},"verboseAdvices":{"advices":[]},"location":{"path":{"file":"tauri-driver"},"span":null,"sourceCode":null},"tags":[],"source":null}],"command":"lint"}

View File

@@ -5,27 +5,27 @@
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde_core@1.0.228","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde_core-1.0.228/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde_core-1.0.228/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","result","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/serde_core-c243362a1c9713c6/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde-1.0.228/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde-1.0.228/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","derive","serde_derive","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/serde-dbfd827f955688ab/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#libc@0.2.178","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/libc-0.2.178/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/libc-0.2.178/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","extra_traits","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/libc-6137998050d6cf3a/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#equivalent@1.0.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/equivalent-1.0.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"equivalent","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/equivalent-1.0.2/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libequivalent-f4aa64648d3a68e2.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libequivalent-f4aa64648d3a68e2.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#hashbrown@0.16.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/hashbrown-0.16.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"hashbrown","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/hashbrown-0.16.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libhashbrown-59be9d718f31a851.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libhashbrown-59be9d718f31a851.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#equivalent@1.0.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/equivalent-1.0.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"equivalent","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/equivalent-1.0.2/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libequivalent-f4aa64648d3a68e2.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libequivalent-f4aa64648d3a68e2.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#smallvec@1.15.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/smallvec-1.15.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"smallvec","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/smallvec-1.15.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["const_generics"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsmallvec-527f54e18ada5e74.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsmallvec-527f54e18ada5e74.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#winnow@0.5.40","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"winnow","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.5.40/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libwinnow-d240db3d2ad86e36.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libwinnow-d240db3d2ad86e36.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#pkg-config@0.3.32","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pkg-config-0.3.32/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"pkg_config","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pkg-config-0.3.32/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libpkg_config-472b2d4752e072b5.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libpkg_config-472b2d4752e072b5.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#heck@0.5.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/heck-0.5.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"heck","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/heck-0.5.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libheck-368295e68f50b2c3.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libheck-368295e68f50b2c3.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#cfg-if@1.0.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cfg-if-1.0.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"cfg_if","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cfg-if-1.0.4/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcfg_if-18a708a4a0d70bfc.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#cfg-if@1.0.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cfg-if-1.0.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"cfg_if","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cfg-if-1.0.4/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcfg_if-6237c5d2ac8fdd1c.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcfg_if-6237c5d2ac8fdd1c.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#autocfg@1.5.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/autocfg-1.5.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"autocfg","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/autocfg-1.5.0/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libautocfg-8894a47441bd56dd.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libautocfg-8894a47441bd56dd.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.103","linked_libs":[],"linked_paths":[],"cfgs":["span_locations","wrap_proc_macro","proc_macro_span_location","proc_macro_span_file"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/proc-macro2-f2c7ac76b8e89a6b/out"}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde_core@1.0.228","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/serde_core-5b4826bc37118458/out"}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228","linked_libs":[],"linked_paths":[],"cfgs":["if_docsrs_then_no_serde_core"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/serde-a502507c7bf7d410/out"}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#libc@0.2.178","linked_libs":[],"linked_paths":[],"cfgs":["freebsd12"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/libc-fe725bd454c816d7/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#indexmap@2.12.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/indexmap-2.12.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"indexmap","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/indexmap-2.12.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libindexmap-a8755f54f48ac9bf.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libindexmap-a8755f54f48ac9bf.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#autocfg@1.5.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/autocfg-1.5.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"autocfg","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/autocfg-1.5.0/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libautocfg-8894a47441bd56dd.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libautocfg-8894a47441bd56dd.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#cfg-if@1.0.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cfg-if-1.0.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"cfg_if","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cfg-if-1.0.4/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcfg_if-6237c5d2ac8fdd1c.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcfg_if-6237c5d2ac8fdd1c.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#libc@0.2.178","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/libc-0.2.178/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/libc-0.2.178/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/libc-6aecbaefac595471/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#target-lexicon@0.12.16","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/target-lexicon-0.12.16/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/target-lexicon-0.12.16/build.rs","edition":"2018","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/target-lexicon-8514eed84c37c130/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#version-compare@0.2.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/version-compare-0.2.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"version_compare","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/version-compare-0.2.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libversion_compare-8eb9fb7dcf7ed531.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libversion_compare-8eb9fb7dcf7ed531.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde_core@1.0.228","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde_core-1.0.228/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde_core-1.0.228/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","rc","result","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/serde_core-6a531a2e64d826bc/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#version_check@0.9.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/version_check-0.9.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"version_check","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/version_check-0.9.5/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libversion_check-0f6ab564ae9887d4.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libversion_check-0f6ab564ae9887d4.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.16","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pin-project-lite-0.2.16/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"pin_project_lite","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pin-project-lite-0.2.16/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libpin_project_lite-5d9e80b75b3eef3f.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#zerocopy@0.8.31","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zerocopy-0.8.31/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zerocopy-0.8.31/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["simd"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/zerocopy-2cab854a8d80d0bb/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#pin-project-lite@0.2.16","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pin-project-lite-0.2.16/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"pin_project_lite","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pin-project-lite-0.2.16/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libpin_project_lite-5d9e80b75b3eef3f.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#syn@1.0.109","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/syn-1.0.109/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/syn-1.0.109/build.rs","edition":"2018","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["clone-impls","default","derive","extra-traits","fold","full","parsing","printing","proc-macro","quote","visit"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/syn-6b2bf696cf70f196/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.103","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/proc-macro2-1.0.103/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"proc_macro2","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/proc-macro2-1.0.103/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","proc-macro","span-locations"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libproc_macro2-9e6acefd37758b9e.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libproc_macro2-9e6acefd37758b9e.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde_core@1.0.228","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde_core-1.0.228/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"serde_core","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde_core-1.0.228/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","result","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libserde_core-2fadebc569dc8ae8.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libserde_core-2fadebc569dc8ae8.rmeta"],"executable":null,"fresh":true}
@@ -65,8 +65,8 @@
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#icu_properties_data@2.1.2","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/icu_properties_data-9f6628699bfbbe1a/out"}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#getrandom@0.3.4","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/getrandom-3d0ca75c7b490a63/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#siphasher@1.0.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/siphasher-1.0.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"siphasher","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/siphasher-1.0.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsiphasher-10917cd0e13783fc.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsiphasher-10917cd0e13783fc.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#winnow@0.7.14","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.7.14/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"winnow","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.7.14/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libwinnow-86bb1b5bddd98d1d.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libwinnow-86bb1b5bddd98d1d.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#typenum@1.19.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/typenum-1.19.0/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/typenum-1.19.0/build.rs","edition":"2018","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/typenum-c7b8667111793827/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#winnow@0.7.14","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.7.14/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"winnow","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.7.14/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libwinnow-86bb1b5bddd98d1d.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libwinnow-86bb1b5bddd98d1d.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#futures-channel@0.3.31","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/futures-channel-0.3.31/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"futures_channel","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/futures-channel-0.3.31/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","futures-sink","sink","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfutures_channel-37d0325e9ee24b34.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#semver@1.0.27","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/semver-1.0.27/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"semver","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/semver-1.0.27/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","serde","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsemver-c8e75f9d00926fb3.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsemver-c8e75f9d00926fb3.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde_derive@1.0.228","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde_derive-1.0.228/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"serde_derive","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde_derive-1.0.228/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libserde_derive-cbd2153d8a943d16.so"],"executable":null,"fresh":true}
@@ -77,8 +77,8 @@
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rand_core@0.6.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rand_core-0.6.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"rand_core","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rand_core-0.6.4/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","getrandom","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librand_core-c3b1659def6f2082.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librand_core-c3b1659def6f2082.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#phf_shared@0.11.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf_shared-0.11.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"phf_shared","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf_shared-0.11.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libphf_shared-b7acdf4cecadb432.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libphf_shared-b7acdf4cecadb432.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#typenum@1.19.0","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/typenum-f643354aeae9adba/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#anyhow@1.0.100","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/anyhow-1.0.100/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/anyhow-1.0.100/build.rs","edition":"2018","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/anyhow-4f4c842113b6e891/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#pin-utils@0.1.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pin-utils-0.1.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"pin_utils","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pin-utils-0.1.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libpin_utils-419b4dfb91fea471.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#anyhow@1.0.100","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/anyhow-1.0.100/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/anyhow-1.0.100/build.rs","edition":"2018","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/anyhow-4f4c842113b6e891/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#futures-macro@0.3.31","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/futures-macro-0.3.31/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"futures_macro","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/futures-macro-0.3.31/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfutures_macro-abe2c8da41b4406a.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#toml_parser@1.0.6+spec-1.1.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/toml_parser-1.0.6+spec-1.1.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"toml_parser","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/toml_parser-1.0.6+spec-1.1.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtoml_parser-a73c7051c538d50a.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtoml_parser-a73c7051c538d50a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#bitflags@2.10.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bitflags-2.10.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"bitflags","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bitflags-2.10.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["serde","serde_core","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbitflags-30ee6ac28a8ca409.rmeta"],"executable":null,"fresh":true}
@@ -93,10 +93,10 @@
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#futures-task@0.3.31","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/futures-task-0.3.31/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"futures_task","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/futures-task-0.3.31/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfutures_task-de234338db6d77e0.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#getrandom@0.1.16","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/getrandom-0.1.16/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/getrandom-0.1.16/build.rs","edition":"2018","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/getrandom-66866660c5ea92be/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#log@0.4.29","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/log-0.4.29/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"log","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/log-0.4.29/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liblog-c9276305320cbeac.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde-1.0.228/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde-1.0.228/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","derive","rc","serde_derive","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/serde-49567799694f284d/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#fnv@1.0.7","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/fnv-1.0.7/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"fnv","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/fnv-1.0.7/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfnv-92dd6573194b1649.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfnv-92dd6573194b1649.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#bitflags@1.3.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bitflags-1.3.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"bitflags","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bitflags-1.3.2/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbitflags-b551d3fe3a8a6729.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde-1.0.228/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde-1.0.228/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","derive","rc","serde_derive","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/serde-49567799694f284d/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#typeid@1.0.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/typeid-1.0.3/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/typeid-1.0.3/build.rs","edition":"2018","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/typeid-59114d189c45da1d/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#bitflags@1.3.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bitflags-1.3.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"bitflags","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bitflags-1.3.2/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbitflags-b551d3fe3a8a6729.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#toml_datetime@0.6.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/toml_datetime-0.6.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"toml_datetime","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/toml_datetime-0.6.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["serde"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtoml_datetime-c429cfb79c2081eb.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtoml_datetime-c429cfb79c2081eb.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde_spanned@0.6.9","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde_spanned-0.6.9/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"serde_spanned","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde_spanned-0.6.9/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["serde"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libserde_spanned-69b6244d05459d87.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libserde_spanned-69b6244d05459d87.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rand@0.8.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rand-0.8.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"rand","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rand-0.8.5/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","getrandom","libc","rand_chacha","small_rng","std","std_rng"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librand-fd4f9e54697df591.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librand-fd4f9e54697df591.rmeta"],"executable":null,"fresh":true}
@@ -107,90 +107,90 @@
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228","linked_libs":[],"linked_paths":[],"cfgs":["if_docsrs_then_no_serde_core"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/serde-1d23b1b528bc7c0e/out"}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#typeid@1.0.3","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/typeid-b90a0ded66f868f1/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#aho-corasick@1.1.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/aho-corasick-1.1.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"aho_corasick","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/aho-corasick-1.1.4/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["perf-literal","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libaho_corasick-f3c9821dbaaa3611.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libaho_corasick-f3c9821dbaaa3611.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#writeable@0.6.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/writeable-0.6.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"writeable","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/writeable-0.6.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libwriteable-7093899f7a96fc15.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libwriteable-7093899f7a96fc15.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#regex-syntax@0.8.8","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/regex-syntax-0.8.8/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"regex_syntax","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/regex-syntax-0.8.8/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std","unicode","unicode-age","unicode-bool","unicode-case","unicode-gencat","unicode-perl","unicode-script","unicode-segment"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libregex_syntax-35bdd9f2e49c857f.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libregex_syntax-35bdd9f2e49c857f.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#once_cell@1.21.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/once_cell-1.21.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"once_cell","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/once_cell-1.21.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","race","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libonce_cell-88cad944dacc265a.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libonce_cell-88cad944dacc265a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#itoa@1.0.16","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/itoa-1.0.16/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"itoa","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/itoa-1.0.16/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libitoa-644d2fadb21ffa15.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libitoa-644d2fadb21ffa15.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#once_cell@1.21.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/once_cell-1.21.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"once_cell","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/once_cell-1.21.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","race","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libonce_cell-88cad944dacc265a.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libonce_cell-88cad944dacc265a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#litemap@0.8.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/litemap-0.8.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"litemap","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/litemap-0.8.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liblitemap-6908c2fc0d5dfb69.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liblitemap-6908c2fc0d5dfb69.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#writeable@0.6.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/writeable-0.6.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"writeable","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/writeable-0.6.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libwriteable-7093899f7a96fc15.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libwriteable-7093899f7a96fc15.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#toml_edit@0.20.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/toml_edit-0.20.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"toml_edit","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/toml_edit-0.20.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","serde"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtoml_edit-f88f2d2fb6e854af.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtoml_edit-f88f2d2fb6e854af.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#yoke@0.8.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/yoke-0.8.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"yoke","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/yoke-0.8.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["derive","zerofrom"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libyoke-ea2adc12b294eb07.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libyoke-ea2adc12b294eb07.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#phf_generator@0.11.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf_generator-0.11.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"phf_generator","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf_generator-0.11.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libphf_generator-fcb5f580321e4459.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libphf_generator-fcb5f580321e4459.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#getrandom@0.1.16","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/getrandom-0.1.16/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"getrandom","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/getrandom-0.1.16/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libgetrandom-201fe92db093183e.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libgetrandom-201fe92db093183e.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde@1.0.228","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde-1.0.228/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"serde","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde-1.0.228/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","derive","rc","serde_derive","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libserde-7742d4eb6b008c70.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.17","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/thiserror-2.0.17/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/thiserror-2.0.17/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/thiserror-40ca3b497b7e78a9/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#litemap@0.8.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/litemap-0.8.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"litemap","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/litemap-0.8.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liblitemap-6908c2fc0d5dfb69.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liblitemap-6908c2fc0d5dfb69.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#strsim@0.11.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/strsim-0.11.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"strsim","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/strsim-0.11.1/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libstrsim-b5071d94becd24a2.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libstrsim-b5071d94becd24a2.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#regex-syntax@0.8.8","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/regex-syntax-0.8.8/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"regex_syntax","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/regex-syntax-0.8.8/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std","unicode","unicode-age","unicode-bool","unicode-case","unicode-gencat","unicode-perl","unicode-script","unicode-segment"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libregex_syntax-35bdd9f2e49c857f.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libregex_syntax-35bdd9f2e49c857f.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.17","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/thiserror-2.0.17/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/thiserror-2.0.17/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/thiserror-40ca3b497b7e78a9/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#ident_case@1.0.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ident_case-1.0.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"ident_case","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ident_case-1.0.1/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libident_case-2dc10d9b37d5f124.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libident_case-2dc10d9b37d5f124.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#regex-automata@0.4.13","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/regex-automata-0.4.13/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"regex_automata","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/regex-automata-0.4.13/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","dfa-onepass","hybrid","meta","nfa-backtrack","nfa-pikevm","nfa-thompson","perf-inline","perf-literal","perf-literal-multisubstring","perf-literal-substring","std","syntax","unicode","unicode-age","unicode-bool","unicode-case","unicode-gencat","unicode-perl","unicode-script","unicode-segment","unicode-word-boundary"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libregex_automata-1b111124f30b0021.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libregex_automata-1b111124f30b0021.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#anyhow@1.0.100","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/anyhow-1.0.100/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"anyhow","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/anyhow-1.0.100/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libanyhow-1774b8d480791d46.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libanyhow-1774b8d480791d46.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#thiserror-impl@2.0.17","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/thiserror-impl-2.0.17/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"thiserror_impl","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/thiserror-impl-2.0.17/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libthiserror_impl-33bb24551c9889c6.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#erased-serde@0.4.9","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/erased-serde-0.4.9/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/erased-serde-0.4.9/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/erased-serde-d6f8b2a7a45ffe13/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#phf_shared@0.8.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf_shared-0.8.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"phf_shared","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf_shared-0.8.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libphf_shared-0b76ab534a5f2e34.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libphf_shared-0b76ab534a5f2e34.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#getrandom@0.3.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/getrandom-0.3.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"getrandom","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/getrandom-0.3.4/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libgetrandom-0a0f6f2506e4d06b.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libgetrandom-0a0f6f2506e4d06b.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#toml@0.8.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/toml-0.8.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"toml","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/toml-0.8.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["parse"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtoml-367be64a69112812.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtoml-367be64a69112812.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#zerovec@0.11.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zerovec-0.11.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"zerovec","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zerovec-0.11.5/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["derive","yoke"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzerovec-e9b9b25d56a3ac61.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzerovec-e9b9b25d56a3ac61.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rand_core@0.5.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rand_core-0.5.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"rand_core","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rand_core-0.5.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","getrandom","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librand_core-fa05633518e23043.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librand_core-fa05633518e23043.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#phf_macros@0.11.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf_macros-0.11.3/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"phf_macros","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf_macros-0.11.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libphf_macros-44c7026b70b7c62b.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#zerotrie@0.2.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zerotrie-0.2.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"zerotrie","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zerotrie-0.2.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["yoke","zerofrom"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzerotrie-352fed74e20e257a.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzerotrie-352fed74e20e257a.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.17","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/thiserror-ee85ff31b1a3071c/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#regex-automata@0.4.13","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/regex-automata-0.4.13/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"regex_automata","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/regex-automata-0.4.13/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","dfa-onepass","hybrid","meta","nfa-backtrack","nfa-pikevm","nfa-thompson","perf-inline","perf-literal","perf-literal-multisubstring","perf-literal-substring","std","syntax","unicode","unicode-age","unicode-bool","unicode-case","unicode-gencat","unicode-perl","unicode-script","unicode-segment","unicode-word-boundary"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libregex_automata-1b111124f30b0021.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libregex_automata-1b111124f30b0021.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#zerotrie@0.2.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zerotrie-0.2.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"zerotrie","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zerotrie-0.2.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["yoke","zerofrom"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzerotrie-352fed74e20e257a.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzerotrie-352fed74e20e257a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#darling_core@0.21.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/darling_core-0.21.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"darling_core","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/darling_core-0.21.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["strsim","suggestions"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdarling_core-09d76f69c0a0a7db.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdarling_core-09d76f69c0a0a7db.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#phf_macros@0.11.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf_macros-0.11.3/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"phf_macros","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf_macros-0.11.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libphf_macros-44c7026b70b7c62b.so"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#erased-serde@0.4.9","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/erased-serde-2409ba887e4a0b7e/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#regex@1.12.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/regex-1.12.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"regex","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/regex-1.12.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","perf","perf-backtrack","perf-cache","perf-dfa","perf-inline","perf-literal","perf-onepass","std","unicode","unicode-age","unicode-bool","unicode-case","unicode-gencat","unicode-perl","unicode-script","unicode-segment"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libregex-32beac5cb946916e.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libregex-32beac5cb946916e.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#getrandom@0.3.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/getrandom-0.3.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"getrandom","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/getrandom-0.3.4/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libgetrandom-0a0f6f2506e4d06b.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libgetrandom-0a0f6f2506e4d06b.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#proc-macro-hack@0.5.20+deprecated","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/proc-macro-hack-0.5.20+deprecated/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/proc-macro-hack-0.5.20+deprecated/build.rs","edition":"2018","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/proc-macro-hack-c38ca0deb00262a4/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#phf_shared@0.10.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf_shared-0.10.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"phf_shared","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf_shared-0.10.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libphf_shared-ea430e3dbabfaf2e.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libphf_shared-ea430e3dbabfaf2e.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#icu_normalizer_data@2.1.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_normalizer_data-2.1.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"icu_normalizer_data","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_normalizer_data-2.1.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libicu_normalizer_data-45a55af3745745e7.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libicu_normalizer_data-45a55af3745745e7.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#icu_properties_data@2.1.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_properties_data-2.1.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"icu_properties_data","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_properties_data-2.1.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libicu_properties_data-7f4da17781519449.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libicu_properties_data-7f4da17781519449.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#byteorder@1.5.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/byteorder-1.5.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"byteorder","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/byteorder-1.5.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbyteorder-f9fc7238e1bc5f1a.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbyteorder-f9fc7238e1bc5f1a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#system-deps@6.2.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/system-deps-6.2.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"system_deps","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/system-deps-6.2.2/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsystem_deps-37d214fc992d76de.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsystem_deps-37d214fc992d76de.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tinystr@0.8.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tinystr-0.8.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tinystr","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tinystr-0.8.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["zerovec"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtinystr-3d370ed58fe5b89a.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtinystr-3d370ed58fe5b89a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#potential_utf@0.1.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/potential_utf-0.1.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"potential_utf","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/potential_utf-0.1.4/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["zerovec"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libpotential_utf-dede564a8fa8ee5f.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libpotential_utf-dede564a8fa8ee5f.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#regex@1.12.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/regex-1.12.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"regex","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/regex-1.12.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","perf","perf-backtrack","perf-cache","perf-dfa","perf-inline","perf-literal","perf-onepass","std","unicode","unicode-age","unicode-bool","unicode-case","unicode-gencat","unicode-perl","unicode-script","unicode-segment"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libregex-32beac5cb946916e.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libregex-32beac5cb946916e.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rand_chacha@0.2.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rand_chacha-0.2.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"rand_chacha","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rand_chacha-0.2.2/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librand_chacha-c33a5f42c4fc2841.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librand_chacha-c33a5f42c4fc2841.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#darling_macro@0.21.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/darling_macro-0.21.3/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"darling_macro","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/darling_macro-0.21.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdarling_macro-4ec59b6dbde7ea54.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rand_pcg@0.2.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rand_pcg-0.2.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"rand_pcg","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rand_pcg-0.2.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librand_pcg-d05d7be2df660fdd.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librand_pcg-d05d7be2df660fdd.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#proc-macro-hack@0.5.20+deprecated","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/proc-macro-hack-b3aa3c371e0f054b/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#new_debug_unreachable@1.0.6","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/new_debug_unreachable-1.0.6/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"debug_unreachable","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/new_debug_unreachable-1.0.6/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdebug_unreachable-65e82a2b275e7606.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdebug_unreachable-65e82a2b275e7606.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#scopeguard@1.2.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/scopeguard-1.2.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"scopeguard","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/scopeguard-1.2.0/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libscopeguard-88630dd0b0352bf1.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libscopeguard-88630dd0b0352bf1.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#byteorder@1.5.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/byteorder-1.5.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"byteorder","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/byteorder-1.5.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbyteorder-f9fc7238e1bc5f1a.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbyteorder-f9fc7238e1bc5f1a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#crossbeam-utils@0.8.21","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/crossbeam-utils-0.8.21/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/crossbeam-utils-0.8.21/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/crossbeam-utils-12f6a43a9fc01710/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.146","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde_json-1.0.146/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde_json-1.0.146/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","std","unbounded_depth"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/serde_json-c18ed6e73349f0d6/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#scopeguard@1.2.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/scopeguard-1.2.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"scopeguard","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/scopeguard-1.2.0/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libscopeguard-88630dd0b0352bf1.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libscopeguard-88630dd0b0352bf1.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#new_debug_unreachable@1.0.6","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/new_debug_unreachable-1.0.6/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"debug_unreachable","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/new_debug_unreachable-1.0.6/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdebug_unreachable-65e82a2b275e7606.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdebug_unreachable-65e82a2b275e7606.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#log@0.4.29","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/log-0.4.29/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"log","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/log-0.4.29/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liblog-2bbfff408a5788ec.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liblog-2bbfff408a5788ec.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#crossbeam-utils@0.8.21","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/crossbeam-utils-0.8.21/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/crossbeam-utils-0.8.21/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/crossbeam-utils-12f6a43a9fc01710/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#phf_generator@0.10.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf_generator-0.10.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"phf_generator","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf_generator-0.10.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libphf_generator-4241c292a5098dc0.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libphf_generator-4241c292a5098dc0.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#glib-sys@0.18.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/glib-sys-0.18.1/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/glib-sys-0.18.1/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["v2_58","v2_60","v2_62","v2_64","v2_66","v2_68","v2_70"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/glib-sys-058b919e9589048b/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#gobject-sys@0.18.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gobject-sys-0.18.0/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gobject-sys-0.18.0/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["v2_58","v2_62","v2_66","v2_68","v2_70"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/gobject-sys-750fb2df7584ea9c/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#gio-sys@0.18.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gio-sys-0.18.1/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gio-sys-0.18.1/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["v2_58","v2_60","v2_62","v2_64","v2_66","v2_68","v2_70"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/gio-sys-3e992956d856ba79/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#icu_locale_core@2.1.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_locale_core-2.1.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"icu_locale_core","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_locale_core-2.1.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["zerovec"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libicu_locale_core-0fd630fdb55e4c9b.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libicu_locale_core-0fd630fdb55e4c9b.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#icu_collections@2.1.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_collections-2.1.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"icu_collections","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_collections-2.1.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libicu_collections-31ef3e6b997347f3.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libicu_collections-31ef3e6b997347f3.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#darling@0.21.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/darling-0.21.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"darling","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/darling-0.21.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","suggestions"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdarling-4bc96a190e89b639.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdarling-4bc96a190e89b639.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rand@0.7.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rand-0.7.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"rand","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rand-0.7.3/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","getrandom","getrandom_package","libc","rand_pcg","small_rng","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librand-12f11364f87f1530.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librand-12f11364f87f1530.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.146","linked_libs":[],"linked_paths":[],"cfgs":["fast_arithmetic=\"64\""],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/serde_json-6fc5d5ae49c1e8b3/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#darling@0.21.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/darling-0.21.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"darling","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/darling-0.21.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","suggestions"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdarling-4bc96a190e89b639.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdarling-4bc96a190e89b639.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#gdk-sys@0.18.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gdk-sys-0.18.2/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gdk-sys-0.18.2/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/gdk-sys-3b99ef7250809b35/build-script-build"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#crossbeam-utils@0.8.21","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/crossbeam-utils-bf661e57f4958ccc/out"}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.146","linked_libs":[],"linked_paths":[],"cfgs":["fast_arithmetic=\"64\""],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/serde_json-6fc5d5ae49c1e8b3/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#proc-macro-hack@0.5.20+deprecated","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/proc-macro-hack-0.5.20+deprecated/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"proc_macro_hack","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/proc-macro-hack-0.5.20+deprecated/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libproc_macro_hack-7f842b73d0074f0b.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#lock_api@0.4.14","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/lock_api-0.4.14/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"lock_api","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/lock_api-0.4.14/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["atomic_usize","default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liblock_api-f371427aa01ccc96.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liblock_api-f371427aa01ccc96.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#crossbeam-utils@0.8.21","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/crossbeam-utils-bf661e57f4958ccc/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#string_cache_codegen@0.5.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/string_cache_codegen-0.5.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"string_cache_codegen","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/string_cache_codegen-0.5.4/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libstring_cache_codegen-44d93d96a986da14.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libstring_cache_codegen-44d93d96a986da14.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#phf_codegen@0.11.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf_codegen-0.11.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"phf_codegen","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf_codegen-0.11.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libphf_codegen-7f488728cb7a4921.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libphf_codegen-7f488728cb7a4921.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#string_cache_codegen@0.5.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/string_cache_codegen-0.5.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"string_cache_codegen","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/string_cache_codegen-0.5.4/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libstring_cache_codegen-44d93d96a986da14.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libstring_cache_codegen-44d93d96a986da14.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#glib-sys@0.18.1","linked_libs":["glib-2.0","gobject-2.0","glib-2.0"],"linked_paths":[],"cfgs":["system_deps_have_glib_2_0","system_deps_have_gobject_2_0"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/glib-sys-4158c9a7848d7c14/out"}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#gobject-sys@0.18.0","linked_libs":["gobject-2.0","glib-2.0"],"linked_paths":[],"cfgs":["system_deps_have_gobject_2_0"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/gobject-sys-42c614aed75dd852/out"}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#gio-sys@0.18.1","linked_libs":["gio-2.0","gobject-2.0","glib-2.0"],"linked_paths":[],"cfgs":["system_deps_have_gio_2_0"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/gio-sys-42dcde97a7ad1b1f/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#icu_provider@2.1.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_provider-2.1.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"icu_provider","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_provider-2.1.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["baked"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libicu_provider-c1649d4b1e534efb.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libicu_provider-c1649d4b1e534efb.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde_with_macros@3.16.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde_with_macros-3.16.1/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"serde_with_macros","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde_with_macros-3.16.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libserde_with_macros-c5a7e3dcdafca57d.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#phf_generator@0.8.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf_generator-0.8.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"phf_generator","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf_generator-0.8.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libphf_generator-4631925ef46985aa.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libphf_generator-4631925ef46985aa.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde_with_macros@3.16.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde_with_macros-3.16.1/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"serde_with_macros","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde_with_macros-3.16.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libserde_with_macros-c5a7e3dcdafca57d.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#parking_lot_core@0.9.12","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/parking_lot_core-0.9.12/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"parking_lot_core","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/parking_lot_core-0.9.12/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libparking_lot_core-12c1209039ad0f6a.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libparking_lot_core-12c1209039ad0f6a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#proc-macro-error-attr@1.0.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/proc-macro-error-attr-1.0.4/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/proc-macro-error-attr-1.0.4/build.rs","edition":"2018","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/proc-macro-error-attr-92362dd8246541b6/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#ryu@1.0.21","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ryu-1.0.21/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"ryu","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ryu-1.0.21/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libryu-c55e517df3fb28ae.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libryu-c55e517df3fb28ae.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.11.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"bytes","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.11.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbytes-802cf41a5ee80318.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbytes-802cf41a5ee80318.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#precomputed-hash@0.1.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/precomputed-hash-0.1.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"precomputed_hash","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/precomputed-hash-0.1.1/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libprecomputed_hash-8294a540e6d86e07.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libprecomputed_hash-8294a540e6d86e07.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#mac@0.1.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/mac-0.1.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"mac","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/mac-0.1.1/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libmac-90bf4e41d1866dbc.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libmac-90bf4e41d1866dbc.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.11.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"bytes","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.11.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbytes-802cf41a5ee80318.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbytes-802cf41a5ee80318.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#ryu@1.0.21","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ryu-1.0.21/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"ryu","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ryu-1.0.21/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libryu-c55e517df3fb28ae.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libryu-c55e517df3fb28ae.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#phf_macros@0.10.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf_macros-0.10.0/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"phf_macros","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf_macros-0.10.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libphf_macros-c5118f8c58fb5a6d.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#markup5ever@0.14.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/markup5ever-0.14.1/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/markup5ever-0.14.1/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/markup5ever-2ae830af71271890/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#crossbeam-utils@0.8.21","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/crossbeam-utils-0.8.21/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"crossbeam_utils","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/crossbeam-utils-0.8.21/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcrossbeam_utils-cc5e7cc997781b11.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#glib-sys@0.18.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/glib-sys-0.18.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"glib_sys","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/glib-sys-0.18.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["v2_58","v2_60","v2_62","v2_64","v2_66","v2_68","v2_70"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libglib_sys-5416b50e0da27027.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#icu_properties@2.1.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_properties-2.1.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"icu_properties","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_properties-2.1.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["compiled_data"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libicu_properties-94db42957da9caf0.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libicu_properties-94db42957da9caf0.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#icu_normalizer@2.1.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_normalizer-2.1.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"icu_normalizer","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_normalizer-2.1.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["compiled_data"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libicu_normalizer-243204476c1f5c93.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libicu_normalizer-243204476c1f5c93.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#icu_properties@2.1.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_properties-2.1.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"icu_properties","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_properties-2.1.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["compiled_data"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libicu_properties-94db42957da9caf0.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libicu_properties-94db42957da9caf0.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#proc-macro-error-attr@1.0.4","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/proc-macro-error-attr-8a534f9a16904ebf/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#phf_codegen@0.8.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf_codegen-0.8.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"phf_codegen","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf_codegen-0.8.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libphf_codegen-97d60c4f1f562a44.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libphf_codegen-97d60c4f1f562a44.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#parking_lot@0.12.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/parking_lot-0.12.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"parking_lot","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/parking_lot-0.12.5/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libparking_lot-2f33d371d441560f.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libparking_lot-2f33d371d441560f.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#futf@0.1.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/futf-0.1.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"futf","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/futf-0.1.5/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfutf-8389052cb4bc31de.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfutf-8389052cb4bc31de.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.146","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde_json-1.0.146/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"serde_json","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde_json-1.0.146/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","std","unbounded_depth"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libserde_json-723316ac71e6684f.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libserde_json-723316ac71e6684f.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#parking_lot@0.12.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/parking_lot-0.12.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"parking_lot","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/parking_lot-0.12.5/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libparking_lot-2f33d371d441560f.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libparking_lot-2f33d371d441560f.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#phf_codegen@0.8.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf_codegen-0.8.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"phf_codegen","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf_codegen-0.8.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libphf_codegen-97d60c4f1f562a44.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libphf_codegen-97d60c4f1f562a44.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#proc-macro-error-attr@1.0.4","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/proc-macro-error-attr-8a534f9a16904ebf/out"}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#gdk-sys@0.18.2","linked_libs":["gdk-3","z","pangocairo-1.0","pango-1.0","harfbuzz","gdk_pixbuf-2.0","cairo-gobject","cairo","gobject-2.0","glib-2.0"],"linked_paths":[],"cfgs":["system_deps_have_gdk_3_0","gdk_backend=\"broadway\"","gdk_backend=\"wayland\"","gdk_backend=\"x11\""],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/gdk-sys-ed33c07aee7b7549/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#phf_macros@0.10.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf_macros-0.10.0/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"phf_macros","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf_macros-0.10.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libphf_macros-c5118f8c58fb5a6d.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#crossbeam-utils@0.8.21","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/crossbeam-utils-0.8.21/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"crossbeam_utils","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/crossbeam-utils-0.8.21/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcrossbeam_utils-cc5e7cc997781b11.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#cssparser@0.29.6","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cssparser-0.29.6/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cssparser-0.29.6/build.rs","edition":"2018","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/cssparser-c32fea58f74e0b4e/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rustc_version@0.4.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustc_version-0.4.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"rustc_version","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustc_version-0.4.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librustc_version-58979d19398225f8.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librustc_version-58979d19398225f8.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#getrandom@0.2.16","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/getrandom-0.2.16/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"getrandom","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/getrandom-0.2.16/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libgetrandom-42a757b045851c44.rmeta"],"executable":null,"fresh":true}
@@ -198,110 +198,110 @@
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#gobject-sys@0.18.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gobject-sys-0.18.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"gobject_sys","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gobject-sys-0.18.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["v2_58","v2_62","v2_66","v2_68","v2_70"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libgobject_sys-bf81566f4b3e184b.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#idna_adapter@1.2.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/idna_adapter-1.2.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"idna_adapter","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/idna_adapter-1.2.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["compiled_data"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libidna_adapter-fb3d37a83bacf478.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libidna_adapter-fb3d37a83bacf478.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#proc-macro-error@1.0.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/proc-macro-error-1.0.4/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/proc-macro-error-1.0.4/build.rs","edition":"2018","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","syn","syn-error"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/proc-macro-error-21a3de49eedbbe31/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#utf-8@0.7.6","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/utf-8-0.7.6/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"utf8","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/utf-8-0.7.6/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libutf8-8976f7a3e6278b2e.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libutf8-8976f7a3e6278b2e.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#dtoa@1.0.10","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dtoa-1.0.10/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"dtoa","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dtoa-1.0.10/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdtoa-15a2c047bc9c568c.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdtoa-15a2c047bc9c568c.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#bitflags@1.3.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bitflags-1.3.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"bitflags","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bitflags-1.3.2/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbitflags-a537dbb8805141b2.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbitflags-a537dbb8805141b2.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#percent-encoding@2.3.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/percent-encoding-2.3.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"percent_encoding","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/percent-encoding-2.3.2/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libpercent_encoding-cb1f44110c863152.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libpercent_encoding-cb1f44110c863152.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#utf-8@0.7.6","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/utf-8-0.7.6/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"utf8","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/utf-8-0.7.6/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libutf8-8976f7a3e6278b2e.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libutf8-8976f7a3e6278b2e.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#toml_writer@1.0.6+spec-1.1.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/toml_writer-1.0.6+spec-1.1.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"toml_writer","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/toml_writer-1.0.6+spec-1.1.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtoml_writer-a10c1473507a42e4.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtoml_writer-a10c1473507a42e4.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#utf8_iter@1.0.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/utf8_iter-1.0.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"utf8_iter","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/utf8_iter-1.0.4/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libutf8_iter-35a1ebaa8e089bfe.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libutf8_iter-35a1ebaa8e089bfe.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#bytes@1.11.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.11.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"bytes","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytes-1.11.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbytes-bed5cc5aff1ea43b.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#dtoa@1.0.10","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dtoa-1.0.10/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"dtoa","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dtoa-1.0.10/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdtoa-15a2c047bc9c568c.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdtoa-15a2c047bc9c568c.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#proc-macro-error-attr@1.0.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/proc-macro-error-attr-1.0.4/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"proc_macro_error_attr","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/proc-macro-error-attr-1.0.4/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libproc_macro_error_attr-320e2cc1cb59007e.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#string_cache@0.8.9","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/string_cache-0.8.9/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"string_cache","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/string_cache-0.8.9/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","serde","serde_support"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libstring_cache-8cd5ec8b36897572.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libstring_cache-8cd5ec8b36897572.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#selectors@0.24.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/selectors-0.24.0/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/selectors-0.24.0/build.rs","edition":"2015","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/selectors-735f3400f54b1bd4/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#phf@0.10.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf-0.10.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"phf","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf-0.10.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","macros","phf_macros","proc-macro-hack","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libphf-e2da0a2ea29c506b.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libphf-e2da0a2ea29c506b.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#proc-macro-error-attr@1.0.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/proc-macro-error-attr-1.0.4/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"proc_macro_error_attr","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/proc-macro-error-attr-1.0.4/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libproc_macro_error_attr-320e2cc1cb59007e.so"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#cssparser@0.29.6","linked_libs":[],"linked_paths":[],"cfgs":["rustc_has_pr45225"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/cssparser-4897a8681c07c782/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#gio-sys@0.18.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gio-sys-0.18.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"gio_sys","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gio-sys-0.18.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["v2_58","v2_60","v2_62","v2_64","v2_66","v2_68","v2_70"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libgio_sys-8964f90477b6f683.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#idna@1.1.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/idna-1.1.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"idna","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/idna-1.1.0/src/lib.rs","edition":"2018","doc":true,"doctest":false,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","compiled_data","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libidna-d7adfde84e96414a.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libidna-d7adfde84e96414a.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#proc-macro-error@1.0.4","linked_libs":[],"linked_paths":[],"cfgs":["use_fallback"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/proc-macro-error-fcfd8db63499a993/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tendril@0.4.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tendril-0.4.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tendril","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tendril-0.4.3/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtendril-20ce9207755f7ea8.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtendril-20ce9207755f7ea8.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#dtoa-short@0.3.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dtoa-short-0.3.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"dtoa_short","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dtoa-short-0.3.5/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdtoa_short-00548226c037d34d.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdtoa_short-00548226c037d34d.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#toml@0.9.10+spec-1.1.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/toml-0.9.10+spec-1.1.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"toml","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/toml-0.9.10+spec-1.1.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","display","parse","serde","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtoml-894edc9f4a3220dc.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtoml-894edc9f4a3220dc.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#form_urlencoded@1.2.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/form_urlencoded-1.2.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"form_urlencoded","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/form_urlencoded-1.2.2/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libform_urlencoded-01078b25a76608b9.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libform_urlencoded-01078b25a76608b9.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#dtoa-short@0.3.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dtoa-short-0.3.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"dtoa_short","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dtoa-short-0.3.5/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdtoa_short-00548226c037d34d.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdtoa_short-00548226c037d34d.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#idna@1.1.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/idna-1.1.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"idna","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/idna-1.1.0/src/lib.rs","edition":"2018","doc":true,"doctest":false,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","compiled_data","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libidna-d7adfde84e96414a.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libidna-d7adfde84e96414a.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#cssparser@0.29.6","linked_libs":[],"linked_paths":[],"cfgs":["rustc_has_pr45225"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/cssparser-4897a8681c07c782/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#phf@0.10.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf-0.10.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"phf","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf-0.10.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","macros","phf_macros","proc-macro-hack","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libphf-e2da0a2ea29c506b.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libphf-e2da0a2ea29c506b.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#markup5ever@0.14.1","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/markup5ever-6227cfd32231f95c/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#phf@0.11.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf-0.11.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"phf","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf-0.11.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","macros","phf_macros","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libphf-18943aabadbff865.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libphf-18943aabadbff865.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#uuid@1.19.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/uuid-1.19.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"uuid","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/uuid-1.19.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","rng","serde","std","v4"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libuuid-b4e402bf7148baf7.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libuuid-b4e402bf7148baf7.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#ctor@0.2.9","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ctor-0.2.9/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"ctor","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ctor-0.2.9/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libctor-391c43c65c427f21.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#cssparser-macros@0.6.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cssparser-macros-0.6.1/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"cssparser_macros","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cssparser-macros-0.6.1/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcssparser_macros-52edcdfae6f8ff0c.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#ctor@0.2.9","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ctor-0.2.9/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"ctor","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ctor-0.2.9/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libctor-391c43c65c427f21.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#indexmap@1.9.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/indexmap-1.9.3/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/indexmap-1.9.3/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["serde","serde-1"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/indexmap-6a1c2d918f5d7404/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#alloc-no-stdlib@2.0.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/alloc-no-stdlib-2.0.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"alloc_no_stdlib","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/alloc-no-stdlib-2.0.4/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liballoc_no_stdlib-f9c9b0a16c9c0331.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liballoc_no_stdlib-f9c9b0a16c9c0331.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#matches@0.1.10","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/matches-0.1.10/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"matches","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/matches-0.1.10/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libmatches-112e9319166e4e62.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libmatches-112e9319166e4e62.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#unic-common@0.9.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unic-common-0.9.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"unic_common","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unic-common-0.9.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libunic_common-5f2551cb81f1c7ad.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libunic_common-5f2551cb81f1c7ad.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#find-msvc-tools@0.1.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/find-msvc-tools-0.1.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"find_msvc_tools","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/find-msvc-tools-0.1.5/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfind_msvc_tools-5920961436c808e1.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfind_msvc_tools-5920961436c808e1.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#camino@1.2.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/camino-1.2.2/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/camino-1.2.2/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["serde1"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/camino-88bd969bf36761f5/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#nodrop@0.1.14","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nodrop-0.1.14/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"nodrop","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nodrop-0.1.14/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libnodrop-2fef010da030f48b.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libnodrop-2fef010da030f48b.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#unic-char-range@0.9.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unic-char-range-0.9.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"unic_char_range","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unic-char-range-0.9.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libunic_char_range-0bc9dcfb614a47b5.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libunic_char_range-0bc9dcfb614a47b5.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#convert_case@0.4.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/convert_case-0.4.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"convert_case","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/convert_case-0.4.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libconvert_case-64fe0d3cb40c43d3.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libconvert_case-64fe0d3cb40c43d3.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#alloc-no-stdlib@2.0.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/alloc-no-stdlib-2.0.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"alloc_no_stdlib","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/alloc-no-stdlib-2.0.4/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liballoc_no_stdlib-f9c9b0a16c9c0331.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liballoc_no_stdlib-f9c9b0a16c9c0331.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#shlex@1.3.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/shlex-1.3.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"shlex","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/shlex-1.3.0/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libshlex-9ec73c791a70e40d.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libshlex-9ec73c791a70e40d.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#nodrop@0.1.14","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nodrop-0.1.14/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"nodrop","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nodrop-0.1.14/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libnodrop-2fef010da030f48b.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libnodrop-2fef010da030f48b.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#itoa@1.0.16","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/itoa-1.0.16/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"itoa","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/itoa-1.0.16/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libitoa-d321e1c2c050809b.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#indexmap@1.9.3","linked_libs":[],"linked_paths":[],"cfgs":["has_std"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/indexmap-2511808a9b040ff9/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#find-msvc-tools@0.1.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/find-msvc-tools-0.1.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"find_msvc_tools","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/find-msvc-tools-0.1.5/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfind_msvc_tools-5920961436c808e1.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfind_msvc_tools-5920961436c808e1.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#unic-common@0.9.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unic-common-0.9.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"unic_common","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unic-common-0.9.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libunic_common-5f2551cb81f1c7ad.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libunic_common-5f2551cb81f1c7ad.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#camino@1.2.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/camino-1.2.2/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/camino-1.2.2/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["serde1"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/camino-88bd969bf36761f5/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#matches@0.1.10","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/matches-0.1.10/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"matches","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/matches-0.1.10/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libmatches-112e9319166e4e62.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libmatches-112e9319166e4e62.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#unic-char-range@0.9.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unic-char-range-0.9.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"unic_char_range","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unic-char-range-0.9.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libunic_char_range-0bc9dcfb614a47b5.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libunic_char_range-0bc9dcfb614a47b5.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#url@2.5.7","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/url-2.5.7/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"url","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/url-2.5.7/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","serde","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liburl-0045203f895255d8.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liburl-0045203f895255d8.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#proc-macro-error@1.0.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/proc-macro-error-1.0.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"proc_macro_error","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/proc-macro-error-1.0.4/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","syn","syn-error"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libproc_macro_error-ebe3c4cd15ad0231.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libproc_macro_error-ebe3c4cd15ad0231.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#indexmap@1.9.3","linked_libs":[],"linked_paths":[],"cfgs":["has_std"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/indexmap-2511808a9b040ff9/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#markup5ever@0.14.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/markup5ever-0.14.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"markup5ever","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/markup5ever-0.14.1/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libmarkup5ever-f2b88a87dca94985.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libmarkup5ever-f2b88a87dca94985.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#cc@1.2.50","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cc-1.2.50/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"cc","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cc-1.2.50/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcc-3f9c09b604f1f440.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcc-3f9c09b604f1f440.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#camino@1.2.2","linked_libs":[],"linked_paths":[],"cfgs":["try_reserve_2","path_buf_deref_mut","os_str_bytes","absolute_path","os_string_pathbuf_leak"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/camino-4722b41ded8bc2b9/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#cssparser@0.29.6","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cssparser-0.29.6/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"cssparser","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cssparser-0.29.6/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcssparser-1c516bc068157884.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcssparser-1c516bc068157884.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#unic-ucd-version@0.9.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unic-ucd-version-0.9.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"unic_ucd_version","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unic-ucd-version-0.9.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libunic_ucd_version-08fd875bc720cbe0.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libunic_ucd_version-08fd875bc720cbe0.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#derive_more@0.99.20","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/derive_more-0.99.20/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"derive_more","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/derive_more-0.99.20/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["add","add_assign","as_mut","as_ref","constructor","convert_case","default","deref","deref_mut","display","error","from","from_str","index","index_mut","into","into_iterator","is_variant","iterator","mul","mul_assign","not","rustc_version","sum","try_into","unwrap"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libderive_more-b249a0463900842d.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#unic-char-property@0.9.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unic-char-property-0.9.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"unic_char_property","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unic-char-property-0.9.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libunic_char_property-8f5b8856d71db9ad.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libunic_char_property-8f5b8856d71db9ad.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#alloc-stdlib@0.2.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/alloc-stdlib-0.2.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"alloc_stdlib","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/alloc-stdlib-0.2.2/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liballoc_stdlib-f055a315207a03cb.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liballoc_stdlib-f055a315207a03cb.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#servo_arc@0.2.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/servo_arc-0.2.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"servo_arc","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/servo_arc-0.2.0/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libservo_arc-b1136b15269514d3.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libservo_arc-b1136b15269514d3.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#alloc-stdlib@0.2.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/alloc-stdlib-0.2.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"alloc_stdlib","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/alloc-stdlib-0.2.2/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liballoc_stdlib-f055a315207a03cb.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liballoc_stdlib-f055a315207a03cb.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#camino@1.2.2","linked_libs":[],"linked_paths":[],"cfgs":["try_reserve_2","path_buf_deref_mut","os_str_bytes","absolute_path","os_string_pathbuf_leak"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/camino-4722b41ded8bc2b9/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#derive_more@0.99.20","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/derive_more-0.99.20/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"derive_more","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/derive_more-0.99.20/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["add","add_assign","as_mut","as_ref","constructor","convert_case","default","deref","deref_mut","display","error","from","from_str","index","index_mut","into","into_iterator","is_variant","iterator","mul","mul_assign","not","rustc_version","sum","try_into","unwrap"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libderive_more-b249a0463900842d.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#cssparser@0.29.6","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cssparser-0.29.6/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"cssparser","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cssparser-0.29.6/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcssparser-1c516bc068157884.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcssparser-1c516bc068157884.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#unic-char-property@0.9.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unic-char-property-0.9.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"unic_char_property","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unic-char-property-0.9.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libunic_char_property-8f5b8856d71db9ad.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libunic_char_property-8f5b8856d71db9ad.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#cc@1.2.50","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cc-1.2.50/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"cc","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cc-1.2.50/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcc-3f9c09b604f1f440.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcc-3f9c09b604f1f440.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#selectors@0.24.0","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/selectors-6b7c1c081b1d2e90/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#fxhash@0.2.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/fxhash-0.2.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"fxhash","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/fxhash-0.2.1/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfxhash-b1662d12142f0c9a.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfxhash-b1662d12142f0c9a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#phf@0.8.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf-0.8.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"phf","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf-0.8.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libphf-46b770e40aa49c00.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libphf-46b770e40aa49c00.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#typeid@1.0.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/typeid-1.0.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"typeid","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/typeid-1.0.3/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtypeid-e77a0359ea7c4992.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtypeid-e77a0359ea7c4992.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#thiserror@1.0.69","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/thiserror-1.0.69/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"thiserror","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/thiserror-1.0.69/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libthiserror-4016e4c50003b424.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde_derive_internals@0.29.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde_derive_internals-0.29.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"serde_derive_internals","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde_derive_internals-0.29.1/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libserde_derive_internals-7cf261b72ba22bad.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libserde_derive_internals-7cf261b72ba22bad.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#match_token@0.1.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/match_token-0.1.0/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"match_token","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/match_token-0.1.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libmatch_token-c0b1f431d91ece86.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#schemars@0.8.22","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/schemars-0.8.22/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/schemars-0.8.22/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","derive","indexmap","preserve_order","schemars_derive","url","uuid1"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/schemars-4f5335d7bc138ad7/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde_derive_internals@0.29.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde_derive_internals-0.29.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"serde_derive_internals","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde_derive_internals-0.29.1/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libserde_derive_internals-7cf261b72ba22bad.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libserde_derive_internals-7cf261b72ba22bad.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#hashbrown@0.12.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/hashbrown-0.12.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"hashbrown","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/hashbrown-0.12.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["raw"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libhashbrown-cd846cc65f6e0660.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libhashbrown-cd846cc65f6e0660.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#brotli-decompressor@5.0.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/brotli-decompressor-5.0.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"brotli_decompressor","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/brotli-decompressor-5.0.0/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc-stdlib","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbrotli_decompressor-623d41a4a8688afc.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbrotli_decompressor-623d41a4a8688afc.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#erased-serde@0.4.9","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/erased-serde-0.4.9/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"erased_serde","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/erased-serde-0.4.9/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liberased_serde-0ffd133c99761613.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liberased_serde-0ffd133c99761613.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#schemars@0.8.22","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/schemars-0.8.22/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/schemars-0.8.22/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","derive","indexmap","preserve_order","schemars_derive","url","uuid1"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/schemars-4f5335d7bc138ad7/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#html5ever@0.29.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/html5ever-0.29.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"html5ever","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/html5ever-0.29.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libhtml5ever-202ad17edb5e86d3.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libhtml5ever-202ad17edb5e86d3.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#selectors@0.24.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/selectors-0.24.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"selectors","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/selectors-0.24.0/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libselectors-c408656f73afdc19.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libselectors-c408656f73afdc19.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#unic-ucd-ident@0.9.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unic-ucd-ident-0.9.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"unic_ucd_ident","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unic-ucd-ident-0.9.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","id","xid"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libunic_ucd_ident-de63942b851e9e57.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libunic_ucd_ident-de63942b851e9e57.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#schemars_derive@0.8.22","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/schemars_derive-0.8.22/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"schemars_derive","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/schemars_derive-0.8.22/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libschemars_derive-41188d820ebcaf27.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#camino@1.2.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/camino-1.2.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"camino","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/camino-1.2.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["serde1"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcamino-0067d3ba988bc444.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcamino-0067d3ba988bc444.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#erased-serde@0.4.9","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/erased-serde-0.4.9/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"erased_serde","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/erased-serde-0.4.9/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liberased_serde-0ffd133c99761613.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liberased_serde-0ffd133c99761613.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#unic-ucd-ident@0.9.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unic-ucd-ident-0.9.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"unic_ucd_ident","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unic-ucd-ident-0.9.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","id","xid"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libunic_ucd_ident-de63942b851e9e57.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libunic_ucd_ident-de63942b851e9e57.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#brotli-decompressor@5.0.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/brotli-decompressor-5.0.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"brotli_decompressor","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/brotli-decompressor-5.0.0/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc-stdlib","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbrotli_decompressor-623d41a4a8688afc.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbrotli_decompressor-623d41a4a8688afc.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#cfb@0.7.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cfb-0.7.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"cfb","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cfb-0.7.3/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcfb-65b085ede7d30608.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcfb-65b085ede7d30608.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#jsonptr@0.6.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/jsonptr-0.6.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"jsonptr","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/jsonptr-0.6.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["assign","default","delete","json","resolve","serde","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libjsonptr-1fa90335b712e578.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libjsonptr-1fa90335b712e578.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#atk-sys@0.18.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/atk-sys-0.18.2/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/atk-sys-0.18.2/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/atk-sys-d42e0d941f8a7f72/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#pango-sys@0.18.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pango-sys-0.18.0/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pango-sys-0.18.0/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/pango-sys-05ab09cf37c79ef4/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#cairo-sys-rs@0.18.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cairo-sys-rs-0.18.2/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cairo-sys-rs-0.18.2/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["glib","use_glib"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/cairo-sys-rs-16b0280a38b651f8/build-script-build"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#schemars@0.8.22","linked_libs":[],"linked_paths":[],"cfgs":["std_atomic64","std_atomic"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/schemars-5428054ee53606f8/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#html5ever@0.29.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/html5ever-0.29.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"html5ever","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/html5ever-0.29.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libhtml5ever-202ad17edb5e86d3.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libhtml5ever-202ad17edb5e86d3.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#indexmap@1.9.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/indexmap-1.9.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"indexmap","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/indexmap-1.9.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["serde","serde-1"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libindexmap-437d29e58517d8a8.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libindexmap-437d29e58517d8a8.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#gdk-pixbuf-sys@0.18.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gdk-pixbuf-sys-0.18.0/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gdk-pixbuf-sys-0.18.0/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/gdk-pixbuf-sys-2364747bf2573bbe/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#atk-sys@0.18.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/atk-sys-0.18.2/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/atk-sys-0.18.2/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/atk-sys-d42e0d941f8a7f72/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#cairo-sys-rs@0.18.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cairo-sys-rs-0.18.2/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cairo-sys-rs-0.18.2/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["glib","use_glib"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/cairo-sys-rs-16b0280a38b651f8/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#schemars_derive@0.8.22","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/schemars_derive-0.8.22/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"schemars_derive","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/schemars_derive-0.8.22/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libschemars_derive-41188d820ebcaf27.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#indexmap@1.9.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/indexmap-1.9.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"indexmap","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/indexmap-1.9.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["serde","serde-1"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libindexmap-437d29e58517d8a8.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libindexmap-437d29e58517d8a8.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#schemars@0.8.22","linked_libs":[],"linked_paths":[],"cfgs":["std_atomic64","std_atomic"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/schemars-5428054ee53606f8/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#pango-sys@0.18.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pango-sys-0.18.0/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pango-sys-0.18.0/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/pango-sys-05ab09cf37c79ef4/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#thiserror@2.0.17","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/thiserror-2.0.17/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"thiserror","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/thiserror-2.0.17/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libthiserror-5982ff58add55a29.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libthiserror-5982ff58add55a29.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#proc-macro-crate@2.0.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/proc-macro-crate-2.0.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"proc_macro_crate","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/proc-macro-crate-2.0.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libproc_macro_crate-0989ee150e2ebf6e.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libproc_macro_crate-0989ee150e2ebf6e.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#futures-executor@0.3.31","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/futures-executor-0.3.31/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"futures_executor","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/futures-executor-0.3.31/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfutures_executor-abcf930290e0b804.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#zerofrom@0.1.6","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zerofrom-0.1.6/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"zerofrom","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zerofrom-0.1.6/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["derive"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzerofrom-c807c29236b58254.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#cargo-platform@0.1.9","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cargo-platform-0.1.9/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"cargo_platform","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cargo-platform-0.1.9/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcargo_platform-9524c3191bd61294.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcargo_platform-9524c3191bd61294.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#zerofrom@0.1.6","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zerofrom-0.1.6/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"zerofrom","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zerofrom-0.1.6/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["derive"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzerofrom-c807c29236b58254.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#thiserror@1.0.69","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/thiserror-1.0.69/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"thiserror","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/thiserror-1.0.69/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libthiserror-47545e65bfdbc8b8.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libthiserror-47545e65bfdbc8b8.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#dunce@1.0.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dunce-1.0.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"dunce","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dunce-1.0.5/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdunce-8a6c2e4f6d30a57f.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdunce-8a6c2e4f6d30a57f.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#stable_deref_trait@1.2.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/stable_deref_trait-1.2.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"stable_deref_trait","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/stable_deref_trait-1.2.1/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libstable_deref_trait-e1ac803ad7e62968.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#same-file@1.0.6","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/same-file-1.0.6/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"same_file","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/same-file-1.0.6/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsame_file-cf2de2adb0762469.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsame_file-cf2de2adb0762469.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#dunce@1.0.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dunce-1.0.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"dunce","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dunce-1.0.5/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdunce-8a6c2e4f6d30a57f.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdunce-8a6c2e4f6d30a57f.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#dyn-clone@1.0.20","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dyn-clone-1.0.20/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"dyn_clone","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dyn-clone-1.0.20/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdyn_clone-13e98e462e33ddda.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdyn_clone-13e98e462e33ddda.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#lazy_static@1.5.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/lazy_static-1.5.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"lazy_static","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/lazy_static-1.5.0/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liblazy_static-5f1438d28b1de877.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#heck@0.4.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/heck-0.4.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"heck","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/heck-0.4.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libheck-194e6447fcd8f24b.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libheck-194e6447fcd8f24b.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#same-file@1.0.6","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/same-file-1.0.6/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"same_file","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/same-file-1.0.6/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsame_file-cf2de2adb0762469.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsame_file-cf2de2adb0762469.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#walkdir@2.5.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/walkdir-2.5.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"walkdir","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/walkdir-2.5.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libwalkdir-a2bf97d292f523dd.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libwalkdir-a2bf97d292f523dd.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#schemars@0.8.22","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/schemars-0.8.22/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"schemars","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/schemars-0.8.22/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","derive","indexmap","preserve_order","schemars_derive","url","uuid1"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libschemars-c8c7cc5e22b2bc62.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libschemars-c8c7cc5e22b2bc62.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#pango-sys@0.18.0","linked_libs":["pango-1.0","gobject-2.0","glib-2.0","harfbuzz"],"linked_paths":[],"cfgs":["system_deps_have_pango"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/pango-sys-de5f3723c0f0ce12/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#cargo_metadata@0.19.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cargo_metadata-0.19.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"cargo_metadata","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cargo_metadata-0.19.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcargo_metadata-6ad227f44aaf2604.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcargo_metadata-6ad227f44aaf2604.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#json-patch@3.0.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/json-patch-3.0.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"json_patch","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/json-patch-3.0.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","diff"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libjson_patch-2e0aab4dd5c8e429.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libjson_patch-2e0aab4dd5c8e429.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#kuchikiki@0.8.8-speedreader","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/kuchikiki-0.8.8-speedreader/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"kuchikiki","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/kuchikiki-0.8.8-speedreader/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libkuchikiki-103d42862ded1b70.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libkuchikiki-103d42862ded1b70.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#schemars@0.8.22","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/schemars-0.8.22/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"schemars","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/schemars-0.8.22/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","derive","indexmap","preserve_order","schemars_derive","url","uuid1"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libschemars-c8c7cc5e22b2bc62.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libschemars-c8c7cc5e22b2bc62.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#gdk-pixbuf-sys@0.18.0","linked_libs":["gdk_pixbuf-2.0","gobject-2.0","glib-2.0"],"linked_paths":[],"cfgs":["system_deps_have_gdk_pixbuf_2_0"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/gdk-pixbuf-sys-cd30da39e4dbc7a7/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#yoke@0.8.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/yoke-0.8.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"yoke","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/yoke-0.8.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["derive","zerofrom"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libyoke-3d8577cf8aeb3c88.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#pango-sys@0.18.0","linked_libs":["pango-1.0","gobject-2.0","glib-2.0","harfbuzz"],"linked_paths":[],"cfgs":["system_deps_have_pango"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/pango-sys-de5f3723c0f0ce12/out"}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#atk-sys@0.18.2","linked_libs":["atk-1.0","gobject-2.0","glib-2.0"],"linked_paths":[],"cfgs":["system_deps_have_atk"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/atk-sys-09a2e35a61549ba6/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#brotli@8.0.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/brotli-8.0.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"brotli","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/brotli-8.0.2/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc-stdlib","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbrotli-cae5a0267bf0046e.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbrotli-cae5a0267bf0046e.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#infer@0.19.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/infer-0.19.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"infer","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/infer-0.19.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","cfb","default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libinfer-6a2ce71443b16b11.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libinfer-6a2ce71443b16b11.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#gdk-pixbuf-sys@0.18.0","linked_libs":["gdk_pixbuf-2.0","gobject-2.0","glib-2.0"],"linked_paths":[],"cfgs":["system_deps_have_gdk_pixbuf_2_0"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/gdk-pixbuf-sys-cd30da39e4dbc7a7/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde-untagged@0.1.9","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde-untagged-0.1.9/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"serde_untagged","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde-untagged-0.1.9/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libserde_untagged-1cf37efe8e18ab39.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libserde_untagged-1cf37efe8e18ab39.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#urlpattern@0.3.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/urlpattern-0.3.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"urlpattern","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/urlpattern-0.3.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liburlpattern-810f47ac0449aebc.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liburlpattern-810f47ac0449aebc.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#atk-sys@0.18.2","linked_libs":["atk-1.0","gobject-2.0","glib-2.0"],"linked_paths":[],"cfgs":["system_deps_have_atk"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/atk-sys-09a2e35a61549ba6/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#kuchikiki@0.8.8-speedreader","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/kuchikiki-0.8.8-speedreader/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"kuchikiki","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/kuchikiki-0.8.8-speedreader/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libkuchikiki-103d42862ded1b70.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libkuchikiki-103d42862ded1b70.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#cairo-sys-rs@0.18.2","linked_libs":["cairo","cairo-gobject","cairo","gobject-2.0","glib-2.0"],"linked_paths":[],"cfgs":["system_deps_have_cairo","system_deps_have_cairo_gobject"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/cairo-sys-rs-3faa9bebb102ec4c/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#glib-macros@0.18.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/glib-macros-0.18.5/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"glib_macros","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/glib-macros-0.18.5/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libglib_macros-61828177866c8567.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#walkdir@2.5.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/walkdir-2.5.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"walkdir","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/walkdir-2.5.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libwalkdir-a2bf97d292f523dd.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libwalkdir-a2bf97d292f523dd.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#infer@0.19.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/infer-0.19.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"infer","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/infer-0.19.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","cfb","default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libinfer-6a2ce71443b16b11.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libinfer-6a2ce71443b16b11.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde_with@3.16.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde_with-3.16.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"serde_with","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde_with-3.16.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","macros","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libserde_with-58d34210f838f90a.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libserde_with-58d34210f838f90a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#urlpattern@0.3.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/urlpattern-0.3.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"urlpattern","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/urlpattern-0.3.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liburlpattern-810f47ac0449aebc.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liburlpattern-810f47ac0449aebc.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#brotli@8.0.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/brotli-8.0.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"brotli","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/brotli-8.0.2/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc-stdlib","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbrotli-cae5a0267bf0046e.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbrotli-cae5a0267bf0046e.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#http@1.4.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/http-1.4.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"http","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/http-1.4.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libhttp-8ab3ac9b3e5de459.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libhttp-8ab3ac9b3e5de459.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde_with@3.16.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde_with-3.16.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"serde_with","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde_with-3.16.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","macros","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libserde_with-58d34210f838f90a.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libserde_with-58d34210f838f90a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#glob@0.3.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/glob-0.3.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"glob","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/glob-0.3.3/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libglob-9ddb071f0ab5bdaa.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libglob-9ddb071f0ab5bdaa.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#pango-sys@0.18.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pango-sys-0.18.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"pango_sys","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pango-sys-0.18.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libpango_sys-697239d588b9d468.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#cairo-sys-rs@0.18.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cairo-sys-rs-0.18.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"cairo_sys","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cairo-sys-rs-0.18.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["glib","use_glib"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcairo_sys-2498733f7cdf801b.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#gdk-pixbuf-sys@0.18.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gdk-pixbuf-sys-0.18.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"gdk_pixbuf_sys","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gdk-pixbuf-sys-0.18.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libgdk_pixbuf_sys-7d86c99b3809d80a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#cairo-sys-rs@0.18.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cairo-sys-rs-0.18.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"cairo_sys","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cairo-sys-rs-0.18.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["glib","use_glib"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcairo_sys-2498733f7cdf801b.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#pango-sys@0.18.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pango-sys-0.18.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"pango_sys","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pango-sys-0.18.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libpango_sys-697239d588b9d468.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rand_core@0.6.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rand_core-0.6.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"rand_core","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rand_core-0.6.4/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","getrandom","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librand_core-3c31f503dcfe52ff.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#toml_edit@0.19.15","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/toml_edit-0.19.15/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"toml_edit","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/toml_edit-0.19.15/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtoml_edit-ac5163a2850202b2.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtoml_edit-ac5163a2850202b2.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#typenum@1.19.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/typenum-1.19.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"typenum","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/typenum-1.19.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtypenum-af6d51510ae8a47e.rmeta"],"executable":null,"fresh":true}
@@ -320,16 +320,16 @@
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#parking@2.2.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/parking-2.2.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"parking","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/parking-2.2.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libparking-378cfc3f8b049625.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tinystr@0.8.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tinystr-0.8.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tinystr","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tinystr-0.8.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["zerovec"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtinystr-1d0b74cf8de61e9d.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#memoffset@0.9.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/memoffset-0.9.1/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/memoffset-0.9.1/build.rs","edition":"2015","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/memoffset-19712d54440c4572/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#litemap@0.8.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/litemap-0.8.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"litemap","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/litemap-0.8.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liblitemap-2c0084426e93789f.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#writeable@0.6.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/writeable-0.6.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"writeable","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/writeable-0.6.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libwriteable-92859d6095826bd4.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#gtk-sys@0.18.2","linked_libs":["gtk-3","gdk-3","z","pangocairo-1.0","pango-1.0","harfbuzz","atk-1.0","cairo-gobject","cairo","gdk_pixbuf-2.0","gio-2.0","gobject-2.0","glib-2.0"],"linked_paths":[],"cfgs":["system_deps_have_gtk_3_0"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/gtk-sys-3c14dc0cdc3dfe9b/out"}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#gio@0.18.4","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/gio-48eba9a01918d760/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#lock_api@0.4.14","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/lock_api-0.4.14/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"lock_api","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/lock_api-0.4.14/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["atomic_usize","default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liblock_api-bfb8d86e943b628d.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#writeable@0.6.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/writeable-0.6.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"writeable","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/writeable-0.6.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libwriteable-92859d6095826bd4.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#litemap@0.8.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/litemap-0.8.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"litemap","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/litemap-0.8.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liblitemap-2c0084426e93789f.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#memoffset@0.9.1","linked_libs":[],"linked_paths":[],"cfgs":["tuple_ty","allow_clippy","maybe_uninit","doctests","raw_ref_macros","stable_const","stable_offset_of"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/memoffset-74c0f68ea760db9b/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#crypto-common@0.1.7","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/crypto-common-0.1.7/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"crypto_common","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/crypto-common-0.1.7/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["getrandom","rand_core","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcrypto_common-25f68eda236162e2.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#potential_utf@0.1.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/potential_utf-0.1.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"potential_utf","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/potential_utf-0.1.4/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["zerovec"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libpotential_utf-8647bc59a8422598.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#atk-sys@0.18.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/atk-sys-0.18.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"atk_sys","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/atk-sys-0.18.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libatk_sys-049511fa6d21243c.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#zerotrie@0.2.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zerotrie-0.2.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"zerotrie","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zerotrie-0.2.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["yoke","zerofrom"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzerotrie-ff7866d36baae996.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#atk-sys@0.18.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/atk-sys-0.18.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"atk_sys","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/atk-sys-0.18.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libatk_sys-049511fa6d21243c.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#concurrent-queue@2.5.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/concurrent-queue-2.5.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"concurrent_queue","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/concurrent-queue-2.5.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libconcurrent_queue-8b639f2e1351f6e5.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#option-ext@0.2.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/option-ext-0.2.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"option_ext","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/option-ext-0.2.0/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liboption_ext-abd50e40d381cf73.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liboption_ext-abd50e40d381cf73.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#embed-resource@3.0.6","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/embed-resource-3.0.6/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"embed_resource","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/embed-resource-3.0.6/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libembed_resource-423d80811b38b39f.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libembed_resource-423d80811b38b39f.rmeta"],"executable":null,"fresh":true}
@@ -338,36 +338,36 @@
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#gio@0.18.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gio-0.18.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"gio","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gio-0.18.4/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["v2_58","v2_60","v2_62","v2_64","v2_66","v2_68","v2_70"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libgio-ad70856c11f7e06c.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#parking_lot@0.12.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/parking_lot-0.12.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"parking_lot","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/parking_lot-0.12.5/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libparking_lot-5bebd9eb5ddd6796.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#icu_locale_core@2.1.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_locale_core-2.1.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"icu_locale_core","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_locale_core-2.1.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["zerovec"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libicu_locale_core-a89a6bd3c3a4e4ca.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#icu_collections@2.1.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_collections-2.1.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"icu_collections","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_collections-2.1.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libicu_collections-9bf91a2fe86759d4.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#memoffset@0.9.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/memoffset-0.9.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"memoffset","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/memoffset-0.9.1/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libmemoffset-bfd5a4fbe16d33d3.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#icu_collections@2.1.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_collections-2.1.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"icu_collections","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_collections-2.1.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libicu_collections-9bf91a2fe86759d4.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#dirs-sys@0.5.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dirs-sys-0.5.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"dirs_sys","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dirs-sys-0.5.0/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdirs_sys-d5b4b762e3eb48b6.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdirs_sys-d5b4b762e3eb48b6.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#mio@1.1.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/mio-1.1.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"mio","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/mio-1.1.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["net","os-ext","os-poll"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libmio-9e3e53ac58bbd9b4.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#crc32fast@1.5.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/crc32fast-1.5.0/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/crc32fast-1.5.0/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/crc32fast-b2520ba5e2f57e6e/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#percent-encoding@2.3.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/percent-encoding-2.3.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"percent_encoding","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/percent-encoding-2.3.2/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libpercent_encoding-a0e7f105f5199ee1.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#fnv@1.0.7","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/fnv-1.0.7/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"fnv","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/fnv-1.0.7/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfnv-9e2dcb4bbe8b5cf3.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#byteorder@1.5.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/byteorder-1.5.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"byteorder","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/byteorder-1.5.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbyteorder-38697f7ceed19776.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#gtk-sys@0.18.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gtk-sys-0.18.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"gtk_sys","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gtk-sys-0.18.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["v3_24"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libgtk_sys-9ffb64bcb1177abb.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#fnv@1.0.7","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/fnv-1.0.7/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"fnv","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/fnv-1.0.7/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfnv-9e2dcb4bbe8b5cf3.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-winres@0.3.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-winres-0.3.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tauri_winres","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-winres-0.3.5/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtauri_winres-d08c99d0dae22228.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtauri_winres-d08c99d0dae22228.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#gtk-sys@0.18.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gtk-sys-0.18.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"gtk_sys","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gtk-sys-0.18.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["v3_24"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libgtk_sys-9ffb64bcb1177abb.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#cairo-rs@0.18.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cairo-rs-0.18.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"cairo","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cairo-rs-0.18.5/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","glib","use_glib"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcairo-4d1608c9c332fe89.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#icu_provider@2.1.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_provider-2.1.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"icu_provider","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_provider-2.1.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["baked"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libicu_provider-8155f28b69cc5151.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#crc32fast@1.5.0","linked_libs":[],"linked_paths":[],"cfgs":["stable_arm_crc32_intrinsics"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/crc32fast-c895ad404100caec/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#gdk-pixbuf@0.18.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gdk-pixbuf-0.18.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"gdk_pixbuf","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gdk-pixbuf-0.18.5/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libgdk_pixbuf-629aea59dac8da14.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#crc32fast@1.5.0","linked_libs":[],"linked_paths":[],"cfgs":["stable_arm_crc32_intrinsics"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/crc32fast-c895ad404100caec/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tokio@1.48.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.48.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tokio","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.48.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["bytes","default","fs","full","io-std","io-util","libc","macros","mio","net","parking_lot","process","rt","rt-multi-thread","signal","signal-hook-registry","socket2","sync","time","tokio-macros"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtokio-65b34c7895794047.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#dirs@6.0.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dirs-6.0.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"dirs","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dirs-6.0.0/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdirs-8c62a8a375c70f18.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdirs-8c62a8a375c70f18.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#pango@0.18.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pango-0.18.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"pango","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pango-0.18.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libpango-cd43a0a498d00d88.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tokio@1.48.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.48.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tokio","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.48.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["bytes","default","fs","full","io-std","io-util","libc","macros","mio","net","parking_lot","process","rt","rt-multi-thread","signal","signal-hook-registry","socket2","sync","time","tokio-macros"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtokio-65b34c7895794047.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#cargo_toml@0.22.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cargo_toml-0.22.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"cargo_toml","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cargo_toml-0.22.3/src/cargo_toml.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcargo_toml-40d6fe331f2044b0.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcargo_toml-40d6fe331f2044b0.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#field-offset@0.3.6","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/field-offset-0.3.6/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/field-offset-0.3.6/build.rs","edition":"2015","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/field-offset-ec661d8376d82956/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#icu_normalizer_data@2.1.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_normalizer_data-2.1.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"icu_normalizer_data","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_normalizer_data-2.1.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libicu_normalizer_data-8de7efa495e7b507.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#icu_properties_data@2.1.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_properties_data-2.1.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"icu_properties_data","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_properties_data-2.1.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libicu_properties_data-b880926ef3443015.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#icu_normalizer_data@2.1.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_normalizer_data-2.1.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"icu_normalizer_data","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_normalizer_data-2.1.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libicu_normalizer_data-8de7efa495e7b507.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tracing-core@0.1.36","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tracing-core-0.1.36/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tracing_core","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tracing-core-0.1.36/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","once_cell","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtracing_core-d1d91b5037705d34.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#subtle@2.6.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/subtle-2.6.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"subtle","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/subtle-2.6.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsubtle-8c24189f00ebf9a9.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#winnow@0.7.14","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.7.14/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"winnow","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/winnow-0.7.14/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libwinnow-6e3d8279050cedcc.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-plugin@2.5.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-plugin-2.5.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tauri_plugin","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-plugin-2.5.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["build"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtauri_plugin-cc31f12f6308e516.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtauri_plugin-cc31f12f6308e516.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#icu_properties@2.1.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_properties-2.1.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"icu_properties","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_properties-2.1.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["compiled_data"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libicu_properties-a4331be97a8aead1.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#gdk@0.18.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gdk-0.18.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"gdk","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gdk-0.18.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libgdk-d971dc221245e489.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#icu_normalizer@2.1.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_normalizer-2.1.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"icu_normalizer","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_normalizer-2.1.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["compiled_data"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libicu_normalizer-20199e550ee0cd8a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-build@2.5.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-build-2.5.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tauri_build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-build-2.5.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["config-json","default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtauri_build-57a1541da830e32c.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtauri_build-57a1541da830e32c.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#field-offset@0.3.6","linked_libs":[],"linked_paths":[],"cfgs":["fieldoffset_maybe_uninit","fieldoffset_has_alloc"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/field-offset-85796dfbaa98f0b1/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#icu_properties@2.1.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_properties-2.1.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"icu_properties","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_properties-2.1.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["compiled_data"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libicu_properties-a4331be97a8aead1.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-build@2.5.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-build-2.5.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tauri_build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-build-2.5.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["config-json","default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtauri_build-57a1541da830e32c.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtauri_build-57a1541da830e32c.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#icu_normalizer@2.1.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_normalizer-2.1.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"icu_normalizer","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/icu_normalizer-2.1.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["compiled_data"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libicu_normalizer-20199e550ee0cd8a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#gdk@0.18.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gdk-0.18.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"gdk","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gdk-0.18.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libgdk-d971dc221245e489.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#soup3-sys@0.5.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/soup3-sys-0.5.0/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/soup3-sys-0.5.0/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["v3_0"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/soup3-sys-a59c895a299bb88b/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#javascriptcore-rs-sys@1.1.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/javascriptcore-rs-sys-1.1.1/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/javascriptcore-rs-sys-1.1.1/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["v2_28","v2_38"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/javascriptcore-rs-sys-4cc23c168163dbf8/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tracing-attributes@0.1.31","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tracing-attributes-0.1.31/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"tracing_attributes","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tracing-attributes-0.1.31/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtracing_attributes-44b39ca1f1edeb45.so"],"executable":null,"fresh":true}
@@ -378,10 +378,10 @@
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#regex-syntax@0.8.8","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/regex-syntax-0.8.8/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"regex_syntax","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/regex-syntax-0.8.8/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std","unicode","unicode-age","unicode-bool","unicode-case","unicode-gencat","unicode-perl","unicode-script","unicode-segment"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libregex_syntax-6b9a34b059222229.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#atk@0.18.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/atk-0.18.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"atk","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/atk-0.18.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libatk-3e3528c8336df532.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#idna_adapter@1.2.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/idna_adapter-1.2.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"idna_adapter","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/idna_adapter-1.2.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["compiled_data"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libidna_adapter-782b47c297564317.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#gtk@0.18.2","linked_libs":[],"linked_paths":[],"cfgs":["gdk_backend=\"broadway\"","gdk_backend=\"wayland\"","gdk_backend=\"x11\""],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/gtk-f0358129a9dd2001/out"}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#javascriptcore-rs-sys@1.1.1","linked_libs":["javascriptcoregtk-4.1","gobject-2.0","glib-2.0"],"linked_paths":[],"cfgs":["system_deps_have_javascriptcoregtk_4_1"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/javascriptcore-rs-sys-9910de4986a8aab0/out"}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#soup3-sys@0.5.0","linked_libs":["glib-2.0","soup-3.0","gmodule-2.0","glib-2.0","gio-2.0","gobject-2.0","glib-2.0"],"linked_paths":[],"cfgs":["system_deps_have_libsoup_3_0"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/soup3-sys-541e8cdca7c68937/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#field-offset@0.3.6","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/field-offset-0.3.6/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"field_offset","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/field-offset-0.3.6/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfield_offset-a4eedd1a112ae566.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#gtk@0.18.2","linked_libs":[],"linked_paths":[],"cfgs":["gdk_backend=\"broadway\"","gdk_backend=\"wayland\"","gdk_backend=\"x11\""],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/gtk-f0358129a9dd2001/out"}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.146","linked_libs":[],"linked_paths":[],"cfgs":["fast_arithmetic=\"64\""],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/serde_json-d64fa105e12ebb71/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#regex-automata@0.4.13","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/regex-automata-0.4.13/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"regex_automata","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/regex-automata-0.4.13/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","dfa-build","dfa-onepass","dfa-search","hybrid","meta","nfa-backtrack","nfa-pikevm","nfa-thompson","perf-inline","perf-literal","perf-literal-multisubstring","perf-literal-substring","std","syntax","unicode","unicode-age","unicode-bool","unicode-case","unicode-gencat","unicode-perl","unicode-script","unicode-segment","unicode-word-boundary"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libregex_automata-8f65f7d1772e27be.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tracing@0.1.44","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tracing-0.1.44/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tracing","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tracing-0.1.44/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["attributes","default","std","tracing-attributes"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtracing-05de28c834c5a343.rmeta"],"executable":null,"fresh":true}
@@ -390,45 +390,45 @@
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#typenum@1.19.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/typenum-1.19.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"typenum","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/typenum-1.19.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtypenum-32b3612691cc6d16.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtypenum-32b3612691cc6d16.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#getrandom@0.3.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/getrandom-0.3.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"getrandom","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/getrandom-0.3.4/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libgetrandom-7fd10e8d1e14bcd4.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#x11@2.21.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/x11-2.21.0/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/x11-2.21.0/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/x11-b2f6aeeed4a8b3db/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#simd-adler32@0.3.8","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/simd-adler32-0.3.8/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"simd_adler32","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/simd-adler32-0.3.8/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["const-generics","default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsimd_adler32-2e94b4649fa7f82c.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsimd_adler32-2e94b4649fa7f82c.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#bytemuck@1.24.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytemuck-1.24.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"bytemuck","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bytemuck-1.24.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbytemuck-8733be17e225aae3.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#option-ext@0.2.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/option-ext-0.2.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"option_ext","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/option-ext-0.2.0/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liboption_ext-2177164f264298ca.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#ryu@1.0.21","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ryu-1.0.21/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"ryu","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ryu-1.0.21/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libryu-9023f759da28ce91.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#fastrand@2.3.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/fastrand-2.3.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"fastrand","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/fastrand-2.3.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfastrand-a9b0d260cd14d712.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#atomic-waker@1.1.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/atomic-waker-1.1.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"atomic_waker","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/atomic-waker-1.1.2/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libatomic_waker-f070c65b72d51c9a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#utf8_iter@1.0.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/utf8_iter-1.0.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"utf8_iter","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/utf8_iter-1.0.4/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libutf8_iter-133ba69d4e38b4c1.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#simd-adler32@0.3.8","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/simd-adler32-0.3.8/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"simd_adler32","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/simd-adler32-0.3.8/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["const-generics","default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsimd_adler32-2e94b4649fa7f82c.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsimd_adler32-2e94b4649fa7f82c.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#fastrand@2.3.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/fastrand-2.3.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"fastrand","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/fastrand-2.3.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfastrand-a9b0d260cd14d712.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#option-ext@0.2.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/option-ext-0.2.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"option_ext","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/option-ext-0.2.0/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liboption_ext-2177164f264298ca.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#arrayvec@0.7.6","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/arrayvec-0.7.6/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"arrayvec","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/arrayvec-0.7.6/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libarrayvec-bb6b6edd6045d7e7.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#soup3-sys@0.5.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/soup3-sys-0.5.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"soup3_sys","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/soup3-sys-0.5.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["v3_0"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsoup3_sys-d9ea53e537941e12.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#javascriptcore-rs-sys@1.1.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/javascriptcore-rs-sys-1.1.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"javascriptcore_rs_sys","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/javascriptcore-rs-sys-1.1.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["v2_28","v2_38"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libjavascriptcore_rs_sys-d15aacd9b9e49be5.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#atomic-waker@1.1.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/atomic-waker-1.1.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"atomic_waker","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/atomic-waker-1.1.2/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libatomic_waker-f070c65b72d51c9a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#ryu@1.0.21","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ryu-1.0.21/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"ryu","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ryu-1.0.21/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libryu-9023f759da28ce91.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#gtk@0.18.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gtk-0.18.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"gtk","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gtk-0.18.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["v3_24"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libgtk-f289f0379b3f9dbb.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#webkit2gtk-sys@2.0.1","linked_libs":["glib-2.0","webkit2gtk-4.1","gtk-3","gdk-3","z","pangocairo-1.0","pango-1.0","harfbuzz","atk-1.0","cairo-gobject","cairo","gdk_pixbuf-2.0","soup-3.0","gmodule-2.0","glib-2.0","gio-2.0","javascriptcoregtk-4.1","gobject-2.0","glib-2.0"],"linked_paths":[],"cfgs":["system_deps_have_webkit2gtk_4_1"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/webkit2gtk-sys-2ce28906727de6cd/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#uuid@1.19.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/uuid-1.19.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"uuid","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/uuid-1.19.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","rng","serde","std","v4"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libuuid-79084810f9cee24c.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#javascriptcore-rs-sys@1.1.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/javascriptcore-rs-sys-1.1.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"javascriptcore_rs_sys","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/javascriptcore-rs-sys-1.1.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["v2_28","v2_38"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libjavascriptcore_rs_sys-d15aacd9b9e49be5.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#generic-array@0.14.7","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/generic-array-0.14.7/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"generic_array","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/generic-array-0.14.7/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["more_lengths"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libgeneric_array-09bd1b9b334a9efb.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libgeneric_array-09bd1b9b334a9efb.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#x11@2.21.0","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/x11-431dd6be24a616ca/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.146","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde_json-1.0.146/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"serde_json","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde_json-1.0.146/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","raw_value","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libserde_json-129f1222a7484218.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#uuid@1.19.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/uuid-1.19.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"uuid","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/uuid-1.19.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","rng","serde","std","v4"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libuuid-79084810f9cee24c.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#soup3-sys@0.5.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/soup3-sys-0.5.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"soup3_sys","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/soup3-sys-0.5.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["v3_0"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsoup3_sys-d9ea53e537941e12.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#webkit2gtk-sys@2.0.1","linked_libs":["glib-2.0","webkit2gtk-4.1","gtk-3","gdk-3","z","pangocairo-1.0","pango-1.0","harfbuzz","atk-1.0","cairo-gobject","cairo","gdk_pixbuf-2.0","soup-3.0","gmodule-2.0","glib-2.0","gio-2.0","javascriptcoregtk-4.1","gobject-2.0","glib-2.0"],"linked_paths":[],"cfgs":["system_deps_have_webkit2gtk_4_1"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/webkit2gtk-sys-2ce28906727de6cd/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#symphonia-core@0.5.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/symphonia-core-0.5.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"symphonia_core","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/symphonia-core-0.5.5/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsymphonia_core-e17d067e530a45d5.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde_json@1.0.146","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde_json-1.0.146/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"serde_json","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde_json-1.0.146/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","raw_value","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libserde_json-129f1222a7484218.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#idna@1.1.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/idna-1.1.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"idna","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/idna-1.1.0/src/lib.rs","edition":"2018","doc":true,"doctest":false,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","compiled_data","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libidna-1ce0470e2ea2ee55.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri@2.9.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-2.9.5/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-2.9.5/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["common-controls-v6","compression","custom-protocol","default","dynamic-acl","tauri-runtime-wry","webkit2gtk","webview2-com","wry","x11"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/tauri-e9fcbe3aed2920c7/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#form_urlencoded@1.2.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/form_urlencoded-1.2.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"form_urlencoded","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/form_urlencoded-1.2.2/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":false},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libform_urlencoded-0178875806ad0e4b.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#event-listener@5.4.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/event-listener-5.4.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"event_listener","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/event-listener-5.4.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","parking","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libevent_listener-d7545a70d513a97d.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#gdkx11-sys@0.18.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gdkx11-sys-0.18.2/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gdkx11-sys-0.18.2/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/gdkx11-sys-92f5cb92369d2cf9/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#powerfmt@0.2.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/powerfmt-0.2.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"powerfmt","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/powerfmt-0.2.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libpowerfmt-7813a41aba93a2d4.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#time-core@0.1.6","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/time-core-0.1.6/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"time_core","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/time-core-0.1.6/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtime_core-3c9085b0b4ddf244.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtime_core-3c9085b0b4ddf244.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#adler2@2.0.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/adler2-2.0.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"adler2","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/adler2-2.0.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libadler2-70f2ae686cd2ff4a.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libadler2-70f2ae686cd2ff4a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#num-conv@0.1.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/num-conv-0.1.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"num_conv","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/num-conv-0.1.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libnum_conv-68396d117bfa854c.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libnum_conv-68396d117bfa854c.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#unic-char-range@0.9.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unic-char-range-0.9.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"unic_char_range","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unic-char-range-0.9.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libunic_char_range-912627833606769d.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#unic-common@0.9.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unic-common-0.9.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"unic_common","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unic-common-0.9.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libunic_common-d0a9b1453a8f4168.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#alloc-no-stdlib@2.0.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/alloc-no-stdlib-2.0.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"alloc_no_stdlib","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/alloc-no-stdlib-2.0.4/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liballoc_no_stdlib-3e1372c23a7bef7d.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#powerfmt@0.2.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/powerfmt-0.2.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"powerfmt","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/powerfmt-0.2.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libpowerfmt-7813a41aba93a2d4.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#adler2@2.0.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/adler2-2.0.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"adler2","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/adler2-2.0.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libadler2-70f2ae686cd2ff4a.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libadler2-70f2ae686cd2ff4a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#event-listener-strategy@0.5.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/event-listener-strategy-0.5.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"event_listener_strategy","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/event-listener-strategy-0.5.4/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libevent_listener_strategy-26cd6fb5c004dab7.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#miniz_oxide@0.8.9","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/miniz_oxide-0.8.9/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"miniz_oxide","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/miniz_oxide-0.8.9/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","simd","simd-adler32","with-alloc"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libminiz_oxide-683db57c7a0e2d36.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libminiz_oxide-683db57c7a0e2d36.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#unic-char-property@0.9.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unic-char-property-0.9.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"unic_char_property","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unic-char-property-0.9.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libunic_char_property-10422f990c598ddb.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri@2.9.5","linked_libs":[],"linked_paths":[],"cfgs":["custom_protocol","desktop"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/tauri-49b7c0768ea40013/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#url@2.5.7","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/url-2.5.7/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"url","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/url-2.5.7/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","serde","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liburl-ff51b1fa8661fdb9.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#gdkx11-sys@0.18.2","linked_libs":["gdk-3","z","pangocairo-1.0","pango-1.0","harfbuzz","gdk_pixbuf-2.0","cairo-gobject","cairo","gobject-2.0","glib-2.0"],"linked_paths":[],"cfgs":["system_deps_have_gdk_x11_3_0"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/gdkx11-sys-d4f73a50b28a382a/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#time-macros@0.2.24","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/time-macros-0.2.24/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"time_macros","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/time-macros-0.2.24/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["formatting","parsing"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtime_macros-cf4c7427ec7b71df.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#alloc-stdlib@0.2.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/alloc-stdlib-0.2.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"alloc_stdlib","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/alloc-stdlib-0.2.2/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liballoc_stdlib-c36c273455ea7695.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#unic-ucd-version@0.9.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unic-ucd-version-0.9.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"unic_ucd_version","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unic-ucd-version-0.9.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libunic_ucd_version-64e240b8a6c7c7e2.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri@2.9.5","linked_libs":[],"linked_paths":[],"cfgs":["custom_protocol","desktop"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/tauri-49b7c0768ea40013/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#deranged@0.5.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/deranged-0.5.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"deranged","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/deranged-0.5.5/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","powerfmt"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libderanged-670e833df5be91e0.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#url@2.5.7","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/url-2.5.7/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"url","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/url-2.5.7/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","serde","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liburl-ff51b1fa8661fdb9.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#miniz_oxide@0.8.9","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/miniz_oxide-0.8.9/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"miniz_oxide","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/miniz_oxide-0.8.9/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","simd","simd-adler32","with-alloc"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libminiz_oxide-683db57c7a0e2d36.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libminiz_oxide-683db57c7a0e2d36.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#unic-char-property@0.9.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unic-char-property-0.9.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"unic_char_property","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unic-char-property-0.9.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libunic_char_property-10422f990c598ddb.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#alloc-stdlib@0.2.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/alloc-stdlib-0.2.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"alloc_stdlib","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/alloc-stdlib-0.2.2/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liballoc_stdlib-c36c273455ea7695.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#event-listener-strategy@0.5.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/event-listener-strategy-0.5.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"event_listener_strategy","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/event-listener-strategy-0.5.4/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libevent_listener_strategy-26cd6fb5c004dab7.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#x11@2.21.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/x11-2.21.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"x11","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/x11-2.21.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libx11-fd00a7b9cab332c6.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#futures-lite@2.6.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/futures-lite-2.6.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"futures_lite","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/futures-lite-2.6.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","fastrand","futures-io","parking","race","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfutures_lite-62313ea4dc87d24e.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#crc32fast@1.5.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/crc32fast-1.5.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"crc32fast","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/crc32fast-1.5.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcrc32fast-bf4c10d06c9c10a2.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcrc32fast-bf4c10d06c9c10a2.rmeta"],"executable":null,"fresh":true}
@@ -438,54 +438,54 @@
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#cookie@0.18.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cookie-0.18.1/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cookie-0.18.1/build.rs","edition":"2018","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/cookie-bc2f242286887374/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#num-traits@0.2.19","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/num-traits-0.2.19/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/num-traits-0.2.19/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["i128","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/num-traits-c9df9b033acc0704/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#x11-dl@2.21.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/x11-dl-2.21.0/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/x11-dl-2.21.0/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/x11-dl-7364f572afc423cc/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#siphasher@1.0.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/siphasher-1.0.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"siphasher","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/siphasher-1.0.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsiphasher-c750eb0c9750207c.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#time-core@0.1.6","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/time-core-0.1.6/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"time_core","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/time-core-0.1.6/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtime_core-3928ebc2dded2d25.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#raw-window-handle@0.6.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/raw-window-handle-0.6.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"raw_window_handle","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/raw-window-handle-0.6.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libraw_window_handle-5e4b75a356ebfcd3.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#num-conv@0.1.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/num-conv-0.1.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"num_conv","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/num-conv-0.1.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libnum_conv-06451802a8e998b8.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#siphasher@1.0.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/siphasher-1.0.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"siphasher","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/siphasher-1.0.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsiphasher-c750eb0c9750207c.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#either@1.15.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/either-1.15.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"either","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/either-1.15.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["std","use_std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libeither-c8d396d337920be5.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libeither-c8d396d337920be5.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#gdkx11-sys@0.18.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gdkx11-sys-0.18.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"gdk_x11_sys","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gdkx11-sys-0.18.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libgdk_x11_sys-f378b6a51ce3d62e.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#num-conv@0.1.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/num-conv-0.1.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"num_conv","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/num-conv-0.1.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libnum_conv-06451802a8e998b8.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#time-core@0.1.6","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/time-core-0.1.6/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"time_core","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/time-core-0.1.6/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtime_core-3928ebc2dded2d25.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#flate2@1.1.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/flate2-1.1.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"flate2","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/flate2-1.1.5/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["any_impl","default","miniz_oxide","rust_backend"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libflate2-2046a9f7f7bafd1c.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libflate2-2046a9f7f7bafd1c.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#brotli-decompressor@5.0.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/brotli-decompressor-5.0.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"brotli_decompressor","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/brotli-decompressor-5.0.0/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc-stdlib","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbrotli_decompressor-0abaa7bbfe444e5b.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#gdkx11-sys@0.18.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gdkx11-sys-0.18.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"gdk_x11_sys","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gdkx11-sys-0.18.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libgdk_x11_sys-f378b6a51ce3d62e.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#unic-ucd-ident@0.9.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unic-ucd-ident-0.9.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"unic_ucd_ident","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unic-ucd-ident-0.9.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","id","xid"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libunic_ucd_ident-fdda0315b2617de7.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#cookie@0.18.1","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/cookie-d9346e2bc685f450/out"}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#x11-dl@2.21.0","linked_libs":["dl"],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/x11-dl-9b3d2c981ad0d476/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#brotli-decompressor@5.0.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/brotli-decompressor-5.0.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"brotli_decompressor","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/brotli-decompressor-5.0.0/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc-stdlib","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbrotli_decompressor-0abaa7bbfe444e5b.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#itertools@0.14.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/itertools-0.14.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"itertools","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/itertools-0.14.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","use_alloc","use_std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libitertools-d5c4e00e146b744d.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libitertools-d5c4e00e146b744d.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#phf_shared@0.11.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf_shared-0.11.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"phf_shared","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf_shared-0.11.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":false},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libphf_shared-9051c6ac0432efa5.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#erased-serde@0.4.9","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/erased-serde-0.4.9/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"erased_serde","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/erased-serde-0.4.9/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liberased_serde-7af39399e5de2356.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#num-traits@0.2.19","linked_libs":[],"linked_paths":[],"cfgs":["has_total_cmp"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/num-traits-50fa729e9ccb039a/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#time@0.3.44","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/time-0.3.44/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"time","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/time-0.3.44/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","formatting","macros","parsing","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtime-1e7ddff53570d512.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#phf_shared@0.11.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf_shared-0.11.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"phf_shared","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf_shared-0.11.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":false},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libphf_shared-9051c6ac0432efa5.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#cookie@0.18.1","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/cookie-d9346e2bc685f450/out"}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#x11-dl@2.21.0","linked_libs":["dl"],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/x11-dl-9b3d2c981ad0d476/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#jsonptr@0.6.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/jsonptr-0.6.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"jsonptr","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/jsonptr-0.6.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["assign","default","delete","json","resolve","serde","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libjsonptr-fe486b6d3c89772a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#cfb@0.7.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cfb-0.7.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"cfb","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cfb-0.7.3/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcfb-9f8a953fb4783aa5.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#soup3@0.5.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/soup3-0.5.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"soup","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/soup3-0.5.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsoup-ff7e692fd11696cb.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#webkit2gtk-sys@2.0.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/webkit2gtk-sys-2.0.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"webkit2gtk_sys","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/webkit2gtk-sys-2.0.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["v2_10","v2_12","v2_14","v2_16","v2_18","v2_20","v2_22","v2_24","v2_26","v2_28","v2_30","v2_32","v2_34","v2_36","v2_38","v2_40","v2_6","v2_8"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libwebkit2gtk_sys-3ace4f370a3b5d45.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#block-buffer@0.10.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/block-buffer-0.10.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"block_buffer","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/block-buffer-0.10.4/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libblock_buffer-57193a827ef9f912.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libblock_buffer-57193a827ef9f912.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#crypto-common@0.1.7","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/crypto-common-0.1.7/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"crypto_common","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/crypto-common-0.1.7/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcrypto_common-29d7c83552f090b7.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcrypto_common-29d7c83552f090b7.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#javascriptcore-rs@1.1.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/javascriptcore-rs-1.1.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"javascriptcore","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/javascriptcore-rs-1.1.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","v2_28","v2_38"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libjavascriptcore-95465bd5c9c60ae8.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#block-buffer@0.10.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/block-buffer-0.10.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"block_buffer","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/block-buffer-0.10.4/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libblock_buffer-57193a827ef9f912.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libblock_buffer-57193a827ef9f912.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#webkit2gtk-sys@2.0.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/webkit2gtk-sys-2.0.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"webkit2gtk_sys","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/webkit2gtk-sys-2.0.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["v2_10","v2_12","v2_14","v2_16","v2_18","v2_20","v2_22","v2_24","v2_26","v2_28","v2_30","v2_32","v2_34","v2_36","v2_38","v2_40","v2_6","v2_8"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libwebkit2gtk_sys-3ace4f370a3b5d45.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#regex@1.12.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/regex-1.12.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"regex","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/regex-1.12.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","perf","perf-backtrack","perf-cache","perf-dfa","perf-inline","perf-literal","perf-onepass","std","unicode","unicode-age","unicode-bool","unicode-case","unicode-gencat","unicode-perl","unicode-script","unicode-segment"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libregex-5351eacec0f34e96.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#fdeflate@0.3.7","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/fdeflate-0.3.7/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"fdeflate","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/fdeflate-0.3.7/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfdeflate-e5f5d3fc9790f68b.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfdeflate-e5f5d3fc9790f68b.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#regex@1.12.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/regex-1.12.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"regex","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/regex-1.12.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","perf","perf-backtrack","perf-cache","perf-dfa","perf-inline","perf-literal","perf-onepass","std","unicode","unicode-age","unicode-bool","unicode-case","unicode-gencat","unicode-perl","unicode-script","unicode-segment"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libregex-5351eacec0f34e96.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#toml_parser@1.0.6+spec-1.1.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/toml_parser-1.0.6+spec-1.1.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"toml_parser","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/toml_parser-1.0.6+spec-1.1.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtoml_parser-2eba08491e7ff7e9.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde_repr@0.1.20","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde_repr-0.1.20/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"serde_repr","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde_repr-0.1.20/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libserde_repr-626c9a8bc582bc41.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#toml_datetime@0.7.5+spec-1.1.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/toml_datetime-0.7.5+spec-1.1.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"toml_datetime","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/toml_datetime-0.7.5+spec-1.1.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","serde","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtoml_datetime-12f99308f930096d.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde_spanned@1.0.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde_spanned-1.0.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"serde_spanned","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde_spanned-1.0.4/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","serde","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libserde_spanned-ac10a120786b2684.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#toml_datetime@0.7.5+spec-1.1.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/toml_datetime-0.7.5+spec-1.1.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"toml_datetime","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/toml_datetime-0.7.5+spec-1.1.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","serde","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtoml_datetime-12f99308f930096d.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#encoding_rs@0.8.35","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/encoding_rs-0.8.35/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"encoding_rs","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/encoding_rs-0.8.35/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libencoding_rs-26b550fb424cdde2.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#crunchy@0.2.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/crunchy-0.2.4/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/crunchy-0.2.4/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","limit_128"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/crunchy-d1a0a58bbe59e550/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#toml_writer@1.0.6+spec-1.1.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/toml_writer-1.0.6+spec-1.1.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"toml_writer","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/toml_writer-1.0.6+spec-1.1.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtoml_writer-253ed315ecb32e70.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#same-file@1.0.6","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/same-file-1.0.6/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"same_file","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/same-file-1.0.6/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsame_file-59e2b2bf64557ccb.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#crunchy@0.2.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/crunchy-0.2.4/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/crunchy-0.2.4/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","limit_128"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/crunchy-d1a0a58bbe59e550/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#prost-derive@0.13.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/prost-derive-0.13.5/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"prost_derive","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/prost-derive-0.13.5/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libprost_derive-c0029fff02ab72cb.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#cookie@0.18.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cookie-0.18.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"cookie","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cookie-0.18.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcookie-b4bd9b68d7e7c8cb.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#infer@0.19.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/infer-0.19.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"infer","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/infer-0.19.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","cfb","default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libinfer-afcda218a33ab9f7.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#phf@0.11.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf-0.11.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"phf","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf-0.11.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":false},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","macros","phf_macros","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libphf-bf874d36609f6190.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#urlpattern@0.3.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/urlpattern-0.3.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"urlpattern","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/urlpattern-0.3.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liburlpattern-0a9a0f1f9f4016b5.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#toml@0.9.10+spec-1.1.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/toml-0.9.10+spec-1.1.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"toml","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/toml-0.9.10+spec-1.1.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","display","parse","serde","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtoml-4d552c2c1ad886f5.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#crunchy@0.2.4","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[["CRUNCHY_LIB_SUFFIX","/lib.rs"]],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/crunchy-968dda5e33cc46c6/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#png@0.17.16","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/png-0.17.16/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"png","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/png-0.17.16/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libpng-701c9092cac05cfd.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libpng-701c9092cac05cfd.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#walkdir@2.5.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/walkdir-2.5.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"walkdir","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/walkdir-2.5.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libwalkdir-c5e5c604df388800.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#serde-untagged@0.1.9","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde-untagged-0.1.9/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"serde_untagged","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serde-untagged-0.1.9/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libserde_untagged-ac41c32bc8d10ec1.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#json-patch@3.0.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/json-patch-3.0.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"json_patch","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/json-patch-3.0.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","diff"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libjson_patch-7450e4bd93875864.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#digest@0.10.7","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/digest-0.10.7/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"digest","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/digest-0.10.7/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","block-buffer","core-api","default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdigest-e218aeb334b66615.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdigest-e218aeb334b66615.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#x11-dl@2.21.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/x11-dl-2.21.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"x11_dl","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/x11-dl-2.21.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libx11_dl-81e433419bbaff52.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#num-traits@0.2.19","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/num-traits-0.2.19/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"num_traits","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/num-traits-0.2.19/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["i128","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libnum_traits-c75837b11941dcbd.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#json-patch@3.0.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/json-patch-3.0.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"json_patch","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/json-patch-3.0.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","diff"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libjson_patch-7450e4bd93875864.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#crunchy@0.2.4","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[["CRUNCHY_LIB_SUFFIX","/lib.rs"]],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/crunchy-968dda5e33cc46c6/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#walkdir@2.5.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/walkdir-2.5.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"walkdir","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/walkdir-2.5.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libwalkdir-c5e5c604df388800.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#urlpattern@0.3.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/urlpattern-0.3.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"urlpattern","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/urlpattern-0.3.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liburlpattern-0a9a0f1f9f4016b5.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#png@0.17.16","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/png-0.17.16/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"png","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/png-0.17.16/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libpng-701c9092cac05cfd.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libpng-701c9092cac05cfd.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#toml@0.9.10+spec-1.1.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/toml-0.9.10+spec-1.1.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"toml","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/toml-0.9.10+spec-1.1.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","display","parse","serde","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtoml-4d552c2c1ad886f5.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#prost-derive@0.13.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/prost-derive-0.13.5/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"prost_derive","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/prost-derive-0.13.5/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libprost_derive-c0029fff02ab72cb.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#x11-dl@2.21.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/x11-dl-2.21.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"x11_dl","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/x11-dl-2.21.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libx11_dl-81e433419bbaff52.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#webkit2gtk@2.0.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/webkit2gtk-2.0.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"webkit2gtk","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/webkit2gtk-2.0.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["v2_10","v2_12","v2_14","v2_16","v2_18","v2_2","v2_20","v2_22","v2_24","v2_26","v2_28","v2_30","v2_32","v2_34","v2_36","v2_38","v2_4","v2_40","v2_6","v2_8"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libwebkit2gtk-5e8f09a804820f06.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#phf@0.11.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf-0.11.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"phf","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/phf-0.11.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":false},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","macros","phf_macros","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libphf-bf874d36609f6190.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#infer@0.19.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/infer-0.19.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"infer","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/infer-0.19.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","cfb","default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libinfer-afcda218a33ab9f7.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#digest@0.10.7","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/digest-0.10.7/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"digest","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/digest-0.10.7/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","block-buffer","core-api","default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdigest-e218aeb334b66615.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdigest-e218aeb334b66615.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#brotli@8.0.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/brotli-8.0.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"brotli","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/brotli-8.0.2/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc-stdlib","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbrotli-0b83c99118a5b88d.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#dirs-sys@0.5.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dirs-sys-0.5.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"dirs_sys","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dirs-sys-0.5.0/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdirs_sys-c1155043b2c6966b.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#enumflags2@0.7.12","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/enumflags2-0.7.12/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"enumflags2","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/enumflags2-0.7.12/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["serde"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libenumflags2-a01308c5f0d3d0b8.rmeta"],"executable":null,"fresh":true}
@@ -494,30 +494,30 @@
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#anyhow@1.0.100","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/anyhow-1.0.100/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"anyhow","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/anyhow-1.0.100/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libanyhow-61662e17501ef7b9.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#toml_edit@0.23.10+spec-1.0.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/toml_edit-0.23.10+spec-1.0.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"toml_edit","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/toml_edit-0.23.10+spec-1.0.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["parse"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtoml_edit-02edba08fe1ea5a1.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtoml_edit-02edba08fe1ea5a1.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#dlopen2_derive@0.4.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dlopen2_derive-0.4.3/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"dlopen2_derive","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dlopen2_derive-0.4.3/src/lib.rs","edition":"2024","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdlopen2_derive-2bd98275526d8b7e.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#semver@1.0.27","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/semver-1.0.27/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"semver","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/semver-1.0.27/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsemver-d4cc4d86b9e8a90a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-runtime@2.9.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-runtime-2.9.2/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-runtime-2.9.2/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/tauri-runtime-97b8915a27d0878d/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#mime@0.3.17","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/mime-0.3.17/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"mime","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/mime-0.3.17/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libmime-29dbabf1cb939012.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#cpufeatures@0.2.17","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cpufeatures-0.2.17/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"cpufeatures","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cpufeatures-0.2.17/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcpufeatures-f5116670c7931c01.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcpufeatures-f5116670c7931c01.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.103","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/proc-macro2-1.0.103/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/proc-macro2-1.0.103/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","proc-macro"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/proc-macro2-062ae819a3d59f15/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#glob@0.3.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/glob-0.3.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"glob","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/glob-0.3.3/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libglob-b1415178180bc6fc.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#cpufeatures@0.2.17","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cpufeatures-0.2.17/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"cpufeatures","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cpufeatures-0.2.17/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcpufeatures-45c28af12c96235b.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tiny-keccak@2.0.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tiny-keccak-2.0.2/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tiny-keccak-2.0.2/build.rs","edition":"2018","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","shake"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/tiny-keccak-7149375f0d65dc07/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#dunce@1.0.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dunce-1.0.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"dunce","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dunce-1.0.5/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdunce-b9bec7c2ad022583.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#wry@0.53.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wry-0.53.5/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wry-0.53.5/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["drag-drop","gdkx11","javascriptcore-rs","linux-body","os-webview","protocol","soup3","webkit2gtk","webkit2gtk-sys","x11","x11-dl"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/wry-8b6df9caf1e5c534/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#async-task@4.7.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-task-4.7.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"async_task","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-task-4.7.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libasync_task-8a310d2be3c4cda3.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#dlopen2@0.8.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dlopen2-0.8.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"dlopen2","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dlopen2-0.8.2/src/lib.rs","edition":"2024","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","derive","dlopen2_derive","symbor","wrapper"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdlopen2-79d4818555babd2a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#dunce@1.0.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dunce-1.0.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"dunce","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dunce-1.0.5/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdunce-b9bec7c2ad022583.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-runtime@2.9.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-runtime-2.9.2/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-runtime-2.9.2/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/tauri-runtime-97b8915a27d0878d/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tiny-keccak@2.0.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tiny-keccak-2.0.2/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tiny-keccak-2.0.2/build.rs","edition":"2018","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","shake"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/tiny-keccak-7149375f0d65dc07/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#wry@0.53.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wry-0.53.5/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wry-0.53.5/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["drag-drop","gdkx11","javascriptcore-rs","linux-body","os-webview","protocol","soup3","webkit2gtk","webkit2gtk-sys","x11","x11-dl"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/wry-8b6df9caf1e5c534/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.103","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/proc-macro2-1.0.103/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/proc-macro2-1.0.103/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","proc-macro"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/proc-macro2-062ae819a3d59f15/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#cpufeatures@0.2.17","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cpufeatures-0.2.17/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"cpufeatures","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cpufeatures-0.2.17/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcpufeatures-f5116670c7931c01.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcpufeatures-f5116670c7931c01.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#mime@0.3.17","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/mime-0.3.17/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"mime","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/mime-0.3.17/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libmime-29dbabf1cb939012.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#glob@0.3.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/glob-0.3.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"glob","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/glob-0.3.3/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libglob-b1415178180bc6fc.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#semver@1.0.27","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/semver-1.0.27/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"semver","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/semver-1.0.27/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsemver-d4cc4d86b9e8a90a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#cpufeatures@0.2.17","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cpufeatures-0.2.17/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"cpufeatures","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cpufeatures-0.2.17/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcpufeatures-45c28af12c96235b.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#sha2@0.10.9","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/sha2-0.10.9/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"sha2","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/sha2-0.10.9/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsha2-feda18c3cc53e9dc.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsha2-feda18c3cc53e9dc.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#proc-macro-crate@3.4.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/proc-macro-crate-3.4.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"proc_macro_crate","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/proc-macro-crate-3.4.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libproc_macro_crate-89277a7a3569e810.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libproc_macro_crate-89277a7a3569e810.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.103","linked_libs":[],"linked_paths":[],"cfgs":["wrap_proc_macro","proc_macro_span_location","proc_macro_span_file"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/proc-macro2-545cf9ce869ddfda/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#proc-macro-crate@3.4.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/proc-macro-crate-3.4.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"proc_macro_crate","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/proc-macro-crate-3.4.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libproc_macro_crate-89277a7a3569e810.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libproc_macro_crate-89277a7a3569e810.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#wry@0.53.5","linked_libs":[],"linked_paths":[],"cfgs":["linux","gtk"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/wry-74f203a30cb21d8f/out"}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#tiny-keccak@2.0.2","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/tiny-keccak-6b819b4c0b8292de/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-utils@2.8.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-utils-2.8.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tauri_utils","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-utils-2.8.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["brotli","compression","resources","walkdir"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtauri_utils-eedd27dcce98d576.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-runtime@2.9.2","linked_libs":[],"linked_paths":[],"cfgs":["desktop"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/tauri-runtime-6f751b92e022dcd8/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#dlopen2@0.8.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dlopen2-0.8.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"dlopen2","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dlopen2-0.8.2/src/lib.rs","edition":"2024","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","derive","dlopen2_derive","symbor","wrapper"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdlopen2-79d4818555babd2a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#ico@0.4.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ico-0.4.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"ico","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ico-0.4.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libico-82539014cd27f80f.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libico-82539014cd27f80f.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#dirs@6.0.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dirs-6.0.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"dirs","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dirs-6.0.0/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdirs-f36bacd71c7331e3.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#crunchy@0.2.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/crunchy-0.2.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"crunchy","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/crunchy-0.2.4/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","limit_128"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcrunchy-06f294bd3d2616e8.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcrunchy-06f294bd3d2616e8.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#dirs@6.0.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dirs-6.0.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"dirs","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dirs-6.0.0/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdirs-f36bacd71c7331e3.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#symphonia-metadata@0.5.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/symphonia-metadata-0.5.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"symphonia_metadata","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/symphonia-metadata-0.5.5/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsymphonia_metadata-d416baa62e690327.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#gdkx11@0.18.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gdkx11-0.18.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"gdkx11","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gdkx11-0.18.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libgdkx11-913940b999e6ce08.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#wry@0.53.5","linked_libs":[],"linked_paths":[],"cfgs":["linux","gtk"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/wry-74f203a30cb21d8f/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-utils@2.8.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-utils-2.8.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tauri_utils","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-utils-2.8.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["brotli","compression","resources","walkdir"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtauri_utils-eedd27dcce98d576.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#async-channel@2.5.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-channel-2.5.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"async_channel","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-channel-2.5.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libasync_channel-a94c303d741bb4dd.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#block-buffer@0.10.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/block-buffer-0.10.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"block_buffer","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/block-buffer-0.10.4/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libblock_buffer-1b82f4e08877c431.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#gdkwayland-sys@0.18.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gdkwayland-sys-0.18.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"gdk_wayland_sys","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/gdkwayland-sys-0.18.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libgdk_wayland_sys-b7e590876e06b236.rmeta"],"executable":null,"fresh":true}
@@ -525,211 +525,211 @@
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#zvariant_utils@3.2.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zvariant_utils-3.2.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"zvariant_utils","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zvariant_utils-3.2.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzvariant_utils-22f97e5c9de107f7.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzvariant_utils-22f97e5c9de107f7.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#async-trait@0.1.89","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-trait-0.1.89/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"async_trait","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-trait-0.1.89/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libasync_trait-9ca9efcd3fd9bfd0.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#zerocopy@0.8.31","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zerocopy-0.8.31/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"zerocopy","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zerocopy-0.8.31/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["simd"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzerocopy-a04628393b5ec983.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rustix@1.1.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustix-1.1.3/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustix-1.1.3/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","event","fs","net","pipe","process","std","time"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/rustix-07c64ac039831164/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#unicode-ident@1.0.22","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unicode-ident-1.0.22/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"unicode_ident","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unicode-ident-1.0.22/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libunicode_ident-7ea91a41f77fe445.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#static_assertions@1.1.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/static_assertions-1.1.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"static_assertions","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/static_assertions-1.1.0/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libstatic_assertions-f0a9439e0694ace3.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-runtime-wry@2.9.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-runtime-wry-2.9.3/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-runtime-wry-2.9.3/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["common-controls-v6","x11"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/tauri-runtime-wry-66c91cb79e92f1f0/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#base64@0.22.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/base64-0.22.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"base64","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/base64-0.22.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbase64-939c343dc45ba9e1.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbase64-939c343dc45ba9e1.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rustix@1.1.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustix-1.1.3/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustix-1.1.3/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","event","fs","net","pipe","process","std","time"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/rustix-07c64ac039831164/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#unicode-segmentation@1.12.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unicode-segmentation-1.12.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"unicode_segmentation","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unicode-segmentation-1.12.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libunicode_segmentation-2458a3dacba13ad5.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-codegen@2.5.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-codegen-2.5.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tauri_codegen","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-codegen-2.5.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["brotli","compression"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtauri_codegen-d325ada5ac93ea23.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtauri_codegen-d325ada5ac93ea23.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#wry@0.53.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wry-0.53.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"wry","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wry-0.53.5/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["drag-drop","gdkx11","javascriptcore-rs","linux-body","os-webview","protocol","soup3","webkit2gtk","webkit2gtk-sys","x11","x11-dl"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libwry-2573b2d6d9d2de35.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.103","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/proc-macro2-1.0.103/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"proc_macro2","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/proc-macro2-1.0.103/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","proc-macro"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libproc_macro2-f2c21968afbcfa6f.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#inout@0.1.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/inout-0.1.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"inout","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/inout-0.1.4/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["block-padding"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libinout-b663960e331577bb.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tao@0.34.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tao-0.34.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tao","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tao-0.34.5/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["rwh_06","x11"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtao-2f1eb12d17213c6b.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#zvariant_derive@5.8.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zvariant_derive-5.8.0/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"zvariant_derive","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zvariant_derive-5.8.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzvariant_derive-6e6f0bd2cd80640a.so"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#rustix@1.1.3","linked_libs":[],"linked_paths":[],"cfgs":["static_assertions","lower_upper_exp_for_non_zero","rustc_diagnostics","linux_raw_dep","linux_raw","linux_like","linux_kernel"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/rustix-a330250b3947a510/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#ppv-lite86@0.2.21","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ppv-lite86-0.2.21/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"ppv_lite86","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ppv-lite86-0.2.21/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["simd","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libppv_lite86-8516ad1001f80ec1.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-runtime-wry@2.9.3","linked_libs":[],"linked_paths":[],"cfgs":["desktop"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/tauri-runtime-wry-24267e1c1ff7adc9/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#keyboard-types@0.7.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/keyboard-types-0.7.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"keyboard_types","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/keyboard-types-0.7.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","serde","unicode-segmentation","webdriver"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libkeyboard_types-96b7bf2b1b1a2855.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#digest@0.10.7","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/digest-0.10.7/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"digest","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/digest-0.10.7/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","block-buffer","core-api","default","mac","std","subtle"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdigest-adec77c3e2ffbcea.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tiny-keccak@2.0.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tiny-keccak-2.0.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tiny_keccak","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tiny-keccak-2.0.2/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","shake"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtiny_keccak-e21505b582b7000d.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtiny_keccak-e21505b582b7000d.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#base64@0.22.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/base64-0.22.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"base64","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/base64-0.22.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbase64-939c343dc45ba9e1.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbase64-939c343dc45ba9e1.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-runtime-wry@2.9.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-runtime-wry-2.9.3/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-runtime-wry-2.9.3/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["common-controls-v6","x11"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/tauri-runtime-wry-66c91cb79e92f1f0/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#unicode-ident@1.0.22","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unicode-ident-1.0.22/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"unicode_ident","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/unicode-ident-1.0.22/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libunicode_ident-7ea91a41f77fe445.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-runtime@2.9.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-runtime-2.9.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tauri_runtime","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-runtime-2.9.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtauri_runtime-9fe7d51db05887bd.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-runtime-wry@2.9.3","linked_libs":[],"linked_paths":[],"cfgs":["desktop"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/tauri-runtime-wry-24267e1c1ff7adc9/out"}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#rustix@1.1.3","linked_libs":[],"linked_paths":[],"cfgs":["static_assertions","lower_upper_exp_for_non_zero","rustc_diagnostics","linux_raw_dep","linux_raw","linux_like","linux_kernel"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/rustix-a330250b3947a510/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#zvariant_derive@5.8.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zvariant_derive-5.8.0/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"zvariant_derive","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zvariant_derive-5.8.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzvariant_derive-6e6f0bd2cd80640a.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tao@0.34.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tao-0.34.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tao","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tao-0.34.5/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["rwh_06","x11"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtao-2f1eb12d17213c6b.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#keyboard-types@0.7.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/keyboard-types-0.7.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"keyboard_types","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/keyboard-types-0.7.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","serde","unicode-segmentation","webdriver"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libkeyboard_types-96b7bf2b1b1a2855.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#ppv-lite86@0.2.21","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ppv-lite86-0.2.21/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"ppv_lite86","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ppv-lite86-0.2.21/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["simd","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libppv_lite86-8516ad1001f80ec1.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#proc-macro2@1.0.103","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/proc-macro2-1.0.103/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"proc_macro2","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/proc-macro2-1.0.103/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","proc-macro"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libproc_macro2-f2c21968afbcfa6f.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#digest@0.10.7","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/digest-0.10.7/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"digest","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/digest-0.10.7/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","block-buffer","core-api","default","mac","std","subtle"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdigest-adec77c3e2ffbcea.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-codegen@2.5.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-codegen-2.5.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tauri_codegen","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-codegen-2.5.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["brotli","compression"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtauri_codegen-d325ada5ac93ea23.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtauri_codegen-d325ada5ac93ea23.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#inout@0.1.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/inout-0.1.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"inout","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/inout-0.1.4/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["block-padding"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libinout-b663960e331577bb.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tiny-keccak@2.0.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tiny-keccak-2.0.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tiny_keccak","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tiny-keccak-2.0.2/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","shake"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtiny_keccak-e21505b582b7000d.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtiny_keccak-e21505b582b7000d.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#wry@0.53.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wry-0.53.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"wry","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wry-0.53.5/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["drag-drop","gdkx11","javascriptcore-rs","linux-body","os-webview","protocol","soup3","webkit2gtk","webkit2gtk-sys","x11","x11-dl"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libwry-2573b2d6d9d2de35.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#piper@0.2.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/piper-0.2.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"piper","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/piper-0.2.4/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","futures-io","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libpiper-275d5b717f1b1b96.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#http-body@1.0.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/http-body-1.0.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"http_body","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/http-body-1.0.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libhttp_body-bfeba985aa29ed82.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#ring@0.17.14","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ring-0.17.14/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ring-0.17.14/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","dev_urandom_fallback"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/ring-212f980b3df4d950/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#serialize-to-javascript-impl@0.1.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serialize-to-javascript-impl-0.1.2/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"serialize_to_javascript_impl","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serialize-to-javascript-impl-0.1.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libserialize_to_javascript_impl-b3c5ee99e8d5f178.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#zvariant_utils@1.0.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zvariant_utils-1.0.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"zvariant_utils","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zvariant_utils-1.0.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzvariant_utils-8cf8c95526312dec.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzvariant_utils-8cf8c95526312dec.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#event-listener@2.5.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/event-listener-2.5.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"event_listener","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/event-listener-2.5.3/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libevent_listener-7e8f7ecccfe31d89.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#linux-raw-sys@0.11.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/linux-raw-sys-0.11.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"linux_raw_sys","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/linux-raw-sys-0.11.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["auxvec","elf","errno","general","if_ether","ioctl","net","netlink","no_std","prctl","xdp"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liblinux_raw_sys-220982a4741d8f88.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rustix@1.1.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustix-1.1.3/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustix-1.1.3/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","fs","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/rustix-397a42e4c3c8a119/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#io-lifetimes@1.0.11","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/io-lifetimes-1.0.11/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/io-lifetimes-1.0.11/build.rs","edition":"2018","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["close","hermit-abi","libc","windows-sys"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/io-lifetimes-44680a75b5ae54aa/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#zeroize@1.8.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zeroize-1.8.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"zeroize","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zeroize-1.8.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzeroize-70ca637b85868642.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tower-service@0.3.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tower-service-0.3.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tower_service","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tower-service-0.3.3/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtower_service-23dc759aeb94487a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#muda@0.17.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/muda-0.17.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"muda","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/muda-0.17.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["common-controls-v6","gtk","serde"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libmuda-067e0220b3386bc6.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rand_chacha@0.3.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rand_chacha-0.3.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"rand_chacha","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rand_chacha-0.3.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librand_chacha-8ca3fd23260c7470.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#cipher@0.4.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cipher-0.4.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"cipher","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cipher-0.4.4/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","block-padding"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcipher-3e1953e93cc0261e.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#quote@1.0.42","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/quote-1.0.42/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"quote","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/quote-1.0.42/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","proc-macro"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libquote-895b92c2f7c93a06.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#rustix@1.1.3","linked_libs":[],"linked_paths":[],"cfgs":["static_assertions","lower_upper_exp_for_non_zero","rustc_diagnostics","linux_raw_dep","linux_raw","linux_like","linux_kernel"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/rustix-403f6d64f8762c70/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rustls-pki-types@1.13.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustls-pki-types-1.13.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"rustls_pki_types","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustls-pki-types-1.13.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librustls_pki_types-1f7464d75dbf17d4.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#ring@0.17.14","linked_libs":["static=ring_core_0_17_14_","static=ring_core_0_17_14__test"],"linked_paths":["native=/home/trav/repos/noteflow/client/src-tauri/target/debug/build/ring-0b3b44425cbd11ef/out"],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/ring-0b3b44425cbd11ef/out"}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#io-lifetimes@1.0.11","linked_libs":[],"linked_paths":[],"cfgs":["io_safety_is_in_std","panic_in_const_fn"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/io-lifetimes-d16e57c301c4fa43/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#serialize-to-javascript@0.1.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serialize-to-javascript-0.1.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"serialize_to_javascript","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serialize-to-javascript-0.1.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libserialize_to_javascript-6ac5e1d2a95332cc.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rustix@1.1.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustix-1.1.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"rustix","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustix-1.1.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","event","fs","net","pipe","process","std","time"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librustix-011883fb82cf8011.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-runtime-wry@2.9.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-runtime-wry-2.9.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tauri_runtime_wry","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-runtime-wry-2.9.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["common-controls-v6","x11"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtauri_runtime_wry-66cdbef3b43305c6.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-macros@2.5.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-macros-2.5.2/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"tauri_macros","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-macros-2.5.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["compression","custom-protocol"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtauri_macros-9f87c273bce0f86c.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#blocking@1.6.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/blocking-1.6.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"blocking","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/blocking-1.6.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libblocking-01be0e0d849575e7.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rustix@1.1.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustix-1.1.3/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustix-1.1.3/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","fs","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/rustix-397a42e4c3c8a119/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#io-lifetimes@1.0.11","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/io-lifetimes-1.0.11/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/io-lifetimes-1.0.11/build.rs","edition":"2018","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["close","hermit-abi","libc","windows-sys"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/io-lifetimes-44680a75b5ae54aa/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#event-listener@2.5.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/event-listener-2.5.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"event_listener","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/event-listener-2.5.3/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libevent_listener-7e8f7ecccfe31d89.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#const-random-macro@0.1.16","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/const-random-macro-0.1.16/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"const_random_macro","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/const-random-macro-0.1.16/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libconst_random_macro-98777b160ca5160c.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#muda@0.17.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/muda-0.17.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"muda","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/muda-0.17.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["common-controls-v6","gtk","serde"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libmuda-067e0220b3386bc6.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#cipher@0.4.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cipher-0.4.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"cipher","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cipher-0.4.4/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","block-padding"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcipher-3e1953e93cc0261e.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#blocking@1.6.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/blocking-1.6.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"blocking","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/blocking-1.6.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libblocking-01be0e0d849575e7.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#serialize-to-javascript@0.1.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serialize-to-javascript-0.1.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"serialize_to_javascript","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/serialize-to-javascript-0.1.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libserialize_to_javascript-6ac5e1d2a95332cc.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rustls-pki-types@1.13.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustls-pki-types-1.13.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"rustls_pki_types","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustls-pki-types-1.13.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librustls_pki_types-1f7464d75dbf17d4.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#io-lifetimes@1.0.11","linked_libs":[],"linked_paths":[],"cfgs":["io_safety_is_in_std","panic_in_const_fn"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/io-lifetimes-d16e57c301c4fa43/out"}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#rustix@1.1.3","linked_libs":[],"linked_paths":[],"cfgs":["static_assertions","lower_upper_exp_for_non_zero","rustc_diagnostics","linux_raw_dep","linux_raw","linux_like","linux_kernel"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/rustix-403f6d64f8762c70/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rustix@1.1.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustix-1.1.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"rustix","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustix-1.1.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","event","fs","net","pipe","process","std","time"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librustix-011883fb82cf8011.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#ring@0.17.14","linked_libs":["static=ring_core_0_17_14_","static=ring_core_0_17_14__test"],"linked_paths":["native=/home/trav/repos/noteflow/client/src-tauri/target/debug/build/ring-0b3b44425cbd11ef/out"],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/ring-0b3b44425cbd11ef/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-runtime-wry@2.9.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-runtime-wry-2.9.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tauri_runtime_wry","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-runtime-wry-2.9.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["common-controls-v6","x11"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtauri_runtime_wry-66cdbef3b43305c6.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rand_chacha@0.3.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rand_chacha-0.3.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"rand_chacha","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rand_chacha-0.3.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librand_chacha-8ca3fd23260c7470.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-macros@2.5.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-macros-2.5.2/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"tauri_macros","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-macros-2.5.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["compression","custom-protocol"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtauri_macros-9f87c273bce0f86c.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#quote@1.0.42","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/quote-1.0.42/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"quote","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/quote-1.0.42/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","proc-macro"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libquote-895b92c2f7c93a06.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#num-integer@0.1.46","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/num-integer-0.1.46/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"num_integer","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/num-integer-0.1.46/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["i128","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libnum_integer-3d05d4646502d363.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tokio-util@0.7.17","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-util-0.7.17/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tokio_util","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-util-0.7.17/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["codec","default","io"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtokio_util-dc5f5d17e63ca61f.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#async-io@2.6.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-io-2.6.0/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-io-2.6.0/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/async-io-3298d76580abf572/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#polling@2.8.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/polling-2.8.0/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/polling-2.8.0/build.rs","edition":"2018","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/polling-9053f627bd0890bf/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#async-io@2.6.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-io-2.6.0/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-io-2.6.0/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/async-io-3298d76580abf572/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#memoffset@0.7.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/memoffset-0.7.1/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/memoffset-0.7.1/build.rs","edition":"2015","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/memoffset-227e1084d92f1484/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#equivalent@1.0.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/equivalent-1.0.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"equivalent","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/equivalent-1.0.2/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libequivalent-8b054abaa056da40.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#waker-fn@1.2.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/waker-fn-1.2.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"waker_fn","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/waker-fn-1.2.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libwaker_fn-548457045182d16a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rustix@0.37.28","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustix-0.37.28/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustix-0.37.28/build.rs","edition":"2018","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["fs","io-lifetimes","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/rustix-558c2c0ea9626650/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#hashbrown@0.16.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/hashbrown-0.16.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"hashbrown","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/hashbrown-0.16.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libhashbrown-ab5a0870de3d1859.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#bitflags@2.10.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bitflags-2.10.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"bitflags","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bitflags-2.10.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbitflags-482c81c836e23fd3.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbitflags-482c81c836e23fd3.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#fastrand@1.9.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/fastrand-1.9.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"fastrand","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/fastrand-1.9.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfastrand-7fd5358017a0f756.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#httparse@1.10.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/httparse-1.10.1/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/httparse-1.10.1/build.rs","edition":"2018","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/httparse-048477c8fd570552/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#linux-raw-sys@0.11.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/linux-raw-sys-0.11.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"linux_raw_sys","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/linux-raw-sys-0.11.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["auxvec","elf","errno","general","ioctl","no_std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liblinux_raw_sys-7f94dd0bf6db6991.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liblinux_raw_sys-7f94dd0bf6db6991.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#prettyplease@0.2.37","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/prettyplease-0.2.37/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/prettyplease-0.2.37/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/prettyplease-dfa7ee66a4655c3f/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#bitflags@2.10.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bitflags-2.10.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"bitflags","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bitflags-2.10.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbitflags-482c81c836e23fd3.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbitflags-482c81c836e23fd3.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#heck@0.5.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/heck-0.5.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"heck","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/heck-0.5.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libheck-a0a7590fe437bcd9.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#const-random@0.1.18","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/const-random-0.1.18/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"const_random","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/const-random-0.1.18/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libconst_random-5003dd68732ff995.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#equivalent@1.0.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/equivalent-1.0.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"equivalent","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/equivalent-1.0.2/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libequivalent-8b054abaa056da40.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#fastrand@1.9.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/fastrand-1.9.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"fastrand","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/fastrand-1.9.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfastrand-7fd5358017a0f756.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#linux-raw-sys@0.11.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/linux-raw-sys-0.11.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"linux_raw_sys","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/linux-raw-sys-0.11.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["auxvec","elf","errno","general","ioctl","no_std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liblinux_raw_sys-7f94dd0bf6db6991.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liblinux_raw_sys-7f94dd0bf6db6991.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#httparse@1.10.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/httparse-1.10.1/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/httparse-1.10.1/build.rs","edition":"2018","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/httparse-048477c8fd570552/build-script-build"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#polling@2.8.0","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/polling-62e36d53857b842a/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#polling@3.11.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/polling-3.11.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"polling","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/polling-3.11.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libpolling-3cf55890f15ca97c.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#memoffset@0.7.1","linked_libs":[],"linked_paths":[],"cfgs":["tuple_ty","allow_clippy","maybe_uninit","doctests","raw_ref_macros"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/memoffset-d01b03faac324c49/out"}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#httparse@1.10.1","linked_libs":[],"linked_paths":[],"cfgs":["httparse_simd_neon_intrinsics","httparse_simd"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/httparse-b25763ec913d37bf/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri@2.9.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-2.9.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tauri","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-2.9.5/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["common-controls-v6","compression","custom-protocol","default","dynamic-acl","tauri-runtime-wry","webkit2gtk","webview2-com","wry","x11"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtauri-ecb72a62cd6e7dfe.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#indexmap@2.12.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/indexmap-2.12.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"indexmap","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/indexmap-2.12.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libindexmap-67e54cfc98d826e6.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rustix@1.1.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustix-1.1.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"rustix","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustix-1.1.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","fs","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librustix-be2e55632bffa3d6.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librustix-be2e55632bffa3d6.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#rustix@0.37.28","linked_libs":[],"linked_paths":[],"cfgs":["linux_raw","asm","linux_like","linux_kernel"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/rustix-9a453d3a20e8a366/out"}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#prettyplease@0.2.37","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/prettyplease-c54f8dde71d5bf36/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#futures-lite@1.13.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/futures-lite-1.13.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"futures_lite","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/futures-lite-1.13.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","fastrand","futures-io","memchr","parking","std","waker-fn"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfutures_lite-0f7bda0189eac96e.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#async-io@2.6.0","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/async-io-6da9fb6ed9ce2e97/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#io-lifetimes@1.0.11","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/io-lifetimes-1.0.11/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"io_lifetimes","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/io-lifetimes-1.0.11/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["close","hermit-abi","libc","windows-sys"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libio_lifetimes-c13aef91b4643fa4.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rand@0.8.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rand-0.8.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"rand","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rand-0.8.5/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","getrandom","libc","rand_chacha","small_rng","std","std_rng"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librand-cda4a234d01fcf8b.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#httparse@1.10.1","linked_libs":[],"linked_paths":[],"cfgs":["httparse_simd_neon_intrinsics","httparse_simd"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/httparse-b25763ec913d37bf/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#indexmap@2.12.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/indexmap-2.12.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"indexmap","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/indexmap-2.12.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libindexmap-67e54cfc98d826e6.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#futures-lite@1.13.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/futures-lite-1.13.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"futures_lite","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/futures-lite-1.13.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","fastrand","futures-io","memchr","parking","std","waker-fn"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfutures_lite-0f7bda0189eac96e.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rustix@1.1.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustix-1.1.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"rustix","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustix-1.1.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","fs","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librustix-be2e55632bffa3d6.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librustix-be2e55632bffa3d6.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri@2.9.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-2.9.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tauri","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-2.9.5/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["common-controls-v6","compression","custom-protocol","default","dynamic-acl","tauri-runtime-wry","webkit2gtk","webview2-com","wry","x11"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtauri-ecb72a62cd6e7dfe.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#rustix@0.37.28","linked_libs":[],"linked_paths":[],"cfgs":["linux_raw","asm","linux_like","linux_kernel"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/rustix-9a453d3a20e8a366/out"}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#memoffset@0.7.1","linked_libs":[],"linked_paths":[],"cfgs":["tuple_ty","allow_clippy","maybe_uninit","doctests","raw_ref_macros"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/memoffset-d01b03faac324c49/out"}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#prettyplease@0.2.37","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/prettyplease-c54f8dde71d5bf36/out"}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#async-io@2.6.0","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/async-io-6da9fb6ed9ce2e97/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#polling@3.11.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/polling-3.11.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"polling","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/polling-3.11.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libpolling-3cf55890f15ca97c.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#syn@2.0.111","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/syn-2.0.111/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"syn","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/syn-2.0.111/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["clone-impls","default","derive","extra-traits","full","parsing","printing","proc-macro"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsyn-0099781e116dd12c.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#const-random@0.1.18","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/const-random-0.1.18/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"const_random","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/const-random-0.1.18/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libconst_random-5003dd68732ff995.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#async-lock@2.8.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-lock-2.8.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"async_lock","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-lock-2.8.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libasync_lock-b9ad73a87d3ac874.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#zvariant_derive@3.15.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zvariant_derive-3.15.2/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"zvariant_derive","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zvariant_derive-3.15.2/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzvariant_derive-b9e04ba6263a7e2a.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#syn@2.0.111","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/syn-2.0.111/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"syn","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/syn-2.0.111/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["clone-impls","default","derive","extra-traits","full","parsing","printing","proc-macro"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsyn-0099781e116dd12c.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rand@0.8.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rand-0.8.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"rand","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rand-0.8.5/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","getrandom","libc","rand_chacha","small_rng","std","std_rng"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librand-cda4a234d01fcf8b.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#symphonia-utils-xiph@0.5.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/symphonia-utils-xiph-0.5.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"symphonia_utils_xiph","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/symphonia-utils-xiph-0.5.5/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsymphonia_utils_xiph-1c0e146f6e70405a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#async-executor@1.13.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-executor-1.13.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"async_executor","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-executor-1.13.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libasync_executor-5b0306daa7310cf8.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#prost@0.13.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/prost-0.13.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"prost","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/prost-0.13.5/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["derive","prost-derive","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libprost-54553607397206d5.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libprost-54553607397206d5.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#enumflags2@0.7.12","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/enumflags2-0.7.12/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"enumflags2","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/enumflags2-0.7.12/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["serde"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libenumflags2-c5d68eb532b9eee4.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libenumflags2-c5d68eb532b9eee4.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-plugin-fs@2.4.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-plugin-fs-2.4.4/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-plugin-fs-2.4.4/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/tauri-plugin-fs-8f8be81cee70aadb/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#ordered-stream@0.2.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ordered-stream-0.2.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"ordered_stream","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ordered-stream-0.2.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libordered_stream-bb739ed304a29e95.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#async-fs@1.6.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-fs-1.6.0/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-fs-1.6.0/build.rs","edition":"2018","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/async-fs-835899cd47d57c24/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#async-io@1.13.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-io-1.13.0/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-io-1.13.0/build.rs","edition":"2018","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/async-io-b9ad08a3d28d8aee/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#async-fs@1.6.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-fs-1.6.0/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-fs-1.6.0/build.rs","edition":"2018","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/async-fs-835899cd47d57c24/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#alsa-sys@0.3.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/alsa-sys-0.3.1/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/alsa-sys-0.3.1/build.rs","edition":"2018","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/alsa-sys-3223fc1c5e88ad8d/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#signal-hook@0.3.18","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/signal-hook-0.3.18/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/signal-hook-0.3.18/build.rs","edition":"2018","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/signal-hook-aaf08e78d571bb4f/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rustversion@1.0.22","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustversion-1.0.22/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustversion-1.0.22/build/build.rs","edition":"2018","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/rustversion-685ed1eb2f5bd293/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#try-lock@0.2.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/try-lock-0.2.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"try_lock","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/try-lock-0.2.5/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtry_lock-87e2575cd016009a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tower-layer@0.3.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tower-layer-0.3.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tower_layer","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tower-layer-0.3.3/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtower_layer-6cfc3383d04c6472.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#cfg_aliases@0.2.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cfg_aliases-0.2.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"cfg_aliases","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cfg_aliases-0.2.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcfg_aliases-88ae697f10203bf0.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcfg_aliases-88ae697f10203bf0.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#endi@1.1.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/endi-1.1.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"endi","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/endi-1.1.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libendi-e65d7ab04db53af4.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libendi-e65d7ab04db53af4.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#linux-raw-sys@0.3.8","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/linux-raw-sys-0.3.8/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"linux_raw_sys","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/linux-raw-sys-0.3.8/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["errno","general","ioctl","no_std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liblinux_raw_sys-01ea6c1cab925342.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#fixedbitset@0.5.7","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/fixedbitset-0.5.7/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"fixedbitset","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/fixedbitset-0.5.7/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfixedbitset-0458ac0019c5b591.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfixedbitset-0458ac0019c5b591.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#fastrand@2.3.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/fastrand-2.3.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"fastrand","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/fastrand-2.3.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfastrand-3ceb7b7fa26ada13.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfastrand-3ceb7b7fa26ada13.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#untrusted@0.9.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/untrusted-0.9.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"untrusted","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/untrusted-0.9.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libuntrusted-f599b56918742ec3.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#hex@0.4.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/hex-0.4.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"hex","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/hex-0.4.3/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libhex-22a982ce9f9ed34a.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#alsa-sys@0.3.1","linked_libs":["asound"],"linked_paths":["native=/usr/lib/x86_64-linux-gnu"],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/alsa-sys-d07e7f3e8ce82056/out"}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#async-io@1.13.0","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/async-io-7e3294b7afad8a04/out"}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#signal-hook@0.3.18","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/signal-hook-043504dab41ceb3a/out"}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-plugin-fs@2.4.4","linked_libs":[],"linked_paths":[],"cfgs":["desktop"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/tauri-plugin-fs-18155bc7625726c8/out"}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#rustversion@1.0.22","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/rustversion-c490c10c4b28b3dc/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#nix@0.30.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nix-0.30.1/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nix-0.30.1/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["feature","memoffset","socket","uio","user"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/nix-e494aa0ef2feaf73/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#want@0.3.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/want-0.3.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"want","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/want-0.3.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libwant-10cdedfcc96a6c8f.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#async-fs@1.6.0","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/async-fs-024e30cfad7feb8e/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#cfg_aliases@0.2.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cfg_aliases-0.2.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"cfg_aliases","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cfg_aliases-0.2.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcfg_aliases-88ae697f10203bf0.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcfg_aliases-88ae697f10203bf0.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#try-lock@0.2.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/try-lock-0.2.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"try_lock","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/try-lock-0.2.5/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtry_lock-87e2575cd016009a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#signal-hook@0.3.18","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/signal-hook-0.3.18/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/signal-hook-0.3.18/build.rs","edition":"2018","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/signal-hook-aaf08e78d571bb4f/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#fixedbitset@0.5.7","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/fixedbitset-0.5.7/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"fixedbitset","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/fixedbitset-0.5.7/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfixedbitset-0458ac0019c5b591.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfixedbitset-0458ac0019c5b591.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tower-layer@0.3.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tower-layer-0.3.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tower_layer","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tower-layer-0.3.3/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtower_layer-6cfc3383d04c6472.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#fastrand@2.3.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/fastrand-2.3.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"fastrand","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/fastrand-2.3.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfastrand-3ceb7b7fa26ada13.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfastrand-3ceb7b7fa26ada13.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rustversion@1.0.22","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustversion-1.0.22/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustversion-1.0.22/build/build.rs","edition":"2018","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/rustversion-685ed1eb2f5bd293/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#untrusted@0.9.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/untrusted-0.9.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"untrusted","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/untrusted-0.9.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libuntrusted-f599b56918742ec3.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#linux-raw-sys@0.3.8","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/linux-raw-sys-0.3.8/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"linux_raw_sys","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/linux-raw-sys-0.3.8/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["errno","general","ioctl","no_std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liblinux_raw_sys-01ea6c1cab925342.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#endi@1.1.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/endi-1.1.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"endi","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/endi-1.1.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libendi-e65d7ab04db53af4.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libendi-e65d7ab04db53af4.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#petgraph@0.7.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/petgraph-0.7.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"petgraph","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/petgraph-0.7.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libpetgraph-957db78cf60884ef.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libpetgraph-957db78cf60884ef.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#ring@0.17.14","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ring-0.17.14/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"ring","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ring-0.17.14/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","dev_urandom_fallback"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libring-847f22bcd33d662b.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rustix@0.37.28","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustix-0.37.28/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"rustix","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustix-0.37.28/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["fs","io-lifetimes","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librustix-d82adf02b9f36ed5.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tempfile@3.23.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tempfile-3.23.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tempfile","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tempfile-3.23.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","getrandom"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtempfile-a0531f0390c4255f.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtempfile-a0531f0390c4255f.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#zvariant@5.8.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zvariant-5.8.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"zvariant","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zvariant-5.8.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","enumflags2"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzvariant-2fecbf6e403b5a02.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzvariant-2fecbf6e403b5a02.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#nix@0.30.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nix-0.30.1/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nix-0.30.1/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["feature","memoffset","socket","uio","user"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/nix-e494aa0ef2feaf73/build-script-build"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#async-fs@1.6.0","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/async-fs-024e30cfad7feb8e/out"}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#signal-hook@0.3.18","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/signal-hook-043504dab41ceb3a/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#want@0.3.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/want-0.3.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"want","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/want-0.3.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libwant-10cdedfcc96a6c8f.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-plugin-fs@2.4.4","linked_libs":[],"linked_paths":[],"cfgs":["desktop"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/tauri-plugin-fs-18155bc7625726c8/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#prost-types@0.13.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/prost-types-0.13.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"prost_types","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/prost-types-0.13.5/src/lib.rs","edition":"2021","doc":true,"doctest":false,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libprost_types-482b9d95212c9482.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libprost_types-482b9d95212c9482.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#httparse@1.10.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/httparse-1.10.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"httparse","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/httparse-1.10.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libhttparse-bcdf8554eb29a02a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#h2@0.4.12","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/h2-0.4.12/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"h2","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/h2-0.4.12/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libh2-d274fe5ed547597d.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#zvariant_utils@3.2.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zvariant_utils-3.2.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"zvariant_utils","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zvariant_utils-3.2.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzvariant_utils-79f3b6f894938c58.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#zvariant@3.15.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zvariant-3.15.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"zvariant","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zvariant-3.15.2/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["enumflags2"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzvariant-f7c5c1e887f25796.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#alsa-sys@0.3.1","linked_libs":["asound"],"linked_paths":["native=/usr/lib/x86_64-linux-gnu"],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/alsa-sys-d07e7f3e8ce82056/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#zvariant@5.8.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zvariant-5.8.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"zvariant","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zvariant-5.8.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","enumflags2"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzvariant-2fecbf6e403b5a02.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzvariant-2fecbf6e403b5a02.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rustix@0.37.28","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustix-0.37.28/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"rustix","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustix-0.37.28/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["fs","io-lifetimes","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librustix-d82adf02b9f36ed5.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#ring@0.17.14","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ring-0.17.14/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"ring","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ring-0.17.14/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","dev_urandom_fallback"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libring-847f22bcd33d662b.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#rustversion@1.0.22","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/rustversion-c490c10c4b28b3dc/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tempfile@3.23.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tempfile-3.23.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tempfile","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tempfile-3.23.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","getrandom"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtempfile-a0531f0390c4255f.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtempfile-a0531f0390c4255f.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#async-io@1.13.0","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/async-io-7e3294b7afad8a04/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#memoffset@0.7.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/memoffset-0.7.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"memoffset","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/memoffset-0.7.1/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libmemoffset-8576446beb21236e.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#async-io@2.6.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-io-2.6.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"async_io","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-io-2.6.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libasync_io-81179adc0532df75.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#prettyplease@0.2.37","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/prettyplease-0.2.37/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"prettyplease","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/prettyplease-0.2.37/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libprettyplease-b96c6b7d545b39df.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libprettyplease-b96c6b7d545b39df.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#zvariant_utils@3.2.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zvariant_utils-3.2.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"zvariant_utils","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zvariant_utils-3.2.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzvariant_utils-79f3b6f894938c58.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#dlv-list@0.5.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dlv-list-0.5.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"dlv_list","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dlv-list-0.5.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdlv_list-61fa05d82270e70c.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#h2@0.4.12","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/h2-0.4.12/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"h2","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/h2-0.4.12/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libh2-d274fe5ed547597d.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#zvariant@3.15.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zvariant-3.15.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"zvariant","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zvariant-3.15.2/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["enumflags2"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzvariant-f7c5c1e887f25796.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#prettyplease@0.2.37","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/prettyplease-0.2.37/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"prettyplease","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/prettyplease-0.2.37/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libprettyplease-b96c6b7d545b39df.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libprettyplease-b96c6b7d545b39df.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#httparse@1.10.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/httparse-1.10.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"httparse","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/httparse-1.10.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libhttparse-bcdf8554eb29a02a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#polling@2.8.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/polling-2.8.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"polling","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/polling-2.8.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libpolling-ad0f2a40f42c6676.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#num-bigint@0.4.6","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/num-bigint-0.4.6/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"num_bigint","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/num-bigint-0.4.6/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libnum_bigint-85e81d2b402f7b28.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-plugin-deep-link@2.4.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-plugin-deep-link-2.4.5/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-plugin-deep-link-2.4.5/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/tauri-plugin-deep-link-4231f53c5df7895c/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#socket2@0.4.10","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/socket2-0.4.10/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"socket2","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/socket2-0.4.10/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["all"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsocket2-4b3921bc91d751da.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#quick-xml@0.30.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/quick-xml-0.30.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"quick_xml","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/quick-xml-0.30.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libquick_xml-06d7e4df69c33569.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libquick_xml-06d7e4df69c33569.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#socket2@0.4.10","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/socket2-0.4.10/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"socket2","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/socket2-0.4.10/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["all"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsocket2-4b3921bc91d751da.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#indexmap@1.9.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/indexmap-1.9.3/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/indexmap-1.9.3/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/indexmap-c764d53552acf5cf/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#sync_wrapper@1.0.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/sync_wrapper-1.0.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"sync_wrapper","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/sync_wrapper-1.0.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsync_wrapper-bb6d3deaacc89e0b.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rustls@0.23.35","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustls-0.23.35/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustls-0.23.35/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["log","logging","ring","std","tls12"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/rustls-5183d499eef1573b/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#static_assertions@1.1.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/static_assertions-1.1.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"static_assertions","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/static_assertions-1.1.0/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libstatic_assertions-fe2f8ccda5223f75.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libstatic_assertions-fe2f8ccda5223f75.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#endi@1.1.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/endi-1.1.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"endi","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/endi-1.1.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libendi-8542e0730db336e1.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#httpdate@1.0.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/httpdate-1.0.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"httpdate","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/httpdate-1.0.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libhttpdate-7d64d45794d25410.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#hashbrown@0.14.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/hashbrown-0.14.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"hashbrown","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/hashbrown-0.14.5/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libhashbrown-6b59dd0fe82a8d3a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#multimap@0.10.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/multimap-0.10.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"multimap","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/multimap-0.10.1/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libmultimap-6910a60d0d67170b.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libmultimap-6910a60d0d67170b.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#static_assertions@1.1.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/static_assertions-1.1.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"static_assertions","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/static_assertions-1.1.0/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libstatic_assertions-fe2f8ccda5223f75.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libstatic_assertions-fe2f8ccda5223f75.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#hashbrown@0.14.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/hashbrown-0.14.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"hashbrown","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/hashbrown-0.14.5/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libhashbrown-6b59dd0fe82a8d3a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rustls@0.23.35","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustls-0.23.35/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustls-0.23.35/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["log","logging","ring","std","tls12"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/rustls-5183d499eef1573b/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#endi@1.1.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/endi-1.1.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"endi","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/endi-1.1.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libendi-8542e0730db336e1.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#sync_wrapper@1.0.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/sync_wrapper-1.0.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"sync_wrapper","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/sync_wrapper-1.0.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsync_wrapper-bb6d3deaacc89e0b.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#httpdate@1.0.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/httpdate-1.0.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"httpdate","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/httpdate-1.0.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libhttpdate-7d64d45794d25410.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#zbus_names@2.6.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zbus_names-2.6.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"zbus_names","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zbus_names-2.6.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzbus_names-6245a3e14a63b1af.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#indexmap@1.9.3","linked_libs":[],"linked_paths":[],"cfgs":["has_std"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/indexmap-08064c9274b38959/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#num-rational@0.4.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/num-rational-0.4.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"num_rational","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/num-rational-0.4.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["num-bigint","num-bigint-std","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libnum_rational-d62e82a850e8bb1c.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#prost-build@0.13.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/prost-build-0.13.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"prost_build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/prost-build-0.13.5/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","format"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libprost_build-e080985aab6f4759.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libprost_build-e080985aab6f4759.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#zbus_names@4.2.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zbus_names-4.2.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"zbus_names","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zbus_names-4.2.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzbus_names-f7d74c82bd2ffa3a.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzbus_names-f7d74c82bd2ffa3a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#xcb@1.6.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/xcb-1.6.0/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-main","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/xcb-1.6.0/build/main.rs","edition":"2018","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","libxcb_v1_14","randr","render"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/xcb-da395caeb05cc15a/build-script-main"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#zvariant@5.8.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zvariant-5.8.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"zvariant","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zvariant-5.8.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","enumflags2"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzvariant-870d4d59a179e4d0.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#ordered-multimap@0.7.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ordered-multimap-0.7.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"ordered_multimap","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ordered-multimap-0.7.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libordered_multimap-a7e5cdac06cf6b0a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#zbus_names@4.2.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zbus_names-4.2.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"zbus_names","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zbus_names-4.2.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzbus_names-f7d74c82bd2ffa3a.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzbus_names-f7d74c82bd2ffa3a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#hyper@1.8.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/hyper-1.8.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"hyper","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/hyper-1.8.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["client","default","http1","http2","server"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libhyper-a96f65a3667fdd8c.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#async-io@1.13.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-io-1.13.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"async_io","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-io-1.13.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libasync_io-1d678c81b6ac493f.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#rustls@0.23.35","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/rustls-091db159b20c86b3/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#async-io@1.13.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-io-1.13.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"async_io","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-io-1.13.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libasync_io-1d678c81b6ac493f.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-plugin-deep-link@2.4.5","linked_libs":[],"linked_paths":[],"cfgs":["desktop"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/tauri-plugin-deep-link-b5d33a1dac5cac24/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#async-signal@0.2.13","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-signal-0.2.13/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"async_signal","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-signal-0.2.13/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libasync_signal-3c2900400697d75b.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#prost-build@0.13.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/prost-build-0.13.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"prost_build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/prost-build-0.13.5/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","format"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libprost_build-e080985aab6f4759.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libprost_build-e080985aab6f4759.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#xcb@1.6.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/xcb-1.6.0/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-main","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/xcb-1.6.0/build/main.rs","edition":"2018","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","libxcb_v1_14","randr","render"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/xcb-da395caeb05cc15a/build-script-main"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#indexmap@1.9.3","linked_libs":[],"linked_paths":[],"cfgs":["has_std"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/indexmap-08064c9274b38959/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#ordered-multimap@0.7.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ordered-multimap-0.7.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"ordered_multimap","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ordered-multimap-0.7.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libordered_multimap-a7e5cdac06cf6b0a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#num-rational@0.4.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/num-rational-0.4.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"num_rational","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/num-rational-0.4.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["num-bigint","num-bigint-std","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libnum_rational-d62e82a850e8bb1c.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#nix@0.26.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nix-0.26.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"nix","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nix-0.26.4/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["feature","memoffset","socket","uio","user"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libnix-9b3a70e7548d5aac.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rustls-webpki@0.103.8","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustls-webpki-0.103.8/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"webpki","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustls-webpki-0.103.8/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","ring","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libwebpki-fad2188a86674dea.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#signal-hook@0.3.18","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/signal-hook-0.3.18/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"signal_hook","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/signal-hook-0.3.18/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsignal_hook-aea6e306aa514362.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#alsa-sys@0.3.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/alsa-sys-0.3.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"alsa_sys","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/alsa-sys-0.3.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libalsa_sys-e8451f4339da4614.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#nix@0.30.1","linked_libs":[],"linked_paths":[],"cfgs":["linux","linux_android"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/nix-2db5d1e79e21b67c/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#async-signal@0.2.13","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-signal-0.2.13/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"async_signal","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-signal-0.2.13/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libasync_signal-3c2900400697d75b.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rustversion@1.0.22","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustversion-1.0.22/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"rustversion","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustversion-1.0.22/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librustversion-cb72cc6897e60a92.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#signal-hook@0.3.18","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/signal-hook-0.3.18/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"signal_hook","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/signal-hook-0.3.18/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsignal_hook-aea6e306aa514362.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#async-fs@1.6.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-fs-1.6.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"async_fs","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-fs-1.6.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libasync_fs-505f15360d05004c.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#nix@0.30.1","linked_libs":[],"linked_paths":[],"cfgs":["linux","linux_android"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/nix-2db5d1e79e21b67c/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#alsa-sys@0.3.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/alsa-sys-0.3.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"alsa_sys","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/alsa-sys-0.3.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libalsa_sys-e8451f4339da4614.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#num-iter@0.1.45","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/num-iter-0.1.45/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"num_iter","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/num-iter-0.1.45/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["i128","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libnum_iter-05d4fa8bd63208f0.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#aes@0.8.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/aes-0.8.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"aes","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/aes-0.8.4/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libaes-ad60ff0a37fd0606.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#async-broadcast@0.5.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-broadcast-0.5.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"async_broadcast","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-broadcast-0.5.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libasync_broadcast-9103e4ff656dadc7.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#zbus_macros@3.15.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zbus_macros-3.15.2/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"zbus_macros","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zbus_macros-3.15.2/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzbus_macros-aeb623f7c0266d18.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#http-body-util@0.1.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/http-body-util-0.1.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"http_body_util","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/http-body-util-0.1.3/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libhttp_body_util-0b6b23fa3607e70f.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#async-broadcast@0.5.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-broadcast-0.5.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"async_broadcast","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-broadcast-0.5.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libasync_broadcast-9103e4ff656dadc7.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#hmac@0.12.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/hmac-0.12.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"hmac","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/hmac-0.12.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libhmac-768a6cfbe0a3abd7.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#aes@0.8.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/aes-0.8.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"aes","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/aes-0.8.4/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libaes-ad60ff0a37fd0606.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#sha1@0.10.6","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/sha1-0.10.6/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"sha1","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/sha1-0.10.6/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsha1-1d5a21087af79fe4.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#hmac@0.12.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/hmac-0.12.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"hmac","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/hmac-0.12.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libhmac-768a6cfbe0a3abd7.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#num-complex@0.4.6","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/num-complex-0.4.6/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"num_complex","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/num-complex-0.4.6/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libnum_complex-45de1bc54662b94c.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#async-lock@3.4.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-lock-3.4.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"async_lock","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-lock-3.4.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libasync_lock-0d1561f7f44a1d87.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-plugin-dialog@2.4.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-plugin-dialog-2.4.2/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-plugin-dialog-2.4.2/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/tauri-plugin-dialog-92450968fb256294/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-plugin-shell@2.3.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-plugin-shell-2.3.3/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-plugin-shell-2.3.3/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/tauri-plugin-shell-66556345cca93cc9/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#universal-hash@0.5.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/universal-hash-0.5.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"universal_hash","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/universal-hash-0.5.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libuniversal_hash-f2e858a77af66441.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#derivative@2.2.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/derivative-2.2.0/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"derivative","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/derivative-2.2.0/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libderivative-56a969e0aa2a7e9e.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#pin-project-internal@1.1.10","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pin-project-internal-1.1.10/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"pin_project_internal","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pin-project-internal-1.1.10/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libpin_project_internal-0ad19e666fe1b8de.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#async-recursion@1.1.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-recursion-1.1.1/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"async_recursion","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-recursion-1.1.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libasync_recursion-e010536611915fbf.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#derivative@2.2.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/derivative-2.2.0/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"derivative","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/derivative-2.2.0/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libderivative-56a969e0aa2a7e9e.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#is-docker@0.2.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/is-docker-0.2.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"is_docker","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/is-docker-0.2.0/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libis_docker-a089e0f2525086b9.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#xdg-home@1.3.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/xdg-home-1.3.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"xdg_home","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/xdg-home-1.3.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libxdg_home-cbef96cdce2f8f79.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#os_pipe@1.2.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/os_pipe-1.2.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"os_pipe","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/os_pipe-1.2.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libos_pipe-72ab97fa1ccde773.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#adler2@2.0.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/adler2-2.0.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"adler2","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/adler2-2.0.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libadler2-3086b8c8a710a842.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#extended@0.1.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/extended-0.1.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"extended","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/extended-0.1.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libextended-30380a485348f16d.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rfd@0.15.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rfd-0.15.4/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rfd-0.15.4/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["common-controls-v6","glib-sys","gobject-sys","gtk-sys","gtk3","tokio"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/rfd-1166ff5a3f7d622a/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#cpal@0.15.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cpal-0.15.3/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cpal-0.15.3/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/cpal-ec8ee90decec6caf/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#simd-adler32@0.3.8","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/simd-adler32-0.3.8/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"simd_adler32","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/simd-adler32-0.3.8/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsimd_adler32-870dc464884e5ce0.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#opaque-debug@0.3.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/opaque-debug-0.3.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"opaque_debug","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/opaque-debug-0.3.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libopaque_debug-1e3af4630ac62466.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rfd@0.15.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rfd-0.15.4/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rfd-0.15.4/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["common-controls-v6","glib-sys","gobject-sys","gtk-sys","gtk3","tokio"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/rfd-1166ff5a3f7d622a/build-script-build"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#extended@0.1.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/extended-0.1.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"extended","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/extended-0.1.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libextended-30380a485348f16d.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#adler2@2.0.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/adler2-2.0.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"adler2","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/adler2-2.0.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libadler2-3086b8c8a710a842.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#hashbrown@0.12.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/hashbrown-0.12.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"hashbrown","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/hashbrown-0.12.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["raw"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libhashbrown-df192999945829b1.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#pin-project@1.1.10","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pin-project-1.1.10/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"pin_project","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pin-project-1.1.10/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libpin_project-b77aeddbfdae70ee.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#cpal@0.15.3","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/cpal-ca07765a6658c0b9/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#sigchld@0.2.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/sigchld-0.2.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"sigchld","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/sigchld-0.2.4/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","os_pipe"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsigchld-4d81f70af0b03f63.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#is-wsl@0.4.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/is-wsl-0.4.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"is_wsl","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/is-wsl-0.4.0/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libis_wsl-f920e3e9d13d4d96.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#polyval@0.6.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/polyval-0.6.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"polyval","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/polyval-0.6.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libpolyval-b4cedd320d88c64e.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#rfd@0.15.4","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/rfd-4c8415b39d69f3ef/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#opaque-debug@0.3.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/opaque-debug-0.3.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"opaque_debug","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/opaque-debug-0.3.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libopaque_debug-1e3af4630ac62466.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#symphonia-format-riff@0.5.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/symphonia-format-riff-0.5.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"symphonia_format_riff","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/symphonia-format-riff-0.5.5/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["wav"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsymphonia_format_riff-cf512481e1026708.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#miniz_oxide@0.8.9","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/miniz_oxide-0.8.9/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"miniz_oxide","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/miniz_oxide-0.8.9/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["simd","simd-adler32","with-alloc"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libminiz_oxide-205ebe48c30a0a59.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#pin-project@1.1.10","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pin-project-1.1.10/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"pin_project","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pin-project-1.1.10/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libpin_project-b77aeddbfdae70ee.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-plugin-shell@2.3.3","linked_libs":[],"linked_paths":[],"cfgs":["desktop","desktop"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/tauri-plugin-shell-c94fb7e7928e430b/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#sigchld@0.2.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/sigchld-0.2.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"sigchld","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/sigchld-0.2.4/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","os_pipe"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsigchld-4d81f70af0b03f63.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#cpal@0.15.3","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/cpal-ca07765a6658c0b9/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#is-wsl@0.4.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/is-wsl-0.4.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"is_wsl","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/is-wsl-0.4.0/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libis_wsl-f920e3e9d13d4d96.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#zbus@3.15.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zbus-3.15.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"zbus","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zbus-3.15.2/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["async-executor","async-fs","async-io","async-lock","async-task","blocking"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzbus-9368ab46c4d741e2.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-plugin-dialog@2.4.2","linked_libs":[],"linked_paths":[],"cfgs":["desktop"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/tauri-plugin-dialog-1afc6d47d4ae9196/out"}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-plugin-shell@2.3.3","linked_libs":[],"linked_paths":[],"cfgs":["desktop","desktop"],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/tauri-plugin-shell-c94fb7e7928e430b/out"}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#rfd@0.15.4","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/rfd-4c8415b39d69f3ef/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#axum-core@0.4.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/axum-core-0.4.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"axum_core","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/axum-core-0.4.5/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libaxum_core-94bd87e0644f6f31.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#hkdf@0.12.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/hkdf-0.12.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"hkdf","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/hkdf-0.12.4/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libhkdf-3d94cbbd3da4cca5.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#polyval@0.6.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/polyval-0.6.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"polyval","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/polyval-0.6.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libpolyval-b4cedd320d88c64e.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#indexmap@1.9.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/indexmap-1.9.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"indexmap","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/indexmap-1.9.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libindexmap-d3e7fdd4ebd30b98.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#alsa@0.9.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/alsa-0.9.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"alsa","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/alsa-0.9.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libalsa-938589546622b6ef.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#num@0.4.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/num-0.4.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"num","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/num-0.4.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","num-bigint","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libnum-5b09b6b6486623e2.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#async-process@2.5.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-process-2.5.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"async_process","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-process-2.5.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libasync_process-b0b786c6966bc37f.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#nix@0.30.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nix-0.30.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"nix","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nix-0.30.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["feature","memoffset","socket","uio","user"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libnix-8cb0ec3a833a8d70.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#symphonia-format-riff@0.5.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/symphonia-format-riff-0.5.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"symphonia_format_riff","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/symphonia-format-riff-0.5.5/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["wav"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsymphonia_format_riff-cf512481e1026708.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#indexmap@1.9.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/indexmap-1.9.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"indexmap","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/indexmap-1.9.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libindexmap-d3e7fdd4ebd30b98.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#axum-core@0.4.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/axum-core-0.4.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"axum_core","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/axum-core-0.4.5/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libaxum_core-94bd87e0644f6f31.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#num@0.4.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/num-0.4.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"num","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/num-0.4.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","num-bigint","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libnum-5b09b6b6486623e2.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#alsa@0.9.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/alsa-0.9.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"alsa","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/alsa-0.9.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libalsa-938589546622b6ef.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#hkdf@0.12.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/hkdf-0.12.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"hkdf","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/hkdf-0.12.4/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libhkdf-3d94cbbd3da4cca5.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rustls@0.23.35","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustls-0.23.35/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"rustls","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustls-0.23.35/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["log","logging","ring","std","tls12"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librustls-08c3dea5a950516b.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#zbus_macros@5.12.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zbus_macros-5.12.0/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"zbus_macros","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zbus_macros-5.12.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["blocking-api","default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzbus_macros-4531a5f015e7770a.so"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#xcb@1.6.0","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/xcb-f576da55ed00c3fb/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tonic-build@0.12.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tonic-build-0.12.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tonic_build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tonic-build-0.12.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","prost","prost-build","transport"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtonic_build-6f1c1047e6c4e18f.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtonic_build-6f1c1047e6c4e18f.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#hyper-util@0.1.19","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/hyper-util-0.1.19/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"hyper_util","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/hyper-util-0.1.19/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["client","client-legacy","default","http1","http2","server","server-auto","service","tokio"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libhyper_util-c59a176774ea5187.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#zbus_names@4.2.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zbus_names-4.2.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"zbus_names","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zbus_names-4.2.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzbus_names-0c57465735089b18.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#zbus_macros@5.12.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zbus_macros-5.12.0/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"zbus_macros","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zbus_macros-5.12.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["blocking-api","default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzbus_macros-4531a5f015e7770a.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rust-ini@0.21.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rust-ini-0.21.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"ini","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rust-ini-0.21.3/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libini-a88a4ea3e3a8327e.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tonic-build@0.12.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tonic-build-0.12.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tonic_build","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tonic-build-0.12.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","prost","prost-build","transport"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtonic_build-6f1c1047e6c4e18f.rlib","/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtonic_build-6f1c1047e6c4e18f.rmeta"],"executable":null,"fresh":true}
{"reason":"build-script-executed","package_id":"registry+https://github.com/rust-lang/crates.io-index#xcb@1.6.0","linked_libs":[],"linked_paths":[],"cfgs":[],"env":[],"out_dir":"/home/trav/repos/noteflow/client/src-tauri/target/debug/build/xcb-f576da55ed00c3fb/out"}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tower@0.5.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tower-0.5.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tower","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tower-0.5.2/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["__common","futures-core","futures-util","pin-project-lite","sync_wrapper","util"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtower-ba8a4a9cd95546b8.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#symphonia-bundle-flac@0.5.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/symphonia-bundle-flac-0.5.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"symphonia_bundle_flac","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/symphonia-bundle-flac-0.5.5/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsymphonia_bundle_flac-5e065939441471c3.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#symphonia-format-isomp4@0.5.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/symphonia-format-isomp4-0.5.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"symphonia_format_isomp4","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/symphonia-format-isomp4-0.5.5/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsymphonia_format_isomp4-403ff57aafca25c3.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#symphonia-codec-vorbis@0.5.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/symphonia-codec-vorbis-0.5.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"symphonia_codec_vorbis","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/symphonia-codec-vorbis-0.5.5/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsymphonia_codec_vorbis-fb0729c30ec329b0.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#symphonia-bundle-flac@0.5.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/symphonia-bundle-flac-0.5.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"symphonia_bundle_flac","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/symphonia-bundle-flac-0.5.5/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsymphonia_bundle_flac-5e065939441471c3.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#cbc@0.1.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cbc-0.1.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"cbc","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cbc-0.1.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","block-padding","default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcbc-bfb429bf4adc5a7f.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#sha2@0.10.9","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/sha2-0.10.9/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"sha2","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/sha2-0.10.9/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsha2-be1fd2408db62be5.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#symphonia-bundle-mp3@0.5.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/symphonia-bundle-mp3-0.5.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"symphonia_bundle_mp3","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/symphonia-bundle-mp3-0.5.5/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["mp3"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsymphonia_bundle_mp3-d6c55c7261455e4d.rmeta"],"executable":null,"fresh":true}
@@ -741,26 +741,26 @@
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#dirs-sys@0.4.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dirs-sys-0.4.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"dirs_sys","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dirs-sys-0.4.1/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdirs_sys-d2521b795f6677a5.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#crc32fast@1.5.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/crc32fast-1.5.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"crc32fast","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/crc32fast-1.5.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcrc32fast-d1892647cb2b9c4f.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#async-stream-impl@0.3.6","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-stream-impl-0.3.6/Cargo.toml","target":{"kind":["proc-macro"],"crate_types":["proc-macro"],"name":"async_stream_impl","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-stream-impl-0.3.6/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libasync_stream_impl-ffb3ff2cdc97f701.so"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#openssl-probe@0.1.6","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/openssl-probe-0.1.6/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"openssl_probe","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/openssl-probe-0.1.6/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libopenssl_probe-0a430695cbb7a684.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#matchit@0.7.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/matchit-0.7.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"matchit","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/matchit-0.7.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libmatchit-f5357a874e8bb85c.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#dasp_sample@0.11.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dasp_sample-0.11.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"dasp_sample","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dasp_sample-0.11.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdasp_sample-f06607cf3c5abb82.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#openssl-probe@0.1.6","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/openssl-probe-0.1.6/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"openssl_probe","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/openssl-probe-0.1.6/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libopenssl_probe-0a430695cbb7a684.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#pathdiff@0.2.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pathdiff-0.2.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"pathdiff","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pathdiff-0.2.3/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libpathdiff-ad46ac30bebed8f2.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#symphonia@0.5.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/symphonia-0.5.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"symphonia","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/symphonia-0.5.5/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["aac","adpcm","flac","isomp4","mp3","pcm","symphonia-bundle-flac","symphonia-bundle-mp3","symphonia-codec-aac","symphonia-codec-adpcm","symphonia-codec-pcm","symphonia-codec-vorbis","symphonia-format-isomp4","symphonia-format-riff","vorbis","wav"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsymphonia-c0ac1af4ecfd202c.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#dasp_sample@0.11.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dasp_sample-0.11.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"dasp_sample","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dasp_sample-0.11.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdasp_sample-f06607cf3c5abb82.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#async-stream@0.3.6","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-stream-0.3.6/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"async_stream","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/async-stream-0.3.6/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libasync_stream-f8175869359367cc.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#flate2@1.1.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/flate2-1.1.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"flate2","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/flate2-1.1.5/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["any_impl","default","miniz_oxide","rust_backend"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libflate2-ec0af782d6e373ae.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#secret-service@3.1.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/secret-service-3.1.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"secret_service","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/secret-service-3.1.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["crypto-rust","rt-async-io-crypto-rust"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsecret_service-00964b20539998ab.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#flate2@1.1.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/flate2-1.1.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"flate2","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/flate2-1.1.5/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["any_impl","default","miniz_oxide","rust_backend"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libflate2-ec0af782d6e373ae.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#zbus@5.12.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zbus-5.12.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"zbus","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/zbus-5.12.0/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["async-executor","async-fs","async-io","async-lock","async-process","async-task","blocking","blocking-api","default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libzbus-711ddad50e246069.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#symphonia@0.5.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/symphonia-0.5.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"symphonia","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/symphonia-0.5.5/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["aac","adpcm","flac","isomp4","mp3","pcm","symphonia-bundle-flac","symphonia-bundle-mp3","symphonia-codec-aac","symphonia-codec-adpcm","symphonia-codec-pcm","symphonia-codec-vorbis","symphonia-format-isomp4","symphonia-format-riff","vorbis","wav"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsymphonia-c0ac1af4ecfd202c.rmeta"],"executable":null,"fresh":true}
Compiling noteflow-tauri v0.1.0 (/home/trav/repos/noteflow/client/src-tauri)
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tower@0.4.13","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tower-0.4.13/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tower","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tower-0.4.13/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["__common","balance","buffer","discover","futures-core","futures-util","indexmap","limit","load","make","pin-project","pin-project-lite","rand","ready-cache","slab","tokio","tokio-util","tracing","util"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtower-a7e83cd22586d1f2.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-plugin-deep-link@2.4.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-plugin-deep-link-2.4.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tauri_plugin_deep_link","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-plugin-deep-link-2.4.5/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtauri_plugin_deep_link-1b66f43ff58c3954.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#xcb@1.6.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/xcb-1.6.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"xcb","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/xcb-1.6.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","libxcb_v1_14","randr","render"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libxcb-c95070c104ba8034.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tokio-rustls@0.26.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-rustls-0.26.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tokio_rustls","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-rustls-0.26.4/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["logging","ring","tls12"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtokio_rustls-c0569ac75e1d9bac.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#axum@0.7.9","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/axum-0.7.9/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"axum","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/axum-0.7.9/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libaxum-252d0fb73e522995.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-plugin-deep-link@2.4.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-plugin-deep-link-2.4.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tauri_plugin_deep_link","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-plugin-deep-link-2.4.5/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtauri_plugin_deep_link-1b66f43ff58c3954.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#ghash@0.5.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ghash-0.5.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"ghash","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ghash-0.5.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libghash-90e4c73cf26431e9.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tower@0.4.13","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tower-0.4.13/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tower","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tower-0.4.13/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["__common","balance","buffer","discover","futures-core","futures-util","indexmap","limit","load","make","pin-project","pin-project-lite","rand","ready-cache","slab","tokio","tokio-util","tracing","util"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtower-a7e83cd22586d1f2.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rustls-native-certs@0.8.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustls-native-certs-0.8.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"rustls_native_certs","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustls-native-certs-0.8.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librustls_native_certs-ed220dcb54705a19.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#axum@0.7.9","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/axum-0.7.9/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"axum","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/axum-0.7.9/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libaxum-252d0fb73e522995.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#open@5.3.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/open-5.3.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"open","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/open-5.3.3/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["shellexecute-on-windows"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libopen-60351f54248c1f61.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#cpal@0.15.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cpal-0.15.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"cpal","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/cpal-0.15.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libcpal-85b5c723b1ba7978.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#xcb@1.6.0","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/xcb-1.6.0/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"xcb","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/xcb-1.6.0/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","libxcb_v1_14","randr","render"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libxcb-c95070c104ba8034.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#hyper-timeout@0.5.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/hyper-timeout-0.5.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"hyper_timeout","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/hyper-timeout-0.5.2/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libhyper_timeout-3df2fe055483f045.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#ghash@0.5.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ghash-0.5.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"ghash","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/ghash-0.5.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libghash-90e4c73cf26431e9.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rfd@0.15.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rfd-0.15.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"rfd","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rfd-0.15.4/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["common-controls-v6","glib-sys","gobject-sys","gtk-sys","gtk3","tokio"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librfd-3891562e8e628ffd.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#shared_child@1.1.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/shared_child-1.1.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"shared_child","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/shared_child-1.1.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","timeout"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libshared_child-387aedd7189b4d75.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-plugin-fs@2.4.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-plugin-fs-2.4.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tauri_plugin_fs","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-plugin-fs-2.4.4/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtauri_plugin_fs-e7ba4cda7f348204.rmeta"],"executable":null,"fresh":true}
@@ -774,22 +774,22 @@
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#linux-keyutils@0.2.4","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/linux-keyutils-0.2.4/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"linux_keyutils","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/linux-keyutils-0.2.4/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/liblinux_keyutils-70697f03afb68c45.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#socket2@0.5.10","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/socket2-0.5.10/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"socket2","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/socket2-0.5.10/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["all"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libsocket2-416825d397ebf644.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#thread_local@1.1.9","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/thread_local-1.1.9/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"thread_local","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/thread_local-1.1.9/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libthread_local-f4679fe5723d3d83.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#nu-ansi-term@0.50.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nu-ansi-term-0.50.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"nu_ansi_term","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nu-ansi-term-0.50.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libnu_ansi_term-6a0a1a678b9d4451.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#base64@0.22.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/base64-0.22.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"base64","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/base64-0.22.1/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libbase64-acd783e14d151986.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#iana-time-zone@0.1.64","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/iana-time-zone-0.1.64/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"iana_time_zone","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/iana-time-zone-0.1.64/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["fallback"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libiana_time_zone-d6450465d0a9962b.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#nu-ansi-term@0.50.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nu-ansi-term-0.50.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"nu_ansi_term","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/nu-ansi-term-0.50.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libnu_ansi_term-6a0a1a678b9d4451.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-plugin-dialog@2.4.2","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-plugin-dialog-2.4.2/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tauri_plugin_dialog","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-plugin-dialog-2.4.2/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtauri_plugin_dialog-99d6e80c989a1c1f.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rodio@0.20.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rodio-0.20.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"rodio","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rodio-0.20.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["symphonia","symphonia-aac","symphonia-all","symphonia-flac","symphonia-isomp4","symphonia-mp3","symphonia-vorbis","symphonia-wav"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librodio-65e233d57a9a6031.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-plugin-shell@2.3.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-plugin-shell-2.3.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tauri_plugin_shell","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-plugin-shell-2.3.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtauri_plugin_shell-2fa42f14a682db65.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#rodio@0.20.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rodio-0.20.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"rodio","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rodio-0.20.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["symphonia","symphonia-aac","symphonia-all","symphonia-flac","symphonia-isomp4","symphonia-mp3","symphonia-vorbis","symphonia-wav"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/librodio-65e233d57a9a6031.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#active-win-pos-rs@0.9.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/active-win-pos-rs-0.9.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"active_win_pos_rs","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/active-win-pos-rs-0.9.1/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libactive_win_pos_rs-cd493137ef58f169.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#aes-gcm@0.10.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/aes-gcm-0.10.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"aes_gcm","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/aes-gcm-0.10.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["aes","alloc","default","getrandom","rand_core"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libaes_gcm-53c15a3ba682c265.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#chrono@0.4.42","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/chrono-0.4.42/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"chrono","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/chrono-0.4.42/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","clock","default","iana-time-zone","js-sys","now","oldtime","serde","std","wasm-bindgen","wasmbind","winapi","windows-link"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libchrono-a1ad50b6baa54800.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#keyring@2.3.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/keyring-2.3.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"keyring","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/keyring-2.3.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["byteorder","default","linux-keyutils","linux-secret-service","linux-secret-service-rt-async-io-crypto-rust","platform-all","platform-freebsd","platform-ios","platform-linux","platform-macos","platform-openbsd","platform-windows","secret-service","security-framework","windows-sys"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libkeyring-0912ed267d5c1163.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tracing-subscriber@0.3.22","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tracing-subscriber-0.3.22/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tracing_subscriber","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tracing-subscriber-0.3.22/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","ansi","default","env-filter","fmt","matchers","nu-ansi-term","once_cell","registry","sharded-slab","smallvec","std","thread_local","tracing","tracing-log"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtracing_subscriber-ff4b377ef01b5f43.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tonic@0.12.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tonic-0.12.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tonic","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tonic-0.12.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["channel","codegen","default","gzip","prost","router","server","tls","tls-native-roots","tls-roots","transport"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtonic-720989dc61f2a4ca.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#aes-gcm@0.10.3","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/aes-gcm-0.10.3/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"aes_gcm","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/aes-gcm-0.10.3/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["aes","alloc","default","getrandom","rand_core"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libaes_gcm-53c15a3ba682c265.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#chrono@0.4.42","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/chrono-0.4.42/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"chrono","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/chrono-0.4.42/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","clock","default","iana-time-zone","js-sys","now","oldtime","serde","std","wasm-bindgen","wasmbind","winapi","windows-link"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libchrono-a1ad50b6baa54800.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#tauri-plugin-single-instance@2.3.6","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-plugin-single-instance-2.3.6/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"tauri_plugin_single_instance","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tauri-plugin-single-instance-2.3.6/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["deep-link"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libtauri_plugin_single_instance-b0ec19b118cb37b9.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#dirs@5.0.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dirs-5.0.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"dirs","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dirs-5.0.1/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdirs-d4d3264e8c633651.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#prost-types@0.13.5","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/prost-types-0.13.5/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"prost_types","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/prost-types-0.13.5/src/lib.rs","edition":"2021","doc":true,"doctest":false,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["default","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libprost_types-3ccd7fa7b167e4be.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#directories@5.0.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/directories-5.0.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"directories","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/directories-5.0.1/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdirectories-c3c98b6e9d5d415a.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#dirs@5.0.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dirs-5.0.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"dirs","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/dirs-5.0.1/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libdirs-d4d3264e8c633651.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#futures@0.3.31","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/futures-0.3.31/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"futures","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/futures-0.3.31/src/lib.rs","edition":"2018","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["alloc","async-await","default","executor","futures-executor","std"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libfutures-91a3835cd099048f.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"registry+https://github.com/rust-lang/crates.io-index#hound@3.5.1","manifest_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/hound-3.5.1/Cargo.toml","target":{"kind":["lib"],"crate_types":["lib"],"name":"hound","src_path":"/home/trav/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/hound-3.5.1/src/lib.rs","edition":"2015","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":[],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libhound-c5c2ce41ad3403fc.rmeta"],"executable":null,"fresh":true}
{"reason":"compiler-artifact","package_id":"path+file:///home/trav/repos/noteflow/client/src-tauri#noteflow-tauri@0.1.0","manifest_path":"/home/trav/repos/noteflow/client/src-tauri/Cargo.toml","target":{"kind":["custom-build"],"crate_types":["bin"],"name":"build-script-build","src_path":"/home/trav/repos/noteflow/client/src-tauri/build.rs","edition":"2021","doc":false,"doctest":false,"test":false},"profile":{"opt_level":"0","debuginfo":0,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["custom-protocol","default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/build/noteflow-tauri-43e8014f3a3c111b/build-script-build"],"executable":null,"fresh":false}
@@ -797,4 +797,4 @@
{"reason":"compiler-artifact","package_id":"path+file:///home/trav/repos/noteflow/client/src-tauri#noteflow-tauri@0.1.0","manifest_path":"/home/trav/repos/noteflow/client/src-tauri/Cargo.toml","target":{"kind":["lib","cdylib","staticlib"],"crate_types":["lib","cdylib","staticlib"],"name":"noteflow_lib","src_path":"/home/trav/repos/noteflow/client/src-tauri/src/lib.rs","edition":"2021","doc":true,"doctest":true,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["custom-protocol","default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libnoteflow_lib-4a95591d1c4cd93f.rmeta"],"executable":null,"fresh":false}
{"reason":"compiler-artifact","package_id":"path+file:///home/trav/repos/noteflow/client/src-tauri#noteflow-tauri@0.1.0","manifest_path":"/home/trav/repos/noteflow/client/src-tauri/Cargo.toml","target":{"kind":["bin"],"crate_types":["bin"],"name":"noteflow-tauri","src_path":"/home/trav/repos/noteflow/client/src-tauri/src/main.rs","edition":"2021","doc":true,"doctest":false,"test":true},"profile":{"opt_level":"0","debuginfo":2,"debug_assertions":true,"overflow_checks":true,"test":false},"features":["custom-protocol","default"],"filenames":["/home/trav/repos/noteflow/client/src-tauri/target/debug/deps/libnoteflow_tauri-bc194216ee739488.rmeta"],"executable":null,"fresh":false}
{"reason":"build-finished","success":true}
Finished `dev` profile [unoptimized + debuginfo] target(s) in 10.10s
Finished `dev` profile [unoptimized + debuginfo] target(s) in 9.98s

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,34 @@
# Basedpyright Validation Rules
## Zero Tolerance Policy
**ALL basedpyright errors must be fixed. No exceptions. No rationalizations.**
### Forbidden Behaviors
1. **Never dismiss errors as "just warnings"** - If basedpyright says ERROR, it's an error
2. **Never rationalize errors as "intentional"** - Fix them properly instead
3. **Never proceed with validation when errors exist** - 0 errors required
### Required Validation Steps
After any code changes, run:
```bash
source .venv/bin/activate && basedpyright src/noteflow/
```
**Expected output:** `0 errors, 0 warnings, 0 notes`
### Hygiene Round Checklist
1. Run basedpyright on modified files
2. Run basedpyright on FULL codebase
3. Confirm exactly: `0 errors, 0 warnings, 0 notes`
4. Run quality suite (pytest tests/quality/)
5. Run backend tests
6. Only then report success
### Lesson Learned
On 2026-01-06, I dismissed 93 basedpyright errors as acceptable. This violated CLAUDE.md. Errors are errors. Fix them.

2
client

Submodule client updated: 8555904d45...a567ce9e00

View File

@@ -233,6 +233,7 @@ exclude = [
"client",
"client/**",
".venv",
".venv/",
".venv/**",
".benchmarks",
".benchmarks/**",

View File

@@ -8,12 +8,12 @@ from noteflow.application.services.auth_service import (
UserInfo,
)
from noteflow.application.services.export_service import ExportFormat, ExportService
from noteflow.application.services.identity_service import IdentityService
from noteflow.application.services.identity import IdentityService
from noteflow.application.services.meeting_service import MeetingService
from noteflow.application.services.project_service import ProjectService
from noteflow.application.services.recovery_service import RecoveryService
from noteflow.application.services.retention_service import RetentionReport, RetentionService
from noteflow.application.services.summarization_service import (
from noteflow.application.services.summarization import (
SummarizationMode,
SummarizationService,
SummarizationServiceResult,

View File

@@ -46,14 +46,32 @@ class SegmentData:
"""No-speech probability."""
def to_segment(self, meeting_id: MeetingId) -> Segment:
"""Convert to a Segment entity.
"""Convert to a Segment entity with validation.
Validates segment data before creating the domain entity:
- Segment ID must be non-negative
- End time must be >= start time
- Times must be non-negative
Args:
meeting_id: Meeting this segment belongs to.
Returns:
New Segment entity.
Raises:
ValueError: If segment data fails validation.
"""
if self.segment_id < 0:
msg = f"Segment ID must be non-negative, got {self.segment_id}"
raise ValueError(msg)
if self.start_time < 0:
msg = f"Start time must be non-negative, got {self.start_time}"
raise ValueError(msg)
if self.end_time < self.start_time:
msg = f"End time ({self.end_time}) must be >= start time ({self.start_time})"
raise ValueError(msg)
return Segment(
segment_id=self.segment_id,
text=self.text,

View File

@@ -0,0 +1,87 @@
"""Auth integration storage and retrieval."""
from __future__ import annotations
from dataclasses import dataclass
from typing import TYPE_CHECKING
from uuid import UUID
from noteflow.domain.entities.integration import IntegrationType
from .auth_helpers import (
AuthIntegrationContext,
get_or_create_auth_integration,
get_or_create_default_workspace_id,
get_or_create_user_id,
store_integration_tokens,
)
@dataclass(frozen=True)
class AuthUserData:
"""Bundle of user identity data from OAuth provider."""
provider: str
email: str
display_name: str
if TYPE_CHECKING:
from noteflow.domain.entities.integration import Integration
from noteflow.domain.ports.unit_of_work import UnitOfWork
from noteflow.domain.value_objects import OAuthTokens
class IntegrationManager:
"""Handle auth integration storage and retrieval."""
async def store_auth_user(
self,
uow: UnitOfWork,
user_data: AuthUserData,
tokens: OAuthTokens,
) -> tuple[UUID, UUID]:
"""Create or update user and store auth tokens.
Args:
uow: Unit of work for database operations.
user_data: User identity data from OAuth provider.
tokens: OAuth tokens to store.
Returns:
Tuple of (user_id, workspace_id).
"""
user_id = await get_or_create_user_id(uow, user_data.email, user_data.display_name)
workspace_id = await get_or_create_default_workspace_id(uow, user_id)
integration = await get_or_create_auth_integration(
uow,
AuthIntegrationContext(
provider=user_data.provider,
workspace_id=workspace_id,
user_id=user_id,
provider_email=user_data.email,
),
)
await store_integration_tokens(uow, integration, tokens)
await uow.commit()
return user_id, workspace_id
async def load_auth_integration(
self,
uow: UnitOfWork,
provider: str,
) -> Integration | None:
"""Load auth integration for a provider."""
return await uow.integrations.get_by_provider(
provider=provider,
integration_type=IntegrationType.AUTH.value,
)
async def delete_integration(
self,
uow: UnitOfWork,
integration_id: UUID,
) -> None:
"""Delete an auth integration."""
await uow.integrations.delete(integration_id)
await uow.commit()

View File

@@ -7,32 +7,31 @@ IntegrationType.AUTH and manages User entities.
from __future__ import annotations
from dataclasses import dataclass
from typing import TYPE_CHECKING, TypedDict, Unpack
from uuid import UUID
from noteflow.config.constants import OAUTH_FIELD_ACCESS_TOKEN
from noteflow.domain.entities.integration import IntegrationType
from noteflow.domain.value_objects import OAuthProvider, OAuthTokens
from noteflow.domain.value_objects import OAuthProvider
from noteflow.infrastructure.calendar import OAuthManager
from noteflow.infrastructure.calendar.google_adapter import GoogleCalendarError
from noteflow.infrastructure.calendar.oauth_manager import OAuthError
from noteflow.infrastructure.calendar.outlook_adapter import OutlookCalendarError
from noteflow.infrastructure.logging import get_logger
from .auth_constants import DEFAULT_USER_ID, DEFAULT_WORKSPACE_ID
from .auth_helpers import (
AuthIntegrationContext,
find_connected_auth_integration,
get_or_create_auth_integration,
get_or_create_default_workspace_id,
get_or_create_user_id,
refresh_tokens_for_integration,
store_integration_tokens,
resolve_display_name,
)
from .auth_helpers import find_connected_auth_integration, resolve_display_name
from .auth_integration_manager import IntegrationManager
from .auth_token_exchanger import AuthServiceError, TokenExchanger
from .auth_types import AuthResult, LogoutResult, UserInfo
@dataclass(frozen=True)
class AuthUserData:
"""Bundle of user identity data from OAuth provider."""
provider: str
email: str
display_name: str
class _AuthServiceDepsKwargs(TypedDict, total=False):
"""Optional dependency overrides for AuthService."""
@@ -43,16 +42,11 @@ if TYPE_CHECKING:
from collections.abc import Callable
from noteflow.config.settings import CalendarIntegrationSettings
from noteflow.domain.entities.integration import Integration
from noteflow.domain.ports.unit_of_work import UnitOfWork
logger = get_logger(__name__)
class AuthServiceError(Exception):
"""Auth service operation failed."""
class AuthService:
"""Authentication service for OAuth-based user login.
@@ -80,8 +74,9 @@ class AuthService:
"""
self._uow_factory = uow_factory
self._settings = settings
oauth_manager = kwargs.get("oauth_manager")
self._oauth_manager = oauth_manager or OAuthManager(settings)
oauth_manager = kwargs.get("oauth_manager") or OAuthManager(settings)
self._token_exchanger = TokenExchanger(oauth_manager)
self._integration_manager = IntegrationManager()
async def initiate_login(
self,
@@ -104,7 +99,7 @@ class AuthService:
effective_redirect = redirect_uri or self._settings.redirect_uri
try:
auth_url, state = self._oauth_manager.initiate_auth(
auth_url, state = self._token_exchanger.initiate_auth(
provider=oauth_provider,
redirect_uri=effective_redirect,
)
@@ -132,9 +127,6 @@ class AuthService:
) -> AuthResult:
"""Complete OAuth login and create/update user.
Exchanges authorization code for tokens, fetches user info,
and creates or updates the User entity.
Args:
provider: Provider name ('google' or 'outlook').
code: Authorization code from OAuth callback.
@@ -147,20 +139,31 @@ class AuthService:
AuthServiceError: If OAuth exchange fails.
"""
oauth_provider = self._parse_auth_provider(provider)
# Exchange code for tokens
tokens = await self._exchange_tokens(oauth_provider, code, state)
# Fetch user info from provider
email, display_name = await self._fetch_user_info(
tokens = await self._token_exchanger.exchange_tokens(oauth_provider, code, state)
email, display_name = await self._token_exchanger.fetch_user_info(
oauth_provider, tokens.access_token
)
# Create or update user and store tokens
user_id, workspace_id = await self._store_auth_user(
provider, email, display_name, tokens
user_data = AuthUserData(provider=provider, email=email, display_name=display_name)
async with self._uow_factory() as uow:
user_id, workspace_id = await self._integration_manager.store_auth_user(
uow, user_data, tokens
)
self._log_login_completed(provider, email, user_id, workspace_id)
return AuthResult(
user_id=user_id,
workspace_id=workspace_id,
display_name=display_name,
email=email,
)
def _log_login_completed(
self,
provider: str,
email: str,
user_id: UUID,
workspace_id: UUID,
) -> None:
"""Log successful login completion."""
logger.info(
"auth_login_completed",
event_type="security",
@@ -170,74 +173,6 @@ class AuthService:
workspace_id=str(workspace_id),
)
return AuthResult(
user_id=user_id,
workspace_id=workspace_id,
display_name=display_name,
email=email,
)
async def _exchange_tokens(
self,
oauth_provider: OAuthProvider,
code: str,
state: str,
) -> OAuthTokens:
"""Exchange authorization code for tokens."""
try:
return await self._oauth_manager.complete_auth(
provider=oauth_provider,
code=code,
state=state,
)
except OAuthError as e:
raise AuthServiceError(f"OAuth failed: {e}") from e
async def _fetch_user_info(
self,
oauth_provider: OAuthProvider,
access_token: str,
) -> tuple[str, str]:
"""Fetch user email and display name from provider."""
# Use the calendar adapter to get user info (reuse existing infrastructure)
from noteflow.infrastructure.calendar.google_adapter import GoogleCalendarAdapter
from noteflow.infrastructure.calendar.outlook_adapter import OutlookCalendarAdapter
try:
if oauth_provider == OAuthProvider.GOOGLE:
adapter = GoogleCalendarAdapter()
else:
adapter = OutlookCalendarAdapter()
email, display_name = await adapter.get_user_info(access_token)
return email, display_name
except (GoogleCalendarError, OutlookCalendarError, OAuthError) as e:
raise AuthServiceError(f"Failed to get user info: {e}") from e
async def _store_auth_user(
self,
provider: str,
email: str,
display_name: str,
tokens: OAuthTokens,
) -> tuple[UUID, UUID]:
"""Create or update user and store auth tokens."""
async with self._uow_factory() as uow:
user_id = await get_or_create_user_id(uow, email, display_name)
workspace_id = await get_or_create_default_workspace_id(uow, user_id)
integration = await get_or_create_auth_integration(
uow,
AuthIntegrationContext(
provider=provider,
workspace_id=workspace_id,
user_id=user_id,
provider_email=email,
),
)
await store_integration_tokens(uow, integration, tokens)
await uow.commit()
return user_id, workspace_id
async def get_current_user(self) -> UserInfo:
"""Get current authenticated user info.
@@ -290,25 +225,33 @@ class AuthService:
)
results = [await self._logout_provider(p) for p in providers]
return LogoutResult.aggregate(results)
return LogoutResult.aggregate(
logged_out_flags=[r.logged_out for r in results],
tokens_revoked_flags=[r.tokens_revoked for r in results],
revocation_errors=[r.revocation_error for r in results],
)
async def _logout_provider(self, provider: str) -> LogoutResult:
"""Logout from a specific provider."""
oauth_provider = self._parse_auth_provider(provider)
async with self._uow_factory() as uow:
integration = await self._load_auth_integration(uow, provider)
integration = await self._integration_manager.load_auth_integration(
uow, provider
)
if integration is None:
return LogoutResult(
logged_out=False,
tokens_revoked=True,
)
access_token = await self._load_access_token(uow, integration.id)
await self._delete_integration(uow, integration.id)
access_token = await self._token_exchanger.load_access_token(
uow, integration.id
)
await self._integration_manager.delete_integration(uow, integration.id)
# Revoke tokens (best effort)
tokens_revoked, revocation_error = await self._revoke_access_token(
tokens_revoked, revocation_error = await self._token_exchanger.revoke_access_token(
oauth_provider,
provider,
access_token,
@@ -327,57 +270,6 @@ class AuthService:
revocation_error=revocation_error,
)
async def _load_auth_integration(
self,
uow: UnitOfWork,
provider: str,
) -> Integration | None:
return await uow.integrations.get_by_provider(
provider=provider,
integration_type=IntegrationType.AUTH.value,
)
async def _load_access_token(
self,
uow: UnitOfWork,
integration_id: UUID,
) -> str | None:
secrets = await uow.integrations.get_secrets(integration_id)
return secrets.get(OAUTH_FIELD_ACCESS_TOKEN) if secrets else None
async def _delete_integration(self, uow: UnitOfWork, integration_id: UUID) -> None:
await uow.integrations.delete(integration_id)
await uow.commit()
async def _revoke_access_token(
self,
oauth_provider: OAuthProvider,
provider: str,
access_token: str | None,
) -> tuple[bool, str | None]:
tokens_revoked = True
revocation_error: str | None = None
if access_token:
try:
await self._oauth_manager.revoke_tokens(oauth_provider, access_token)
logger.info(
"auth_tokens_revoked",
event_type="security",
provider=provider,
)
except OAuthError as e:
tokens_revoked = False
revocation_error = str(e)
logger.warning(
"auth_token_revocation_failed",
event_type="security",
provider=provider,
error=revocation_error,
)
return tokens_revoked, revocation_error
async def refresh_auth_tokens(self, provider: str) -> AuthResult | None:
"""Refresh expired auth tokens.
@@ -390,26 +282,16 @@ class AuthService:
oauth_provider = self._parse_auth_provider(provider)
async with self._uow_factory() as uow:
integration = await uow.integrations.get_by_provider(
provider=provider,
integration_type=IntegrationType.AUTH.value,
integration = await self._integration_manager.load_auth_integration(
uow, provider
)
if integration is None or not integration.is_connected:
return None
try:
return await refresh_tokens_for_integration(
uow,
oauth_provider=oauth_provider,
integration=integration,
oauth_manager=self._oauth_manager,
)
except OAuthError as e:
integration.mark_error(f"Token refresh failed: {e}")
await uow.integrations.update(integration)
await uow.commit()
return None
return await self._token_exchanger.refresh_tokens(
uow, oauth_provider, integration
)
@staticmethod
def _parse_auth_provider(provider: str) -> OAuthProvider:

View File

@@ -0,0 +1,144 @@
"""OAuth token exchange, fetching, loading, and revocation."""
from __future__ import annotations
from typing import TYPE_CHECKING
from uuid import UUID
from noteflow.config.constants import OAUTH_FIELD_ACCESS_TOKEN
from noteflow.domain.value_objects import OAuthProvider, OAuthTokens
from noteflow.infrastructure.calendar import OAuthManager
from noteflow.infrastructure.calendar.google_adapter import GoogleCalendarError
from noteflow.infrastructure.calendar.oauth_manager import OAuthError
from noteflow.infrastructure.calendar.outlook_adapter import OutlookCalendarError
from noteflow.infrastructure.logging import get_logger
from .auth_helpers import refresh_tokens_for_integration
from .auth_types import AuthResult
if TYPE_CHECKING:
from noteflow.domain.entities.integration import Integration
from noteflow.domain.ports.unit_of_work import UnitOfWork
logger = get_logger(__name__)
class AuthServiceError(Exception):
"""Auth service operation failed."""
class TokenExchanger:
"""Handle OAuth token exchange, fetching, loading, and revocation."""
def __init__(self, oauth_manager: OAuthManager) -> None:
"""Initialize token exchanger.
Args:
oauth_manager: OAuth manager for token operations.
"""
self._oauth_manager = oauth_manager
def initiate_auth(
self,
provider: OAuthProvider,
redirect_uri: str,
) -> tuple[str, str]:
"""Initiate OAuth authorization flow."""
return self._oauth_manager.initiate_auth(
provider=provider,
redirect_uri=redirect_uri,
)
async def exchange_tokens(
self,
oauth_provider: OAuthProvider,
code: str,
state: str,
) -> OAuthTokens:
"""Exchange authorization code for tokens."""
try:
return await self._oauth_manager.complete_auth(
provider=oauth_provider,
code=code,
state=state,
)
except OAuthError as e:
raise AuthServiceError(f"OAuth failed: {e}") from e
async def fetch_user_info(
self,
oauth_provider: OAuthProvider,
access_token: str,
) -> tuple[str, str]:
"""Fetch user email and display name from provider."""
from noteflow.infrastructure.calendar.google_adapter import GoogleCalendarAdapter
from noteflow.infrastructure.calendar.outlook_adapter import OutlookCalendarAdapter
try:
if oauth_provider == OAuthProvider.GOOGLE:
adapter = GoogleCalendarAdapter()
else:
adapter = OutlookCalendarAdapter()
email, display_name = await adapter.get_user_info(access_token)
return email, display_name
except (GoogleCalendarError, OutlookCalendarError, OAuthError) as e:
raise AuthServiceError(f"Failed to get user info: {e}") from e
async def load_access_token(
self,
uow: UnitOfWork,
integration_id: UUID,
) -> str | None:
"""Load access token from integration secrets."""
secrets = await uow.integrations.get_secrets(integration_id)
return secrets.get(OAUTH_FIELD_ACCESS_TOKEN) if secrets else None
async def revoke_access_token(
self,
oauth_provider: OAuthProvider,
provider: str,
access_token: str | None,
) -> tuple[bool, str | None]:
"""Revoke access token with the OAuth provider."""
tokens_revoked = True
revocation_error: str | None = None
if access_token:
try:
await self._oauth_manager.revoke_tokens(oauth_provider, access_token)
logger.info(
"auth_tokens_revoked",
event_type="security",
provider=provider,
)
except OAuthError as e:
tokens_revoked = False
revocation_error = str(e)
logger.warning(
"auth_token_revocation_failed",
event_type="security",
provider=provider,
error=revocation_error,
)
return tokens_revoked, revocation_error
async def refresh_tokens(
self,
uow: UnitOfWork,
oauth_provider: OAuthProvider,
integration: Integration,
) -> AuthResult | None:
"""Refresh expired auth tokens."""
try:
return await refresh_tokens_for_integration(
uow,
oauth_provider=oauth_provider,
integration=integration,
oauth_manager=self._oauth_manager,
)
except OAuthError as e:
integration.mark_error(f"Token refresh failed: {e}")
await uow.integrations.update(integration)
await uow.commit()
return None

View File

@@ -33,6 +33,33 @@ class UserInfo:
provider: str | None
def _aggregate_logout_results(
logged_out_flags: list[bool],
tokens_revoked_flags: list[bool],
revocation_errors: list[str | None],
) -> tuple[bool, bool, str | None]:
"""Compute aggregated logout result values.
Args:
logged_out_flags: List of logged_out values from individual providers.
tokens_revoked_flags: List of tokens_revoked values from individual providers.
revocation_errors: List of revocation_error values from individual providers.
Returns:
Tuple of (logged_out, tokens_revoked, revocation_error).
"""
if not logged_out_flags:
return (False, True, None)
logged_out = any(logged_out_flags)
all_revoked = all(tokens_revoked_flags)
errors = [
str(err)
for revoked, err in zip(tokens_revoked_flags, revocation_errors, strict=True)
if not revoked and err
]
return (logged_out, all_revoked, "; ".join(errors) if errors else None)
@dataclass(frozen=True, slots=True)
class LogoutResult:
"""Result of logout operation.
@@ -47,30 +74,31 @@ class LogoutResult:
"""Whether remote token revocation succeeded."""
revocation_error: str | None = None
"""Error message if revocation failed (for logging/debugging)."""
@classmethod
def aggregate(cls, results: list[LogoutResult]) -> LogoutResult:
def aggregate(
cls,
logged_out_flags: list[bool],
tokens_revoked_flags: list[bool],
revocation_errors: list[str | None],
) -> LogoutResult:
"""Aggregate multiple provider logout results into single result.
Args:
results: List of LogoutResult from individual providers.
logged_out_flags: List of logged_out values from individual providers.
tokens_revoked_flags: List of tokens_revoked values from individual providers.
revocation_errors: List of revocation_error values from individual providers.
Returns:
Combined LogoutResult where logged_out is True if any succeeded,
tokens_revoked is True only if all succeeded.
"""
if not results:
return cls(logged_out=False, tokens_revoked=True)
logged_out = any(r.logged_out for r in results)
all_revoked = all(r.tokens_revoked for r in results)
errors = [
str(r.revocation_error)
for r in results
if not r.tokens_revoked and r.revocation_error
]
logged_out, tokens_revoked, error = _aggregate_logout_results(
logged_out_flags, tokens_revoked_flags, revocation_errors
)
return cls(
logged_out=logged_out,
tokens_revoked=all_revoked,
revocation_error="; ".join(errors) if errors else None,
tokens_revoked=tokens_revoked,
revocation_error=error,
)
"""Error message if revocation failed (for logging/debugging)."""

View File

@@ -0,0 +1,8 @@
"""Calendar service package."""
from __future__ import annotations
from ._errors import CalendarServiceError
from .calendar_service import CalendarService
__all__ = ["CalendarService", "CalendarServiceError"]

View File

@@ -0,0 +1,87 @@
"""Connection management mixin for calendar service."""
from __future__ import annotations
from typing import TYPE_CHECKING
from noteflow.config.constants import OAUTH_FIELD_ACCESS_TOKEN
from noteflow.domain.entities.integration import IntegrationStatus, IntegrationType
from noteflow.domain.ports.calendar import OAuthConnectionInfo
from noteflow.infrastructure.calendar import OAuthManager
from noteflow.infrastructure.calendar.oauth_manager import OAuthError
from noteflow.infrastructure.logging import get_logger
if TYPE_CHECKING:
from collections.abc import Callable
from datetime import datetime
from noteflow.domain.ports.unit_of_work import UnitOfWork
from noteflow.domain.value_objects import OAuthProvider
logger = get_logger(__name__)
class CalendarServiceConnectionMixin:
"""Mixin for connection status and disconnect operations."""
_oauth_manager: OAuthManager
_uow_factory: Callable[[], UnitOfWork]
_parse_calendar_provider: Callable[..., "OAuthProvider"]
_resolve_connection_status: Callable[..., tuple[str, "datetime | None"]]
async def get_connection_status(self, provider: str) -> OAuthConnectionInfo:
"""Get OAuth connection status for a provider."""
async with self._uow_factory() as uow:
integration = await uow.integrations.get_by_provider(
provider=provider,
integration_type=IntegrationType.CALENDAR.value,
)
if integration is None:
return OAuthConnectionInfo(
provider=provider,
status=IntegrationStatus.DISCONNECTED.value,
)
secrets = await uow.integrations.get_secrets(integration.id)
status, expires_at = self._resolve_connection_status(integration, secrets)
return OAuthConnectionInfo(
provider=provider,
status=status,
email=integration.provider_email,
expires_at=expires_at,
error_message=integration.error_message,
)
async def disconnect(self, provider: str) -> bool:
"""Disconnect OAuth integration and revoke tokens."""
oauth_provider = self._parse_calendar_provider(provider)
async with self._uow_factory() as uow:
integration = await uow.integrations.get_by_provider(
provider=provider,
integration_type=IntegrationType.CALENDAR.value,
)
if integration is None:
return False
secrets = await uow.integrations.get_secrets(integration.id)
access_token = secrets.get(OAUTH_FIELD_ACCESS_TOKEN) if secrets else None
await uow.integrations.delete(integration.id)
await uow.commit()
if access_token:
try:
await self._oauth_manager.revoke_tokens(oauth_provider, access_token)
except OAuthError as e:
logger.warning(
"Failed to revoke tokens for provider=%s: %s",
provider,
e,
)
logger.info("Disconnected provider=%s", provider)
return True

View File

@@ -0,0 +1,7 @@
"""Calendar service errors."""
from __future__ import annotations
class CalendarServiceError(Exception):
"""Calendar service operation failed."""

View File

@@ -0,0 +1,223 @@
"""Event fetching mixin for calendar service."""
from __future__ import annotations
from typing import TYPE_CHECKING
from noteflow.config.constants import ERR_TOKEN_REFRESH_PREFIX
from noteflow.domain.entities.integration import Integration, IntegrationType
from noteflow.domain.ports.calendar import CalendarEventInfo
from noteflow.domain.value_objects import OAuthProvider, OAuthTokens
from noteflow.infrastructure.calendar import (
GoogleCalendarAdapter,
OAuthManager,
OutlookCalendarAdapter,
)
from noteflow.infrastructure.calendar.google_adapter import GoogleCalendarError
from noteflow.infrastructure.calendar.oauth_manager import OAuthError
from noteflow.infrastructure.calendar.outlook_adapter import OutlookCalendarError
from ._errors import CalendarServiceError
if TYPE_CHECKING:
from collections.abc import Awaitable, Callable
from noteflow.config.settings import CalendarIntegrationSettings
from noteflow.domain.ports.unit_of_work import UnitOfWork
class CalendarServiceEventsMixin:
"""Mixin for calendar event fetching operations."""
_oauth_manager: OAuthManager
_uow_factory: Callable[[], UnitOfWork]
_settings: CalendarIntegrationSettings
_google_adapter: GoogleCalendarAdapter
_outlook_adapter: OutlookCalendarAdapter
_parse_calendar_provider: Callable[..., OAuthProvider]
_load_calendar_integration: Callable[..., Awaitable[Integration]]
_load_tokens_for_provider: Callable[..., Awaitable[OAuthTokens]]
_refresh_tokens_if_needed: Callable[..., Awaitable[OAuthTokens]]
_record_sync_success: Callable[..., Awaitable[None]]
_record_sync_error: Callable[..., Awaitable[None]]
_fetch_events: Callable[..., Awaitable[list[CalendarEventInfo]]]
async def list_calendar_events(
self,
provider: str | None = None,
hours_ahead: int | None = None,
limit: int | None = None,
) -> list[CalendarEventInfo]:
"""Fetch calendar events from connected providers."""
effective_hours = hours_ahead or self._settings.sync_hours_ahead
effective_limit = limit or self._settings.max_events
if provider:
events = await self._fetch_provider_events(
provider=provider,
hours_ahead=effective_hours,
limit=effective_limit,
)
else:
events = await self._fetch_all_provider_events(effective_hours, effective_limit)
events.sort(key=lambda e: e.start_time)
return events
async def _fetch_all_provider_events(
self,
hours_ahead: int,
limit: int,
) -> list[CalendarEventInfo]:
"""Fetch events from all configured providers, ignoring errors."""
events: list[CalendarEventInfo] = []
for p in [OAuthProvider.GOOGLE.value, OAuthProvider.OUTLOOK.value]:
provider_events = await self._try_fetch_provider_events(p, hours_ahead, limit)
events.extend(provider_events)
return events
async def _try_fetch_provider_events(
self,
provider: str,
hours_ahead: int,
limit: int,
) -> list[CalendarEventInfo]:
"""Attempt to fetch events from a provider, returning empty list on error."""
try:
return await self._fetch_provider_events(
provider=provider,
hours_ahead=hours_ahead,
limit=limit,
)
except CalendarServiceError:
return []
async def _fetch_provider_events(
self,
provider: str,
hours_ahead: int,
limit: int,
) -> list[CalendarEventInfo]:
"""Fetch events from a specific provider with token refresh."""
oauth_provider = self._parse_calendar_provider(provider)
async with self._uow_factory() as uow:
integration = await self._load_calendar_integration(uow, provider)
tokens = await self._load_tokens_for_provider(uow, provider, integration)
tokens = await self._refresh_tokens_if_needed(uow, integration, oauth_provider, tokens)
try:
events = await self._fetch_events(
oauth_provider,
tokens.access_token,
hours_ahead,
limit,
)
except (GoogleCalendarError, OutlookCalendarError) as e:
await self._record_sync_error(uow, integration, str(e))
raise CalendarServiceError(str(e)) from e
await self._record_sync_success(uow, integration)
return events
async def _load_calendar_integration(
self,
uow: UnitOfWork,
provider: str,
) -> Integration:
integration = await uow.integrations.get_by_provider(
provider=provider,
integration_type=IntegrationType.CALENDAR.value,
)
if integration is None or not integration.is_connected:
raise CalendarServiceError(f"Provider {provider} not connected")
return integration
async def _load_tokens_for_provider(
self,
uow: UnitOfWork,
provider: str,
integration: Integration,
) -> OAuthTokens:
secrets = await uow.integrations.get_secrets(integration.id)
if not secrets:
raise CalendarServiceError(f"No tokens for provider {provider}")
try:
return OAuthTokens.from_secrets_dict(secrets)
except (KeyError, ValueError) as e:
raise CalendarServiceError(f"Invalid tokens: {e}") from e
async def _refresh_tokens_if_needed(
self,
uow: UnitOfWork,
integration: Integration,
oauth_provider: OAuthProvider,
tokens: OAuthTokens,
) -> OAuthTokens:
if not (tokens.is_expired() and tokens.refresh_token):
return tokens
try:
refreshed = await self._oauth_manager.refresh_tokens(
provider=oauth_provider,
refresh_token=tokens.refresh_token,
)
await uow.integrations.set_secrets(
integration_id=integration.id,
secrets=refreshed.to_secrets_dict(),
)
await uow.commit()
return refreshed
except OAuthError as e:
await self._record_sync_error(uow, integration, f"{ERR_TOKEN_REFRESH_PREFIX}{e}")
raise CalendarServiceError(f"{ERR_TOKEN_REFRESH_PREFIX}{e}") from e
async def _record_sync_success(self, uow: UnitOfWork, integration: Integration) -> None:
integration.record_sync()
await uow.integrations.update(integration)
await uow.commit()
async def _record_sync_error(
self,
uow: UnitOfWork,
integration: Integration,
message: str,
) -> None:
integration.mark_error(message)
await uow.integrations.update(integration)
await uow.commit()
async def _fetch_events(
self,
provider: OAuthProvider,
access_token: str,
hours_ahead: int,
limit: int,
) -> list[CalendarEventInfo]:
"""Fetch events from provider API."""
adapter = self._get_adapter(provider)
return await adapter.list_events(
access_token=access_token,
hours_ahead=hours_ahead,
limit=limit,
)
async def _fetch_account_email(
self,
provider: OAuthProvider,
access_token: str,
) -> str:
"""Fetch user email from provider API."""
adapter = self._get_adapter(provider)
return await adapter.get_user_email(access_token)
def _get_adapter(
self,
provider: OAuthProvider,
) -> GoogleCalendarAdapter | OutlookCalendarAdapter:
"""Get calendar adapter for provider."""
if provider == OAuthProvider.GOOGLE:
return self._google_adapter
return self._outlook_adapter

View File

@@ -0,0 +1,49 @@
"""Helper methods mixin for calendar service."""
from __future__ import annotations
from datetime import datetime
from typing import TYPE_CHECKING
from noteflow.domain.entities.integration import Integration, IntegrationStatus
from noteflow.domain.value_objects import OAuthProvider, OAuthTokens
from ._errors import CalendarServiceError
if TYPE_CHECKING:
from noteflow.config.settings import CalendarIntegrationSettings
class CalendarServiceHelpersMixin:
"""Mixin for helper/utility methods."""
_settings: CalendarIntegrationSettings
def _parse_calendar_provider(self, provider: str) -> OAuthProvider:
"""Parse and validate provider string for calendar operations."""
try:
return OAuthProvider.parse(provider)
except ValueError as e:
raise CalendarServiceError(str(e)) from e
def _map_integration_status(self, status: IntegrationStatus) -> str:
"""Map IntegrationStatus to connection status string."""
return status.value if status in IntegrationStatus else IntegrationStatus.DISCONNECTED.value
def _resolve_connection_status(
self,
integration: Integration,
secrets: dict[str, str] | None,
) -> tuple[str, datetime | None]:
"""Resolve connection status and expiration time from stored secrets."""
status = self._map_integration_status(integration.status)
if not secrets or not integration.is_connected:
return status, None
try:
tokens = OAuthTokens.from_secrets_dict(secrets)
except (KeyError, ValueError):
return IntegrationStatus.ERROR.value, None
expires_at = tokens.expires_at
return ("expired", expires_at) if tokens.is_expired() else (status, expires_at)

View File

@@ -0,0 +1,135 @@
"""OAuth flow mixin for calendar service."""
from __future__ import annotations
from typing import TYPE_CHECKING
from uuid import UUID
from noteflow.domain.constants.fields import PROVIDER
from noteflow.domain.entities.integration import Integration, IntegrationType
from noteflow.domain.value_objects import OAuthProvider, OAuthTokens
from noteflow.infrastructure.calendar import OAuthManager
from noteflow.infrastructure.calendar.google_adapter import GoogleCalendarError
from noteflow.infrastructure.calendar.oauth_manager import OAuthError
from noteflow.infrastructure.calendar.outlook_adapter import OutlookCalendarError
from noteflow.infrastructure.logging import get_logger
from ._errors import CalendarServiceError
if TYPE_CHECKING:
from collections.abc import Awaitable, Callable
from noteflow.config.settings import CalendarIntegrationSettings
from noteflow.domain.ports.unit_of_work import UnitOfWork
logger = get_logger(__name__)
class CalendarServiceOAuthMixin:
"""Mixin for OAuth flow operations."""
_oauth_manager: OAuthManager
_settings: CalendarIntegrationSettings
_uow_factory: Callable[[], UnitOfWork]
DEFAULT_WORKSPACE_ID: UUID
_parse_calendar_provider: Callable[..., OAuthProvider]
_exchange_tokens: Callable[..., Awaitable[OAuthTokens]]
_fetch_provider_email: Callable[..., Awaitable[str]]
_fetch_account_email: Callable[..., Awaitable[str]]
async def initiate_oauth(
self,
provider: str,
redirect_uri: str | None = None,
) -> tuple[str, str]:
"""Start OAuth flow for a calendar provider."""
oauth_provider = self._parse_calendar_provider(provider)
effective_redirect = redirect_uri or self._settings.redirect_uri
try:
auth_url, state = self._oauth_manager.initiate_auth(
provider=oauth_provider,
redirect_uri=effective_redirect,
)
logger.info("Initiated OAuth flow for provider=%s", provider)
return auth_url, state
except OAuthError as e:
raise CalendarServiceError(str(e)) from e
async def complete_oauth(
self,
provider: str,
code: str,
state: str,
) -> UUID:
"""Complete OAuth flow and store tokens."""
oauth_provider = self._parse_calendar_provider(provider)
tokens = await self._exchange_tokens(oauth_provider, code, state)
email = await self._fetch_provider_email(oauth_provider, tokens.access_token)
integration_id = await self._store_calendar_integration(provider, email, tokens)
logger.info("Completed OAuth for provider=%s, email=%s", provider, email)
return integration_id
async def _exchange_tokens(
self,
oauth_provider: OAuthProvider,
code: str,
state: str,
) -> OAuthTokens:
"""Exchange authorization code for tokens."""
try:
return await self._oauth_manager.complete_auth(
provider=oauth_provider,
code=code,
state=state,
)
except OAuthError as e:
raise CalendarServiceError(f"OAuth failed: {e}") from e
async def _fetch_provider_email(
self,
oauth_provider: OAuthProvider,
access_token: str,
) -> str:
"""Fetch the account email for a provider."""
try:
return await self._fetch_account_email(oauth_provider, access_token)
except (GoogleCalendarError, OutlookCalendarError) as e:
raise CalendarServiceError(f"Failed to get user email: {e}") from e
async def _store_calendar_integration(
self,
provider: str,
email: str,
tokens: OAuthTokens,
) -> UUID:
"""Persist calendar integration and encrypted tokens."""
async with self._uow_factory() as uow:
integration = await uow.integrations.get_by_provider(
provider=provider,
integration_type=IntegrationType.CALENDAR.value,
)
if integration is None:
integration = Integration.create(
workspace_id=self.DEFAULT_WORKSPACE_ID,
name=f"{provider.title()} Calendar",
integration_type=IntegrationType.CALENDAR,
config={PROVIDER: provider},
)
await uow.integrations.create(integration)
else:
integration.config[PROVIDER] = provider
integration.connect(provider_email=email)
await uow.integrations.update(integration)
await uow.integrations.set_secrets(
integration_id=integration.id,
secrets=tokens.to_secrets_dict(),
)
await uow.commit()
return integration.id

View File

@@ -0,0 +1,64 @@
"""Calendar integration service.
Orchestrates OAuth flow, token management, and calendar event fetching.
Uses existing Integration entity and IntegrationRepository for persistence.
"""
from __future__ import annotations
from typing import TYPE_CHECKING, TypedDict, Unpack
from uuid import UUID
from noteflow.infrastructure.calendar import (
GoogleCalendarAdapter,
OAuthManager,
OutlookCalendarAdapter,
)
from ._connection_mixin import CalendarServiceConnectionMixin
from ._events_mixin import CalendarServiceEventsMixin
from ._helpers_mixin import CalendarServiceHelpersMixin
from ._oauth_mixin import CalendarServiceOAuthMixin
class _CalendarServiceDepsKwargs(TypedDict, total=False):
"""Optional dependency overrides for CalendarService."""
oauth_manager: OAuthManager
google_adapter: GoogleCalendarAdapter
outlook_adapter: OutlookCalendarAdapter
if TYPE_CHECKING:
from collections.abc import Callable
from noteflow.config.settings import CalendarIntegrationSettings
from noteflow.domain.ports.unit_of_work import UnitOfWork
class CalendarService(
CalendarServiceOAuthMixin,
CalendarServiceConnectionMixin,
CalendarServiceEventsMixin,
CalendarServiceHelpersMixin,
):
"""Calendar integration service."""
# Default workspace ID for single-user mode
DEFAULT_WORKSPACE_ID = UUID("00000000-0000-0000-0000-000000000001")
def __init__(
self,
uow_factory: Callable[[], UnitOfWork],
settings: CalendarIntegrationSettings,
**kwargs: Unpack[_CalendarServiceDepsKwargs],
) -> None:
"""Initialize calendar service."""
self._uow_factory = uow_factory
self._settings = settings
oauth_manager = kwargs.get("oauth_manager")
google_adapter = kwargs.get("google_adapter")
outlook_adapter = kwargs.get("outlook_adapter")
self._oauth_manager = oauth_manager or OAuthManager(settings)
self._google_adapter = google_adapter or GoogleCalendarAdapter()
self._outlook_adapter = outlook_adapter or OutlookCalendarAdapter()

View File

@@ -1,480 +0,0 @@
"""Calendar integration service.
Orchestrates OAuth flow, token management, and calendar event fetching.
Uses existing Integration entity and IntegrationRepository for persistence.
"""
from __future__ import annotations
from datetime import datetime
from typing import TYPE_CHECKING, TypedDict, Unpack
from uuid import UUID
from noteflow.config.constants import ERR_TOKEN_REFRESH_PREFIX, OAUTH_FIELD_ACCESS_TOKEN
from noteflow.domain.entities.integration import Integration, IntegrationStatus, IntegrationType
from noteflow.domain.ports.calendar import CalendarEventInfo, OAuthConnectionInfo
from noteflow.domain.value_objects import OAuthProvider, OAuthTokens
from noteflow.infrastructure.calendar import (
GoogleCalendarAdapter,
OAuthManager,
OutlookCalendarAdapter,
)
from noteflow.infrastructure.calendar.google_adapter import GoogleCalendarError
from noteflow.infrastructure.calendar.oauth_manager import OAuthError
from noteflow.infrastructure.calendar.outlook_adapter import OutlookCalendarError
from noteflow.infrastructure.logging import get_logger
from noteflow.domain.constants.fields import PROVIDER
class _CalendarServiceDepsKwargs(TypedDict, total=False):
"""Optional dependency overrides for CalendarService."""
oauth_manager: OAuthManager
google_adapter: GoogleCalendarAdapter
outlook_adapter: OutlookCalendarAdapter
if TYPE_CHECKING:
from collections.abc import Awaitable, Callable
from noteflow.config.settings import CalendarIntegrationSettings
from noteflow.domain.ports.unit_of_work import UnitOfWork
logger = get_logger(__name__)
class CalendarServiceError(Exception):
"""Calendar service operation failed."""
class _CalendarServiceBase:
_oauth_manager: OAuthManager
_settings: CalendarIntegrationSettings
_uow_factory: Callable[[], UnitOfWork]
_google_adapter: GoogleCalendarAdapter
_outlook_adapter: OutlookCalendarAdapter
DEFAULT_WORKSPACE_ID: UUID
_parse_calendar_provider: Callable[..., OAuthProvider]
_exchange_tokens: Callable[..., Awaitable[OAuthTokens]]
_fetch_provider_email: Callable[..., Awaitable[str]]
_fetch_events: Callable[..., Awaitable[list[CalendarEventInfo]]]
_fetch_account_email: Callable[..., Awaitable[str]]
_get_adapter: Callable[..., GoogleCalendarAdapter | OutlookCalendarAdapter]
_load_calendar_integration: Callable[..., Awaitable[Integration]]
_load_tokens_for_provider: Callable[..., Awaitable[OAuthTokens]]
_refresh_tokens_if_needed: Callable[..., Awaitable[OAuthTokens]]
_record_sync_success: Callable[..., Awaitable[None]]
_record_sync_error: Callable[..., Awaitable[None]]
_resolve_connection_status: Callable[..., tuple[str, datetime | None]]
class _CalendarServiceOAuthMixin(_CalendarServiceBase):
_oauth_manager: OAuthManager
_settings: CalendarIntegrationSettings
async def initiate_oauth(
self,
provider: str,
redirect_uri: str | None = None,
) -> tuple[str, str]:
"""Start OAuth flow for a calendar provider."""
oauth_provider = self._parse_calendar_provider(provider)
effective_redirect = redirect_uri or self._settings.redirect_uri
try:
auth_url, state = self._oauth_manager.initiate_auth(
provider=oauth_provider,
redirect_uri=effective_redirect,
)
logger.info("Initiated OAuth flow for provider=%s", provider)
return auth_url, state
except OAuthError as e:
raise CalendarServiceError(str(e)) from e
async def complete_oauth(
self,
provider: str,
code: str,
state: str,
) -> UUID:
"""Complete OAuth flow and store tokens."""
oauth_provider = self._parse_calendar_provider(provider)
tokens = await self._exchange_tokens(oauth_provider, code, state)
email = await self._fetch_provider_email(oauth_provider, tokens.access_token)
integration_id = await self._store_calendar_integration(provider, email, tokens)
logger.info("Completed OAuth for provider=%s, email=%s", provider, email)
return integration_id
async def _exchange_tokens(
self,
oauth_provider: OAuthProvider,
code: str,
state: str,
) -> OAuthTokens:
"""Exchange authorization code for tokens."""
try:
return await self._oauth_manager.complete_auth(
provider=oauth_provider,
code=code,
state=state,
)
except OAuthError as e:
raise CalendarServiceError(f"OAuth failed: {e}") from e
async def _fetch_provider_email(
self,
oauth_provider: OAuthProvider,
access_token: str,
) -> str:
"""Fetch the account email for a provider."""
try:
return await self._fetch_account_email(oauth_provider, access_token)
except (GoogleCalendarError, OutlookCalendarError) as e:
raise CalendarServiceError(f"Failed to get user email: {e}") from e
async def _store_calendar_integration(
self,
provider: str,
email: str,
tokens: OAuthTokens,
) -> UUID:
"""Persist calendar integration and encrypted tokens."""
async with self._uow_factory() as uow:
integration = await uow.integrations.get_by_provider(
provider=provider,
integration_type=IntegrationType.CALENDAR.value,
)
if integration is None:
integration = Integration.create(
workspace_id=self.DEFAULT_WORKSPACE_ID,
name=f"{provider.title()} Calendar",
integration_type=IntegrationType.CALENDAR,
config={PROVIDER: provider},
)
await uow.integrations.create(integration)
else:
integration.config[PROVIDER] = provider
integration.connect(provider_email=email)
await uow.integrations.update(integration)
await uow.integrations.set_secrets(
integration_id=integration.id,
secrets=tokens.to_secrets_dict(),
)
await uow.commit()
return integration.id
class _CalendarServiceConnectionMixin(_CalendarServiceBase):
_oauth_manager: OAuthManager
_uow_factory: Callable[[], UnitOfWork]
async def get_connection_status(self, provider: str) -> OAuthConnectionInfo:
"""Get OAuth connection status for a provider."""
async with self._uow_factory() as uow:
integration = await uow.integrations.get_by_provider(
provider=provider,
integration_type=IntegrationType.CALENDAR.value,
)
if integration is None:
return OAuthConnectionInfo(
provider=provider,
status=IntegrationStatus.DISCONNECTED.value,
)
secrets = await uow.integrations.get_secrets(integration.id)
status, expires_at = self._resolve_connection_status(integration, secrets)
return OAuthConnectionInfo(
provider=provider,
status=status,
email=integration.provider_email,
expires_at=expires_at,
error_message=integration.error_message,
)
async def disconnect(self, provider: str) -> bool:
"""Disconnect OAuth integration and revoke tokens."""
oauth_provider = self._parse_calendar_provider(provider)
async with self._uow_factory() as uow:
integration = await uow.integrations.get_by_provider(
provider=provider,
integration_type=IntegrationType.CALENDAR.value,
)
if integration is None:
return False
secrets = await uow.integrations.get_secrets(integration.id)
access_token = secrets.get(OAUTH_FIELD_ACCESS_TOKEN) if secrets else None
await uow.integrations.delete(integration.id)
await uow.commit()
if access_token:
try:
await self._oauth_manager.revoke_tokens(oauth_provider, access_token)
except OAuthError as e:
logger.warning(
"Failed to revoke tokens for provider=%s: %s",
provider,
e,
)
logger.info("Disconnected provider=%s", provider)
return True
class _CalendarServiceEventsMixin(_CalendarServiceBase):
_oauth_manager: OAuthManager
_uow_factory: Callable[[], UnitOfWork]
_settings: CalendarIntegrationSettings
_google_adapter: GoogleCalendarAdapter
_outlook_adapter: OutlookCalendarAdapter
async def list_calendar_events(
self,
provider: str | None = None,
hours_ahead: int | None = None,
limit: int | None = None,
) -> list[CalendarEventInfo]:
"""Fetch calendar events from connected providers."""
effective_hours = hours_ahead or self._settings.sync_hours_ahead
effective_limit = limit or self._settings.max_events
if provider:
events = await self._fetch_provider_events(
provider=provider,
hours_ahead=effective_hours,
limit=effective_limit,
)
else:
events = await self._fetch_all_provider_events(effective_hours, effective_limit)
events.sort(key=lambda e: e.start_time)
return events
async def _fetch_all_provider_events(
self,
hours_ahead: int,
limit: int,
) -> list[CalendarEventInfo]:
"""Fetch events from all configured providers, ignoring errors."""
events: list[CalendarEventInfo] = []
for p in [OAuthProvider.GOOGLE.value, OAuthProvider.OUTLOOK.value]:
provider_events = await self._try_fetch_provider_events(p, hours_ahead, limit)
events.extend(provider_events)
return events
async def _try_fetch_provider_events(
self,
provider: str,
hours_ahead: int,
limit: int,
) -> list[CalendarEventInfo]:
"""Attempt to fetch events from a provider, returning empty list on error."""
try:
return await self._fetch_provider_events(
provider=provider,
hours_ahead=hours_ahead,
limit=limit,
)
except CalendarServiceError:
return []
async def _fetch_provider_events(
self,
provider: str,
hours_ahead: int,
limit: int,
) -> list[CalendarEventInfo]:
"""Fetch events from a specific provider with token refresh."""
oauth_provider = self._parse_calendar_provider(provider)
async with self._uow_factory() as uow:
integration = await self._load_calendar_integration(uow, provider)
tokens = await self._load_tokens_for_provider(uow, provider, integration)
tokens = await self._refresh_tokens_if_needed(uow, integration, oauth_provider, tokens)
try:
events = await self._fetch_events(
oauth_provider,
tokens.access_token,
hours_ahead,
limit,
)
except (GoogleCalendarError, OutlookCalendarError) as e:
await self._record_sync_error(uow, integration, str(e))
raise CalendarServiceError(str(e)) from e
await self._record_sync_success(uow, integration)
return events
async def _load_calendar_integration(
self,
uow: UnitOfWork,
provider: str,
) -> Integration:
integration = await uow.integrations.get_by_provider(
provider=provider,
integration_type=IntegrationType.CALENDAR.value,
)
if integration is None or not integration.is_connected:
raise CalendarServiceError(f"Provider {provider} not connected")
return integration
async def _load_tokens_for_provider(
self,
uow: UnitOfWork,
provider: str,
integration: Integration,
) -> OAuthTokens:
secrets = await uow.integrations.get_secrets(integration.id)
if not secrets:
raise CalendarServiceError(f"No tokens for provider {provider}")
try:
return OAuthTokens.from_secrets_dict(secrets)
except (KeyError, ValueError) as e:
raise CalendarServiceError(f"Invalid tokens: {e}") from e
async def _refresh_tokens_if_needed(
self,
uow: UnitOfWork,
integration: Integration,
oauth_provider: OAuthProvider,
tokens: OAuthTokens,
) -> OAuthTokens:
if not (tokens.is_expired() and tokens.refresh_token):
return tokens
try:
refreshed = await self._oauth_manager.refresh_tokens(
provider=oauth_provider,
refresh_token=tokens.refresh_token,
)
await uow.integrations.set_secrets(
integration_id=integration.id,
secrets=refreshed.to_secrets_dict(),
)
await uow.commit()
return refreshed
except OAuthError as e:
await self._record_sync_error(uow, integration, f"{ERR_TOKEN_REFRESH_PREFIX}{e}")
raise CalendarServiceError(f"{ERR_TOKEN_REFRESH_PREFIX}{e}") from e
async def _record_sync_success(self, uow: UnitOfWork, integration: Integration) -> None:
integration.record_sync()
await uow.integrations.update(integration)
await uow.commit()
async def _record_sync_error(
self,
uow: UnitOfWork,
integration: Integration,
message: str,
) -> None:
integration.mark_error(message)
await uow.integrations.update(integration)
await uow.commit()
async def _fetch_events(
self,
provider: OAuthProvider,
access_token: str,
hours_ahead: int,
limit: int,
) -> list[CalendarEventInfo]:
"""Fetch events from provider API."""
adapter = self._get_adapter(provider)
return await adapter.list_events(
access_token=access_token,
hours_ahead=hours_ahead,
limit=limit,
)
async def _fetch_account_email(
self,
provider: OAuthProvider,
access_token: str,
) -> str:
"""Fetch user email from provider API."""
adapter = self._get_adapter(provider)
return await adapter.get_user_email(access_token)
def _get_adapter(
self,
provider: OAuthProvider,
) -> GoogleCalendarAdapter | OutlookCalendarAdapter:
"""Get calendar adapter for provider."""
if provider == OAuthProvider.GOOGLE:
return self._google_adapter
return self._outlook_adapter
class _CalendarServiceHelpersMixin(_CalendarServiceBase):
_settings: CalendarIntegrationSettings
def _parse_calendar_provider(self, provider: str) -> OAuthProvider:
"""Parse and validate provider string for calendar operations."""
try:
return OAuthProvider.parse(provider)
except ValueError as e:
raise CalendarServiceError(str(e)) from e
def _map_integration_status(self, status: IntegrationStatus) -> str:
"""Map IntegrationStatus to connection status string."""
return status.value if status in IntegrationStatus else IntegrationStatus.DISCONNECTED.value
def _resolve_connection_status(
self,
integration: Integration,
secrets: dict[str, str] | None,
) -> tuple[str, datetime | None]:
"""Resolve connection status and expiration time from stored secrets."""
status = self._map_integration_status(integration.status)
if not secrets or not integration.is_connected:
return status, None
try:
tokens = OAuthTokens.from_secrets_dict(secrets)
except (KeyError, ValueError):
return IntegrationStatus.ERROR.value, None
expires_at = tokens.expires_at
return ("expired", expires_at) if tokens.is_expired() else (status, expires_at)
class CalendarService(
_CalendarServiceOAuthMixin,
_CalendarServiceConnectionMixin,
_CalendarServiceEventsMixin,
_CalendarServiceHelpersMixin,
):
"""Calendar integration service."""
# Default workspace ID for single-user mode
DEFAULT_WORKSPACE_ID = UUID("00000000-0000-0000-0000-000000000001")
def __init__(
self,
uow_factory: Callable[[], UnitOfWork],
settings: CalendarIntegrationSettings,
**kwargs: Unpack[_CalendarServiceDepsKwargs],
) -> None:
"""Initialize calendar service."""
self._uow_factory = uow_factory
self._settings = settings
oauth_manager = kwargs.get("oauth_manager")
google_adapter = kwargs.get("google_adapter")
outlook_adapter = kwargs.get("outlook_adapter")
self._oauth_manager = oauth_manager or OAuthManager(settings)
self._google_adapter = google_adapter or GoogleCalendarAdapter()
self._outlook_adapter = outlook_adapter or OutlookCalendarAdapter()

View File

@@ -37,24 +37,31 @@ class ExportFormat(Enum):
HTML = "html"
PDF = "pdf"
@classmethod
def from_extension(cls, extension: str) -> ExportFormat | None:
"""Map file extension to export format.
Args:
extension: File extension (e.g., '.md', '.html').
# Module-level constant mapping file extensions to format values.
# Keys are lowercase extensions, values are ExportFormat enum value strings.
_EXTENSION_TO_FORMAT: dict[str, str] = {
".md": "markdown",
".markdown": "markdown",
EXPORT_EXT_HTML: "html",
".htm": "html",
EXPORT_EXT_PDF: "pdf",
}
Returns:
Matching ExportFormat or None if not recognized.
"""
extension_map = {
".md": cls.MARKDOWN,
".markdown": cls.MARKDOWN,
EXPORT_EXT_HTML: cls.HTML,
".htm": cls.HTML,
EXPORT_EXT_PDF: cls.PDF,
}
return extension_map.get(extension.lower())
def export_format_from_extension(extension: str) -> ExportFormat | None:
"""Map file extension to export format.
Args:
extension: File extension (e.g., '.md', '.html').
Returns:
Matching ExportFormat or None if not recognized.
"""
format_value = _EXTENSION_TO_FORMAT.get(extension.lower())
if format_value is None:
return None
return ExportFormat(format_value)
class ExportService:
@@ -262,7 +269,7 @@ class ExportService:
Raises:
ValueError: If extension is not recognized.
"""
fmt = ExportFormat.from_extension(extension)
fmt = export_format_from_extension(extension)
if fmt is None:
supported = [".md", ".markdown", EXPORT_EXT_HTML, ".htm", EXPORT_EXT_PDF]
logger.warning(

View File

@@ -0,0 +1,7 @@
"""Identity service package."""
from __future__ import annotations
from .identity_service import IdentityService
__all__ = ["IdentityService"]

View File

@@ -0,0 +1,57 @@
"""Context resolution mixin for identity service."""
from __future__ import annotations
from typing import TYPE_CHECKING
from uuid import UUID
from noteflow.domain.identity import OperationContext
from noteflow.infrastructure.logging import get_logger
if TYPE_CHECKING:
from collections.abc import Awaitable, Callable
from noteflow.domain.identity import UserContext, WorkspaceContext
from noteflow.domain.ports.unit_of_work import UnitOfWork
logger = get_logger(__name__)
class IdentityContextMixin:
"""Mixin for operation context resolution."""
get_or_create_default_user: "Callable[..., Awaitable[UserContext]]"
get_or_create_default_workspace: "Callable[..., Awaitable[WorkspaceContext]]"
_get_workspace_context: "Callable[..., Awaitable[WorkspaceContext]]"
async def get_context(
self,
uow: UnitOfWork,
workspace_id: UUID | None = None,
request_id: str | None = None,
) -> OperationContext:
"""Get the full operation context."""
user = await self.get_or_create_default_user(uow)
if workspace_id:
logger.info(
"Resolving context for explicit workspace_id=%s, user_id=%s",
workspace_id,
user.user_id,
)
ws_context = await self._get_workspace_context(uow, workspace_id, user.user_id)
else:
logger.debug("No workspace_id provided, using default workspace")
ws_context = await self.get_or_create_default_workspace(uow, user.user_id)
logger.debug(
"Resolved operation context: user=%s, workspace=%s, request_id=%s",
user.user_id,
ws_context.workspace_id,
request_id,
)
return OperationContext(
user=user,
workspace=ws_context,
request_id=request_id,
)

View File

@@ -0,0 +1,78 @@
"""Default user and workspace creation mixin for identity service."""
from __future__ import annotations
from typing import TYPE_CHECKING
from uuid import UUID
from noteflow.domain.identity import DEFAULT_USER_DISPLAY_NAME, UserContext, WorkspaceContext
from noteflow.infrastructure.logging import get_logger
from noteflow.infrastructure.persistence.models import DEFAULT_USER_ID
if TYPE_CHECKING:
from collections.abc import Awaitable, Callable
from noteflow.domain.identity import Workspace, WorkspaceContext
from noteflow.domain.ports.unit_of_work import UnitOfWork
logger = get_logger(__name__)
class IdentityDefaultsMixin:
"""Mixin for default user and workspace creation."""
_get_default_workspace: "Callable[..., Awaitable[Workspace | None]]"
_workspace_context_for_member: "Callable[..., Awaitable[WorkspaceContext]]"
_create_default_workspace: "Callable[..., Awaitable[WorkspaceContext]]"
_default_workspace_context: "Callable[..., WorkspaceContext]"
async def get_or_create_default_user(
self,
uow: UnitOfWork,
) -> UserContext:
"""Get or create the default local user."""
if not uow.supports_users:
logger.debug("Memory mode: returning synthetic default user context")
return UserContext(
user_id=UUID(DEFAULT_USER_ID),
display_name=DEFAULT_USER_DISPLAY_NAME,
)
user = await uow.users.get_default()
if user:
logger.debug("Found existing default user: %s", user.id)
return UserContext(
user_id=user.id,
display_name=user.display_name,
email=user.email,
)
user_id = UUID(DEFAULT_USER_ID)
await uow.users.create_default(
user_id=user_id,
display_name=DEFAULT_USER_DISPLAY_NAME,
)
await uow.commit()
logger.info("Created default local user: %s", user_id)
return UserContext(
user_id=user_id,
display_name=DEFAULT_USER_DISPLAY_NAME,
)
async def get_or_create_default_workspace(
self,
uow: UnitOfWork,
user_id: UUID,
) -> WorkspaceContext:
"""Get or create the default workspace for a user."""
if not uow.supports_workspaces:
logger.debug("Memory mode: returning synthetic default workspace context")
return self._default_workspace_context()
workspace = await self._get_default_workspace(uow, user_id)
if workspace:
return await self._workspace_context_for_member(uow, workspace, user_id)
return await self._create_default_workspace(uow, user_id)

View File

@@ -0,0 +1,145 @@
"""Workspace management mixin for identity service."""
from __future__ import annotations
from typing import TYPE_CHECKING
from uuid import UUID
from noteflow.config.constants import ERROR_MSG_WORKSPACE_PREFIX
from noteflow.domain.identity import (
DEFAULT_WORKSPACE_NAME,
Workspace,
WorkspaceContext,
WorkspaceMembership,
WorkspaceRole,
)
from noteflow.infrastructure.logging import get_logger
from noteflow.infrastructure.persistence.models import DEFAULT_WORKSPACE_ID
if TYPE_CHECKING:
from noteflow.domain.ports.unit_of_work import UnitOfWork
logger = get_logger(__name__)
class IdentityWorkspaceMixin:
"""Mixin for workspace operations."""
async def _get_workspace_context(
self,
uow: UnitOfWork,
workspace_id: UUID,
user_id: UUID,
) -> WorkspaceContext:
"""Get workspace context for a specific workspace."""
if not uow.supports_workspaces:
logger.debug("Memory mode: returning synthetic workspace context for %s", workspace_id)
return self._workspace_context_for_memory(workspace_id)
workspace = await self._require_workspace(uow, workspace_id)
membership = await self._require_membership(uow, workspace_id, user_id)
logger.debug(
"Workspace access granted: user=%s, workspace=%s, role=%s",
user_id,
workspace_id,
membership.role,
)
return WorkspaceContext(
workspace_id=workspace.id,
workspace_name=workspace.name,
role=membership.role,
)
def _default_workspace_context(self) -> WorkspaceContext:
return WorkspaceContext(
workspace_id=UUID(DEFAULT_WORKSPACE_ID),
workspace_name=DEFAULT_WORKSPACE_NAME,
role=WorkspaceRole.OWNER,
)
def _workspace_context_for_memory(self, workspace_id: UUID) -> WorkspaceContext:
return WorkspaceContext(
workspace_id=workspace_id,
workspace_name=DEFAULT_WORKSPACE_NAME,
role=WorkspaceRole.OWNER,
)
async def _get_default_workspace(
self,
uow: UnitOfWork,
user_id: UUID,
) -> Workspace | None:
workspace = await uow.workspaces.get_default_for_user(user_id)
if workspace:
logger.debug(
"Found existing default workspace for user %s: %s",
user_id,
workspace.id,
)
return workspace
async def _workspace_context_for_member(
self,
uow: UnitOfWork,
workspace: Workspace,
user_id: UUID,
) -> WorkspaceContext:
membership = await uow.workspaces.get_membership(workspace.id, user_id)
role = WorkspaceRole(membership.role.value) if membership else WorkspaceRole.OWNER
return WorkspaceContext(
workspace_id=workspace.id,
workspace_name=workspace.name,
role=role,
)
async def _create_default_workspace(
self,
uow: UnitOfWork,
user_id: UUID,
) -> WorkspaceContext:
workspace_id = UUID(DEFAULT_WORKSPACE_ID)
await uow.workspaces.create(
workspace_id=workspace_id,
name=DEFAULT_WORKSPACE_NAME,
owner_id=user_id,
is_default=True,
)
await uow.commit()
logger.info("Created default workspace for user %s: %s", user_id, workspace_id)
return WorkspaceContext(
workspace_id=workspace_id,
workspace_name=DEFAULT_WORKSPACE_NAME,
role=WorkspaceRole.OWNER,
)
async def _require_workspace(
self,
uow: UnitOfWork,
workspace_id: UUID,
) -> Workspace:
logger.debug("Looking up workspace %s", workspace_id)
workspace = await uow.workspaces.get(workspace_id)
if not workspace:
logger.warning("Workspace not found: %s", workspace_id)
msg = f"{ERROR_MSG_WORKSPACE_PREFIX}{workspace_id} not found"
raise ValueError(msg)
return workspace
async def _require_membership(
self,
uow: UnitOfWork,
workspace_id: UUID,
user_id: UUID,
) -> WorkspaceMembership:
membership = await uow.workspaces.get_membership(workspace_id, user_id)
if not membership:
logger.warning(
"Permission denied: user %s is not a member of workspace %s",
user_id,
workspace_id,
)
msg = f"User not a member of workspace {workspace_id}"
raise PermissionError(msg)
return membership

View File

@@ -0,0 +1,234 @@
"""Identity and context management application service.
Orchestrates user identity and workspace context for local-first multi-user support.
Following hexagonal architecture:
gRPC interceptor → IdentityService (application) → Repositories (infrastructure)
"""
from __future__ import annotations
from typing import TYPE_CHECKING
from uuid import UUID, uuid4
from noteflow.config.constants import ERROR_MSG_WORKSPACE_PREFIX
from noteflow.domain.entities.project import slugify
from noteflow.domain.identity import (
DEFAULT_PROJECT_NAME,
DEFAULT_USER_DISPLAY_NAME,
DEFAULT_WORKSPACE_NAME,
OperationContext,
User,
UserContext,
Workspace,
WorkspaceContext,
WorkspaceMembership,
WorkspaceRole,
)
from noteflow.domain.constants.fields import EMAIL
from noteflow.infrastructure.logging import get_logger
from ._context_mixin import IdentityContextMixin
from ._defaults_mixin import IdentityDefaultsMixin
from ._workspace_mixin import IdentityWorkspaceMixin
if TYPE_CHECKING:
from collections.abc import Sequence
from noteflow.domain.ports.unit_of_work import UnitOfWork
logger = get_logger(__name__)
class IdentityService(
IdentityDefaultsMixin,
IdentityContextMixin,
IdentityWorkspaceMixin,
):
"""Application service for identity and workspace context management.
Provide a clean interface for identity operations, abstracting away
the infrastructure details (database persistence, default creation).
Orchestrates:
- Default user and workspace creation on first run
- Operation context resolution
- Workspace membership management
"""
async def list_workspaces(
self, uow: UnitOfWork, user_id: UUID, limit: int = 50, offset: int = 0
) -> Sequence[Workspace]:
"""List workspaces a user is a member of.
Args:
uow: Unit of work for database access.
user_id: User UUID.
limit: Maximum workspaces to return.
offset: Pagination offset.
Returns:
List of workspaces.
"""
if not uow.supports_workspaces:
logger.debug("Memory mode: returning empty workspace list")
return []
workspaces = await uow.workspaces.list_for_user(user_id, limit, offset)
logger.debug(
"Listed %d workspaces for user %s (limit=%d, offset=%d)",
len(workspaces),
user_id,
limit,
offset,
)
return workspaces
async def create_workspace(
self,
uow: UnitOfWork,
name: str,
owner_id: UUID,
slug: str | None = None,
) -> Workspace:
"""Create a new workspace with a default project.
Each workspace must have exactly one default project. This method
creates both the workspace and its default project atomically.
Args:
uow: Unit of work for database access.
name: Workspace name.
owner_id: User UUID of the owner.
slug: Optional URL slug.
Returns:
Created workspace.
Raises:
NotImplementedError: If workspaces not supported.
"""
self._require_workspace_support(uow)
workspace_id = uuid4()
workspace = await uow.workspaces.create(
workspace_id=workspace_id, name=name, owner_id=owner_id, slug=slug
)
await self._create_default_project_if_supported(uow, workspace_id)
await uow.commit()
logger.info("Created workspace %s: %s", workspace.name, workspace_id)
return workspace
@staticmethod
def _require_workspace_support(uow: UnitOfWork) -> None:
"""Raise if workspaces not supported."""
if not uow.supports_workspaces:
msg = "Workspaces require database persistence"
raise NotImplementedError(msg)
@staticmethod
async def _create_default_project_if_supported(
uow: UnitOfWork,
workspace_id: UUID,
) -> None:
"""Create default project if projects are supported."""
if not uow.supports_projects:
return
project_id = uuid4()
await uow.projects.create(
project_id=project_id,
workspace_id=workspace_id,
name=DEFAULT_PROJECT_NAME,
slug=slugify(DEFAULT_PROJECT_NAME),
description=f"{DEFAULT_PROJECT_NAME} project for this workspace",
is_default=True,
)
logger.info("Created default project for workspace %s", workspace_id)
async def get_user(
self,
uow: UnitOfWork,
user_id: UUID,
) -> User | None:
"""Get user by ID.
Args:
uow: Unit of work for database access.
user_id: User UUID.
Returns:
User if found, None otherwise.
"""
if not uow.supports_users:
logger.debug("Memory mode: users not supported, returning None")
return None
user = await uow.users.get(user_id)
if user:
logger.debug("Found user: %s", user_id)
else:
logger.debug("User not found: %s", user_id)
return user
async def update_user_profile(
self,
uow: UnitOfWork,
user_id: UUID,
display_name: str | None = None,
email: str | None = None,
) -> User | None:
"""Update user profile.
Args:
uow: Unit of work for database access.
user_id: User UUID.
display_name: New display name (optional).
email: New email (optional).
Returns:
Updated user if found, None otherwise.
Raises:
NotImplementedError: If users not supported.
"""
self._require_user_support(uow)
user = await uow.users.get(user_id)
if not user:
logger.warning("User not found for profile update: %s", user_id)
return None
updated_fields = self._apply_profile_updates(user, display_name, email)
if not updated_fields:
logger.debug("No fields to update for user %s", user_id)
return user
updated = await uow.users.update(user)
await uow.commit()
logger.info("Updated user profile: user_id=%s, fields=%s", user_id, ", ".join(updated_fields))
return updated
@staticmethod
def _require_user_support(uow: UnitOfWork) -> None:
"""Raise if users not supported."""
if not uow.supports_users:
msg = "Users require database persistence"
raise NotImplementedError(msg)
@staticmethod
def _apply_profile_updates(
user: User,
display_name: str | None,
email: str | None,
) -> list[str]:
"""Apply profile updates and return list of updated field names."""
updated_fields: list[str] = []
if display_name:
user.display_name = display_name
updated_fields.append("display_name")
if email is not None:
user.email = email
updated_fields.append(EMAIL)
return updated_fields

View File

@@ -1,455 +0,0 @@
"""Identity and context management application service.
Orchestrates user identity and workspace context for local-first multi-user support.
Following hexagonal architecture:
gRPC interceptor → IdentityService (application) → Repositories (infrastructure)
"""
from __future__ import annotations
from typing import TYPE_CHECKING
from uuid import UUID, uuid4
from noteflow.config.constants import ERROR_MSG_WORKSPACE_PREFIX
from noteflow.domain.entities.project import slugify
from noteflow.domain.identity import (
DEFAULT_PROJECT_NAME,
DEFAULT_USER_DISPLAY_NAME,
DEFAULT_WORKSPACE_NAME,
OperationContext,
User,
UserContext,
Workspace,
WorkspaceContext,
WorkspaceMembership,
WorkspaceRole,
)
from noteflow.infrastructure.logging import get_logger
from noteflow.domain.constants.fields import EMAIL
from noteflow.infrastructure.persistence.models import (
DEFAULT_USER_ID,
DEFAULT_WORKSPACE_ID,
)
if TYPE_CHECKING:
from collections.abc import Awaitable, Callable, Sequence
from noteflow.domain.ports.unit_of_work import UnitOfWork
logger = get_logger(__name__)
class _IdentityServiceBase:
get_or_create_default_user: Callable[..., Awaitable[UserContext]]
get_or_create_default_workspace: Callable[..., Awaitable[WorkspaceContext]]
_get_workspace_context: Callable[..., Awaitable[WorkspaceContext]]
_default_workspace_context: Callable[..., WorkspaceContext]
_workspace_context_for_memory: Callable[..., WorkspaceContext]
_get_default_workspace: Callable[..., Awaitable[Workspace | None]]
_workspace_context_for_member: Callable[..., Awaitable[WorkspaceContext]]
_create_default_workspace: Callable[..., Awaitable[WorkspaceContext]]
_require_workspace: Callable[..., Awaitable[Workspace]]
_require_membership: Callable[..., Awaitable[WorkspaceMembership]]
class _IdentityDefaultsMixin(_IdentityServiceBase):
async def get_or_create_default_user(
self,
uow: UnitOfWork,
) -> UserContext:
"""Get or create the default local user."""
if not uow.supports_users:
logger.debug("Memory mode: returning synthetic default user context")
return UserContext(
user_id=UUID(DEFAULT_USER_ID),
display_name=DEFAULT_USER_DISPLAY_NAME,
)
user = await uow.users.get_default()
if user:
logger.debug("Found existing default user: %s", user.id)
return UserContext(
user_id=user.id,
display_name=user.display_name,
email=user.email,
)
user_id = UUID(DEFAULT_USER_ID)
await uow.users.create_default(
user_id=user_id,
display_name=DEFAULT_USER_DISPLAY_NAME,
)
await uow.commit()
logger.info("Created default local user: %s", user_id)
return UserContext(
user_id=user_id,
display_name=DEFAULT_USER_DISPLAY_NAME,
)
async def get_or_create_default_workspace(
self,
uow: UnitOfWork,
user_id: UUID,
) -> WorkspaceContext:
"""Get or create the default workspace for a user."""
if not uow.supports_workspaces:
logger.debug("Memory mode: returning synthetic default workspace context")
return self._default_workspace_context()
workspace = await self._get_default_workspace(uow, user_id)
if workspace:
return await self._workspace_context_for_member(uow, workspace, user_id)
return await self._create_default_workspace(uow, user_id)
class _IdentityContextMixin(_IdentityServiceBase):
async def get_context(
self,
uow: UnitOfWork,
workspace_id: UUID | None = None,
request_id: str | None = None,
) -> OperationContext:
"""Get the full operation context."""
user = await self.get_or_create_default_user(uow)
if workspace_id:
logger.info(
"Resolving context for explicit workspace_id=%s, user_id=%s",
workspace_id,
user.user_id,
)
ws_context = await self._get_workspace_context(uow, workspace_id, user.user_id)
else:
logger.debug("No workspace_id provided, using default workspace")
ws_context = await self.get_or_create_default_workspace(uow, user.user_id)
logger.debug(
"Resolved operation context: user=%s, workspace=%s, request_id=%s",
user.user_id,
ws_context.workspace_id,
request_id,
)
return OperationContext(
user=user,
workspace=ws_context,
request_id=request_id,
)
class _IdentityWorkspaceMixin(_IdentityServiceBase):
async def _get_workspace_context(
self,
uow: UnitOfWork,
workspace_id: UUID,
user_id: UUID,
) -> WorkspaceContext:
"""Get workspace context for a specific workspace."""
if not uow.supports_workspaces:
logger.debug("Memory mode: returning synthetic workspace context for %s", workspace_id)
return self._workspace_context_for_memory(workspace_id)
workspace = await self._require_workspace(uow, workspace_id)
membership = await self._require_membership(uow, workspace_id, user_id)
logger.debug(
"Workspace access granted: user=%s, workspace=%s, role=%s",
user_id,
workspace_id,
membership.role,
)
return WorkspaceContext(
workspace_id=workspace.id,
workspace_name=workspace.name,
role=membership.role,
)
def _default_workspace_context(self) -> WorkspaceContext:
return WorkspaceContext(
workspace_id=UUID(DEFAULT_WORKSPACE_ID),
workspace_name=DEFAULT_WORKSPACE_NAME,
role=WorkspaceRole.OWNER,
)
def _workspace_context_for_memory(self, workspace_id: UUID) -> WorkspaceContext:
return WorkspaceContext(
workspace_id=workspace_id,
workspace_name=DEFAULT_WORKSPACE_NAME,
role=WorkspaceRole.OWNER,
)
async def _get_default_workspace(
self,
uow: UnitOfWork,
user_id: UUID,
) -> Workspace | None:
workspace = await uow.workspaces.get_default_for_user(user_id)
if workspace:
logger.debug(
"Found existing default workspace for user %s: %s",
user_id,
workspace.id,
)
return workspace
async def _workspace_context_for_member(
self,
uow: UnitOfWork,
workspace: Workspace,
user_id: UUID,
) -> WorkspaceContext:
membership = await uow.workspaces.get_membership(workspace.id, user_id)
role = WorkspaceRole(membership.role.value) if membership else WorkspaceRole.OWNER
return WorkspaceContext(
workspace_id=workspace.id,
workspace_name=workspace.name,
role=role,
)
async def _create_default_workspace(
self,
uow: UnitOfWork,
user_id: UUID,
) -> WorkspaceContext:
workspace_id = UUID(DEFAULT_WORKSPACE_ID)
await uow.workspaces.create(
workspace_id=workspace_id,
name=DEFAULT_WORKSPACE_NAME,
owner_id=user_id,
is_default=True,
)
await uow.commit()
logger.info("Created default workspace for user %s: %s", user_id, workspace_id)
return WorkspaceContext(
workspace_id=workspace_id,
workspace_name=DEFAULT_WORKSPACE_NAME,
role=WorkspaceRole.OWNER,
)
async def _require_workspace(
self,
uow: UnitOfWork,
workspace_id: UUID,
) -> Workspace:
logger.debug("Looking up workspace %s", workspace_id)
workspace = await uow.workspaces.get(workspace_id)
if not workspace:
logger.warning("Workspace not found: %s", workspace_id)
msg = f"{ERROR_MSG_WORKSPACE_PREFIX}{workspace_id} not found"
raise ValueError(msg)
return workspace
async def _require_membership(
self,
uow: UnitOfWork,
workspace_id: UUID,
user_id: UUID,
) -> WorkspaceMembership:
membership = await uow.workspaces.get_membership(workspace_id, user_id)
if not membership:
logger.warning(
"Permission denied: user %s is not a member of workspace %s",
user_id,
workspace_id,
)
msg = f"User not a member of workspace {workspace_id}"
raise PermissionError(msg)
return membership
class IdentityService(
_IdentityDefaultsMixin,
_IdentityContextMixin,
_IdentityWorkspaceMixin,
):
"""Application service for identity and workspace context management.
Provide a clean interface for identity operations, abstracting away
the infrastructure details (database persistence, default creation).
Orchestrates:
- Default user and workspace creation on first run
- Operation context resolution
- Workspace membership management
"""
async def list_workspaces(
self, uow: UnitOfWork, user_id: UUID, limit: int = 50, offset: int = 0
) -> Sequence[Workspace]:
"""List workspaces a user is a member of.
Args:
uow: Unit of work for database access.
user_id: User UUID.
limit: Maximum workspaces to return.
offset: Pagination offset.
Returns:
List of workspaces.
"""
if not uow.supports_workspaces:
logger.debug("Memory mode: returning empty workspace list")
return []
workspaces = await uow.workspaces.list_for_user(user_id, limit, offset)
logger.debug(
"Listed %d workspaces for user %s (limit=%d, offset=%d)",
len(workspaces),
user_id,
limit,
offset,
)
return workspaces
async def create_workspace(
self,
uow: UnitOfWork,
name: str,
owner_id: UUID,
slug: str | None = None,
) -> Workspace:
"""Create a new workspace with a default project.
Each workspace must have exactly one default project. This method
creates both the workspace and its default project atomically.
Args:
uow: Unit of work for database access.
name: Workspace name.
owner_id: User UUID of the owner.
slug: Optional URL slug.
Returns:
Created workspace.
Raises:
NotImplementedError: If workspaces not supported.
"""
self._require_workspace_support(uow)
workspace_id = uuid4()
workspace = await uow.workspaces.create(
workspace_id=workspace_id, name=name, owner_id=owner_id, slug=slug
)
await self._create_default_project_if_supported(uow, workspace_id)
await uow.commit()
logger.info("Created workspace %s: %s", workspace.name, workspace_id)
return workspace
@staticmethod
def _require_workspace_support(uow: UnitOfWork) -> None:
"""Raise if workspaces not supported."""
if not uow.supports_workspaces:
msg = "Workspaces require database persistence"
raise NotImplementedError(msg)
@staticmethod
async def _create_default_project_if_supported(
uow: UnitOfWork,
workspace_id: UUID,
) -> None:
"""Create default project if projects are supported."""
if not uow.supports_projects:
return
project_id = uuid4()
await uow.projects.create(
project_id=project_id,
workspace_id=workspace_id,
name=DEFAULT_PROJECT_NAME,
slug=slugify(DEFAULT_PROJECT_NAME),
description=f"{DEFAULT_PROJECT_NAME} project for this workspace",
is_default=True,
)
logger.info("Created default project for workspace %s", workspace_id)
async def get_user(
self,
uow: UnitOfWork,
user_id: UUID,
) -> User | None:
"""Get user by ID.
Args:
uow: Unit of work for database access.
user_id: User UUID.
Returns:
User if found, None otherwise.
"""
if not uow.supports_users:
logger.debug("Memory mode: users not supported, returning None")
return None
user = await uow.users.get(user_id)
if user:
logger.debug("Found user: %s", user_id)
else:
logger.debug("User not found: %s", user_id)
return user
async def update_user_profile(
self,
uow: UnitOfWork,
user_id: UUID,
display_name: str | None = None,
email: str | None = None,
) -> User | None:
"""Update user profile.
Args:
uow: Unit of work for database access.
user_id: User UUID.
display_name: New display name (optional).
email: New email (optional).
Returns:
Updated user if found, None otherwise.
Raises:
NotImplementedError: If users not supported.
"""
self._require_user_support(uow)
user = await uow.users.get(user_id)
if not user:
logger.warning("User not found for profile update: %s", user_id)
return None
updated_fields = self._apply_profile_updates(user, display_name, email)
if not updated_fields:
logger.debug("No fields to update for user %s", user_id)
return user
updated = await uow.users.update(user)
await uow.commit()
logger.info("Updated user profile: user_id=%s, fields=%s", user_id, ", ".join(updated_fields))
return updated
@staticmethod
def _require_user_support(uow: UnitOfWork) -> None:
"""Raise if users not supported."""
if not uow.supports_users:
msg = "Users require database persistence"
raise NotImplementedError(msg)
@staticmethod
def _apply_profile_updates(
user: User,
display_name: str | None,
email: str | None,
) -> list[str]:
"""Apply profile updates and return list of updated field names."""
updated_fields: list[str] = []
if display_name:
user.display_name = display_name
updated_fields.append("display_name")
if email is not None:
user.email = email
updated_fields.append(EMAIL)
return updated_fields

View File

@@ -43,6 +43,90 @@ class ExtractionResult:
total_count: int
class _ModelLifecycleHelper:
"""Handle NER model loading and warmup with thread safety."""
def __init__(self, ner_engine: NerPort) -> None:
"""Initialize model lifecycle helper.
Args:
ner_engine: NER engine implementation.
"""
self._ner_engine = ner_engine
self._model_load_lock = asyncio.Lock()
async def ensure_ready(self) -> None:
"""Ensure the NER model is loaded and warmed up safely."""
if self._ner_engine.is_ready():
return
async with self._model_load_lock:
if self._ner_engine.is_ready():
return
await self._warmup()
async def _warmup(self) -> None:
"""Warm up the NER model with a simple extraction."""
loop = asyncio.get_running_loop()
with log_timing("ner_warmup"):
await loop.run_in_executor(
None,
lambda: self._ner_engine.extract("warm up"),
)
class _ExtractionHelper:
"""Handle NER extraction with concurrency control."""
def __init__(
self,
ner_engine: NerPort,
model_helper: _ModelLifecycleHelper,
) -> None:
"""Initialize extraction helper.
Args:
ner_engine: NER engine implementation.
model_helper: Model lifecycle helper for ensuring readiness.
"""
self._ner_engine = ner_engine
self._model_helper = model_helper
self._extraction_lock = asyncio.Lock()
async def extract(
self,
segments: list[tuple[int, str]],
) -> list[NamedEntity]:
"""Extract entities with concurrency control.
Ensures only one extraction runs at a time and handles
lazy model loading safely.
Args:
segments: List of (segment_id, text) tuples.
Returns:
List of extracted entities.
"""
async with self._extraction_lock:
await self._model_helper.ensure_ready()
return await self._extract_entities(segments)
async def _extract_entities(
self,
segments: list[tuple[int, str]],
) -> list[NamedEntity]:
"""Extract entities in an executor (CPU-bound)."""
loop = asyncio.get_running_loop()
segment_count = len(segments)
with log_timing("ner_extraction", segment_count=segment_count):
entities = await loop.run_in_executor(
None,
self._ner_engine.extract_from_segments,
segments,
)
return entities
class NerService:
"""Application service for Named Entity Recognition.
@@ -69,8 +153,8 @@ class NerService:
"""
self._ner_engine = ner_engine
self._uow_factory = uow_factory
self._extraction_lock = asyncio.Lock()
self._model_load_lock = asyncio.Lock()
self._model_helper = _ModelLifecycleHelper(ner_engine)
self._extraction_helper = _ExtractionHelper(ner_engine, self._model_helper)
async def extract_entities(
self,
@@ -93,7 +177,7 @@ class NerService:
ValueError: If meeting not found or has no segments.
RuntimeError: If NER feature is disabled.
"""
self._check_feature_enabled()
_check_feature_enabled()
# Check cache and get segments in one transaction
cached_or_segments = await self._get_cached_or_segments(meeting_id, force_refresh)
@@ -103,7 +187,7 @@ class NerService:
segments = cached_or_segments
# Extract and persist
entities = await self._extract_with_lock(segments)
entities = await self._extraction_helper.extract(segments)
for entity in entities:
entity.meeting_id = meeting_id
@@ -117,11 +201,6 @@ class NerService:
)
return ExtractionResult(entities=entities, cached=False, total_count=len(entities))
def _check_feature_enabled(self) -> None:
"""Raise if NER feature is disabled."""
if not get_feature_flags().ner_enabled:
raise RuntimeError("NER extraction is disabled by feature flag")
async def _get_cached_or_segments(
self,
meeting_id: MeetingId,
@@ -130,7 +209,7 @@ class NerService:
"""Check cache and return cached result or segments for extraction."""
async with self._uow_factory() as uow:
# Check cache first (unless force_refresh)
if cached_result := await self._try_get_cached(uow, meeting_id, force_refresh):
if cached_result := await _try_get_cached(uow, meeting_id, force_refresh):
return cached_result
# Validate meeting exists
@@ -139,34 +218,7 @@ class NerService:
raise ValueError(f"{ERROR_MSG_MEETING_PREFIX}{meeting_id} not found")
# Load segments (not eagerly loaded on meeting)
return await self._load_segments_or_empty(uow, meeting_id)
async def _try_get_cached(
self,
uow: SqlAlchemyUnitOfWork,
meeting_id: MeetingId,
force_refresh: bool,
) -> ExtractionResult | None:
"""Return cached result if available and not forcing refresh."""
if force_refresh:
return None
cached = await uow.entities.get_by_meeting(meeting_id)
if not cached:
return None
logger.debug("Returning %d cached entities for meeting %s", len(cached), meeting_id)
return ExtractionResult(entities=cached, cached=True, total_count=len(cached))
async def _load_segments_or_empty(
self,
uow: SqlAlchemyUnitOfWork,
meeting_id: MeetingId,
) -> ExtractionResult | list[tuple[int, str]]:
"""Load segments for extraction or return empty result."""
segments = await uow.segments.get_by_meeting(meeting_id)
if not segments:
logger.debug("Meeting %s has no segments", meeting_id)
return ExtractionResult(entities=[], cached=False, total_count=0)
return [(s.segment_id, s.text) for s in segments]
return await _load_segments_or_empty(uow, meeting_id)
async def _persist_entities(
self,
@@ -181,58 +233,6 @@ class NerService:
await uow.entities.save_batch(entities)
await uow.commit()
async def _extract_with_lock(
self,
segments: list[tuple[int, str]],
) -> list[NamedEntity]:
"""Extract entities with concurrency control.
Ensures only one extraction runs at a time and handles
lazy model loading safely.
Args:
segments: List of (segment_id, text) tuples.
Returns:
List of extracted entities.
"""
async with self._extraction_lock:
await self._ensure_model_ready()
return await self._extract_entities(segments)
async def _ensure_model_ready(self) -> None:
"""Ensure the NER model is loaded and warmed up safely."""
if self._ner_engine.is_ready():
return
async with self._model_load_lock:
if self._ner_engine.is_ready():
return
await self._warmup_model()
async def _warmup_model(self) -> None:
"""Warm up the NER model with a simple extraction."""
loop = asyncio.get_running_loop()
with log_timing("ner_warmup"):
await loop.run_in_executor(
None,
lambda: self._ner_engine.extract("warm up"),
)
async def _extract_entities(
self,
segments: list[tuple[int, str]],
) -> list[NamedEntity]:
"""Extract entities in an executor (CPU-bound)."""
loop = asyncio.get_running_loop()
segment_count = len(segments)
with log_timing("ner_extraction", segment_count=segment_count):
entities = await loop.run_in_executor(
None,
self._ner_engine.extract_from_segments,
segments,
)
return entities
async def get_entities(self, meeting_id: MeetingId) -> Sequence[NamedEntity]:
"""Get cached entities for a meeting (no extraction).
@@ -298,3 +298,39 @@ class NerService:
True if the engine is ready and NER is enabled.
"""
return get_feature_flags().ner_enabled and self._ner_engine.is_ready()
# --- Module-level helper functions ---
def _check_feature_enabled() -> None:
"""Raise if NER feature is disabled."""
if not get_feature_flags().ner_enabled:
raise RuntimeError("NER extraction is disabled by feature flag")
async def _try_get_cached(
uow: SqlAlchemyUnitOfWork,
meeting_id: MeetingId,
force_refresh: bool,
) -> ExtractionResult | None:
"""Return cached result if available and not forcing refresh."""
if force_refresh:
return None
cached = await uow.entities.get_by_meeting(meeting_id)
if not cached:
return None
logger.debug("Returning %d cached entities for meeting %s", len(cached), meeting_id)
return ExtractionResult(entities=cached, cached=True, total_count=len(cached))
async def _load_segments_or_empty(
uow: SqlAlchemyUnitOfWork,
meeting_id: MeetingId,
) -> ExtractionResult | list[tuple[int, str]]:
"""Load segments for extraction or return empty result."""
segments = await uow.segments.get_by_meeting(meeting_id)
if not segments:
logger.debug("Meeting %s has no segments", meeting_id)
return ExtractionResult(entities=[], cached=False, total_count=0)
return [(s.segment_id, s.text) for s in segments]

View File

@@ -14,8 +14,8 @@ from typing import TYPE_CHECKING, ClassVar
import sqlalchemy.exc
from noteflow.domain.constants.fields import ASSET_PATH, UNKNOWN
from noteflow.infrastructure.audio.constants import ENCRYPTED_AUDIO_FILENAME
from noteflow.domain.value_objects import MeetingState
from noteflow.infrastructure.audio.constants import ENCRYPTED_AUDIO_FILENAME
from noteflow.infrastructure.logging import get_logger, log_state_transition
from noteflow.infrastructure.persistence.constants import MAX_MEETINGS_LIMIT
@@ -58,6 +58,112 @@ class _RecoveryValidation:
previous_state: MeetingState
class _AudioValidator:
"""Validate audio file integrity for meetings."""
def __init__(self, meetings_dir: Path | None) -> None:
"""Initialize audio validator.
Args:
meetings_dir: Base directory for meeting audio files.
"""
self._meetings_dir = meetings_dir
def validate(self, meeting: Meeting) -> AudioValidationResult:
"""Validate audio files for a crashed meeting.
Check that manifest.json and audio.enc exist in the meeting directory.
Args:
meeting: Meeting to validate.
Returns:
AudioValidationResult with validation status.
"""
if self._meetings_dir is None:
return AudioValidationResult(
is_valid=True,
manifest_exists=True,
audio_exists=True,
error_message="Audio validation skipped (no meetings_dir configured)",
)
meeting_dir = _resolve_meeting_dir(meeting, self._meetings_dir)
manifest_exists = (meeting_dir / "manifest.json").exists()
audio_exists = (meeting_dir / ENCRYPTED_AUDIO_FILENAME).exists()
return _build_validation_result(manifest_exists, audio_exists)
class _MeetingRecoverer:
"""Handle recovery of crashed meetings."""
def __init__(self, audio_validator: _AudioValidator) -> None:
"""Initialize meeting recoverer.
Args:
audio_validator: Validator for meeting audio files.
"""
self._audio_validator = audio_validator
def recover_meeting(
self,
meeting: Meeting,
recovery_time: str,
) -> _RecoveryValidation:
"""Apply crash recovery updates to a single meeting."""
previous_state = meeting.state
meeting.mark_error()
log_state_transition(
"meeting",
str(meeting.id),
previous_state,
meeting.state,
reason="crash_recovery",
)
_set_recovery_metadata(meeting, recovery_time, previous_state)
validation = self._audio_validator.validate(meeting)
_set_validation_metadata(meeting, validation)
return _RecoveryValidation(
is_valid=validation.is_valid,
previous_state=previous_state,
)
class _DiarizationJobRecoverer:
"""Handle recovery of crashed diarization jobs."""
def __init__(self, uow: UnitOfWork) -> None:
"""Initialize diarization job recoverer.
Args:
uow: Unit of work for persistence.
"""
self._uow = uow
async def recover(self) -> int:
"""Mark diarization jobs left in running states as failed.
Returns:
Number of jobs marked as failed.
"""
try:
return await self._mark_jobs_failed()
except sqlalchemy.exc.ProgrammingError as e:
return _handle_missing_diarization_table(e)
async def _mark_jobs_failed(self) -> int:
"""Mark running diarization jobs as failed and log result."""
async with self._uow:
failed_count = await self._uow.diarization_jobs.mark_running_as_failed()
await self._uow.commit()
_log_diarization_recovery(failed_count)
return failed_count
class RecoveryService:
"""Recover meetings from crash states on server startup.
@@ -85,77 +191,28 @@ class RecoveryService:
If provided, validates that audio files exist for crashed meetings.
"""
self._uow = uow
self._meetings_dir = meetings_dir
self._audio_validator = _AudioValidator(meetings_dir)
self._meeting_recoverer = _MeetingRecoverer(self._audio_validator)
self._job_recoverer = _DiarizationJobRecoverer(uow)
def validate_meeting_audio(self, meeting: Meeting) -> AudioValidationResult:
"""Validate audio files for a crashed meeting.
Check that manifest.json and audio.enc exist in the meeting directory.
Args:
meeting: Meeting to validate.
Returns:
AudioValidationResult with validation status.
"""
if self._meetings_dir is None:
return AudioValidationResult(
is_valid=True,
manifest_exists=True,
audio_exists=True,
error_message="Audio validation skipped (no meetings_dir configured)",
logger.debug("Validating audio for meeting %s", meeting.id)
result = self._audio_validator.validate(meeting)
if not result.is_valid:
logger.warning(
"Audio validation failed for meeting %s: %s",
meeting.id,
result.error_message,
)
meeting_dir = self._resolve_meeting_dir(meeting, self._meetings_dir)
manifest_exists = (meeting_dir / "manifest.json").exists()
audio_exists = (meeting_dir / ENCRYPTED_AUDIO_FILENAME).exists()
return self._build_validation_result(manifest_exists, audio_exists)
@staticmethod
def _resolve_meeting_dir(meeting: Meeting, base_dir: Path) -> Path:
"""Resolve the directory path for a meeting's audio files."""
default_path = str(meeting.id)
asset_path = meeting.asset_path or default_path
if asset_path == default_path:
asset_path = meeting.metadata.get(ASSET_PATH) or asset_path
return base_dir / asset_path
@staticmethod
def _build_validation_result(
manifest_exists: bool,
audio_exists: bool,
) -> AudioValidationResult:
"""Build validation result from file existence checks."""
if not manifest_exists and not audio_exists:
return AudioValidationResult(
is_valid=False,
manifest_exists=False,
audio_exists=False,
error_message="Meeting directory missing or empty",
)
if not manifest_exists:
return AudioValidationResult(
is_valid=False,
manifest_exists=False,
audio_exists=audio_exists,
error_message="manifest.json not found",
)
if not audio_exists:
return AudioValidationResult(
is_valid=False,
manifest_exists=True,
audio_exists=False,
error_message=f"{ENCRYPTED_AUDIO_FILENAME} not found",
)
return AudioValidationResult(
is_valid=True,
manifest_exists=True,
audio_exists=True,
)
return result
async def recover_crashed_meetings(self) -> tuple[list[Meeting], int]:
"""Find and recover meetings left in active states.
@@ -202,75 +259,15 @@ class RecoveryService:
recovery_time = datetime.now(UTC).isoformat()
for meeting in meetings:
validation = self._recover_meeting(meeting, recovery_time)
validation = self._meeting_recoverer.recover_meeting(meeting, recovery_time)
if not validation.is_valid:
audio_failures += 1
await self._uow.meetings.update(meeting)
recovered.append(meeting)
self._log_meeting_recovery(meeting, validation)
_log_meeting_recovery(meeting, validation)
return recovered, audio_failures
@staticmethod
def _log_meeting_recovery(meeting: Meeting, validation: _RecoveryValidation) -> None:
"""Log successful meeting recovery."""
logger.info(
"Recovered crashed meeting: id=%s, previous_state=%s, audio_valid=%s",
meeting.id,
validation.previous_state,
validation.is_valid,
)
def _recover_meeting(
self, meeting: Meeting, recovery_time: str
) -> _RecoveryValidation:
"""Apply crash recovery updates to a single meeting."""
previous_state = meeting.state
meeting.mark_error()
log_state_transition(
"meeting",
str(meeting.id),
previous_state,
meeting.state,
reason="crash_recovery",
)
self._set_recovery_metadata(meeting, recovery_time, previous_state)
validation = self.validate_meeting_audio(meeting)
self._set_validation_metadata(meeting, validation)
return _RecoveryValidation(
is_valid=validation.is_valid,
previous_state=previous_state,
)
@staticmethod
def _set_recovery_metadata(
meeting: Meeting,
recovery_time: str,
previous_state: MeetingState,
) -> None:
"""Set crash recovery metadata on meeting."""
meeting.metadata["crash_recovered"] = "true"
meeting.metadata["crash_recovery_time"] = recovery_time
meeting.metadata["crash_previous_state"] = previous_state.name
@staticmethod
def _set_validation_metadata(
meeting: Meeting,
validation: AudioValidationResult,
) -> None:
"""Set audio validation metadata on meeting."""
meeting.metadata["audio_valid"] = str(validation.is_valid).lower()
if not validation.is_valid:
meeting.metadata["audio_error"] = validation.error_message or UNKNOWN
logger.warning(
"Audio validation failed for meeting %s: %s",
meeting.id,
validation.error_message,
)
async def count_crashed_meetings(self) -> int:
"""Count meetings currently in crash states.
@@ -286,47 +283,10 @@ class RecoveryService:
async def recover_crashed_diarization_jobs(self) -> int:
"""Mark diarization jobs left in running states as failed.
Find all diarization jobs in QUEUED or RUNNING state and mark them
as FAILED with an error message explaining the crash recovery.
Returns:
Number of jobs marked as failed.
"""
try:
return await self._mark_diarization_jobs_failed()
except sqlalchemy.exc.ProgrammingError as e:
return self._handle_missing_diarization_table(e)
async def _mark_diarization_jobs_failed(self) -> int:
"""Mark running diarization jobs as failed and log result."""
async with self._uow:
failed_count = await self._uow.diarization_jobs.mark_running_as_failed()
await self._uow.commit()
self._log_diarization_recovery(failed_count)
return failed_count
@staticmethod
def _log_diarization_recovery(failed_count: int) -> None:
"""Log diarization job recovery result."""
if failed_count > 0:
logger.warning(
"Marked %d diarization jobs as failed during crash recovery",
failed_count,
)
else:
logger.info("No crashed diarization jobs found during recovery")
@staticmethod
def _handle_missing_diarization_table(error: sqlalchemy.exc.ProgrammingError) -> int:
"""Handle case where diarization_jobs table doesn't exist yet."""
if "does not exist" in str(error) or "UndefinedTableError" in str(error):
logger.debug(
"Diarization jobs table not found during recovery, skipping: %s",
error,
)
return 0
raise error
return await self._job_recoverer.recover()
async def recover_all(self) -> RecoveryResult:
"""Run all crash recovery operations.
@@ -354,3 +314,109 @@ class RecoveryService:
)
return result
# --- Module-level helper functions ---
def _resolve_meeting_dir(meeting: Meeting, base_dir: Path) -> Path:
"""Resolve the directory path for a meeting's audio files."""
default_path = str(meeting.id)
asset_path = meeting.asset_path or default_path
if asset_path == default_path:
asset_path = meeting.metadata.get(ASSET_PATH) or asset_path
return base_dir / asset_path
def _build_validation_result(
manifest_exists: bool,
audio_exists: bool,
) -> AudioValidationResult:
"""Build validation result from file existence checks."""
if not manifest_exists and not audio_exists:
return AudioValidationResult(
is_valid=False,
manifest_exists=False,
audio_exists=False,
error_message="Meeting directory missing or empty",
)
if not manifest_exists:
return AudioValidationResult(
is_valid=False,
manifest_exists=False,
audio_exists=audio_exists,
error_message="manifest.json not found",
)
if not audio_exists:
return AudioValidationResult(
is_valid=False,
manifest_exists=True,
audio_exists=False,
error_message=f"{ENCRYPTED_AUDIO_FILENAME} not found",
)
return AudioValidationResult(
is_valid=True,
manifest_exists=True,
audio_exists=True,
)
def _set_recovery_metadata(
meeting: Meeting,
recovery_time: str,
previous_state: MeetingState,
) -> None:
"""Set crash recovery metadata on meeting."""
meeting.metadata["crash_recovered"] = "true"
meeting.metadata["crash_recovery_time"] = recovery_time
meeting.metadata["crash_previous_state"] = previous_state.name
def _set_validation_metadata(
meeting: Meeting,
validation: AudioValidationResult,
) -> None:
"""Set audio validation metadata on meeting."""
meeting.metadata["audio_valid"] = str(validation.is_valid).lower()
if not validation.is_valid:
meeting.metadata["audio_error"] = validation.error_message or UNKNOWN
logger.warning(
"Audio validation failed for meeting %s: %s",
meeting.id,
validation.error_message,
)
def _log_meeting_recovery(meeting: Meeting, validation: _RecoveryValidation) -> None:
"""Log successful meeting recovery."""
logger.info(
"Recovered crashed meeting: id=%s, previous_state=%s, audio_valid=%s",
meeting.id,
validation.previous_state,
validation.is_valid,
)
def _log_diarization_recovery(failed_count: int) -> None:
"""Log diarization job recovery result."""
if failed_count > 0:
logger.warning(
"Marked %d diarization jobs as failed during crash recovery",
failed_count,
)
else:
logger.info("No crashed diarization jobs found during recovery")
def _handle_missing_diarization_table(error: sqlalchemy.exc.ProgrammingError) -> int:
"""Handle case where diarization_jobs table doesn't exist yet."""
if "does not exist" in str(error) or "UndefinedTableError" in str(error):
logger.debug(
"Diarization jobs table not found during recovery, skipping: %s",
error,
)
return 0
raise error

View File

@@ -0,0 +1,21 @@
"""Summarization service package."""
from __future__ import annotations
from .summarization_service import (
ConsentPersistCallback,
PersistCallback,
SummarizationMode,
SummarizationService,
SummarizationServiceResult,
SummarizationServiceSettings,
)
__all__ = [
"ConsentPersistCallback",
"PersistCallback",
"SummarizationMode",
"SummarizationService",
"SummarizationServiceResult",
"SummarizationServiceSettings",
]

View File

@@ -0,0 +1,70 @@
"""Citation verification and filtering for summaries."""
from __future__ import annotations
from typing import TYPE_CHECKING
from noteflow.infrastructure.logging import get_logger
if TYPE_CHECKING:
from collections.abc import Sequence
from noteflow.domain.entities import Segment, Summary
from noteflow.domain.summarization import CitationVerifier
from .summarization_service import SummarizationServiceResult, SummarizationServiceSettings
logger = get_logger(__name__)
class CitationHelper:
"""Manage citation verification and filtering."""
def __init__(self, settings: "SummarizationServiceSettings") -> None:
self._settings = settings
self._verifier: CitationVerifier | None = None
@property
def verifier(self) -> CitationVerifier | None:
"""Get the current citation verifier."""
return self._verifier
def set_verifier(self, verifier: CitationVerifier) -> None:
"""Set the citation verifier.
Args:
verifier: Citation verifier implementation.
"""
self._verifier = verifier
def filter_citations(self, summary: Summary, segments: list[Segment]) -> Summary:
"""Filter invalid citations from summary.
Args:
summary: Summary to filter.
segments: Available segments.
Returns:
Summary with invalid citations removed.
"""
if self._verifier is None:
return summary
return self._verifier.filter_invalid_citations(summary, segments)
def apply_verification(
self, service_result: "SummarizationServiceResult", segments: "Sequence[Segment]"
) -> None:
"""Apply citation verification and filtering if enabled."""
if not self._settings.verify_citations or self._verifier is None:
return
verification = self._verifier.verify_citations(
service_result.result.summary, list(segments)
)
service_result.verification = verification
if not verification.is_valid:
logger.warning("Summary has %d invalid citations", verification.invalid_count)
if self._settings.filter_invalid_citations:
service_result.filtered_summary = self.filter_citations(
service_result.result.summary, list(segments)
)

View File

@@ -0,0 +1,47 @@
"""Consent management for cloud summarization."""
from __future__ import annotations
from typing import TYPE_CHECKING
from noteflow.infrastructure.logging import get_logger
if TYPE_CHECKING:
from .summarization_service import ConsentPersistCallback, SummarizationServiceSettings
logger = get_logger(__name__)
class ConsentManager:
"""Manage cloud consent state and persistence."""
def __init__(
self,
settings: "SummarizationServiceSettings",
on_consent_change: "ConsentPersistCallback | None",
) -> None:
self._settings = settings
self._on_consent_change = on_consent_change
@property
def granted(self) -> bool:
"""Return whether cloud consent is currently granted."""
return self._settings.cloud_consent_granted
def set_callback(self, callback: "ConsentPersistCallback | None") -> None:
"""Set the consent change callback."""
self._on_consent_change = callback
async def grant(self) -> None:
"""Grant consent for cloud processing."""
self._settings.cloud_consent_granted = True
logger.info("Cloud consent granted")
if self._on_consent_change:
await self._on_consent_change(True)
async def revoke(self) -> None:
"""Revoke consent for cloud processing."""
self._settings.cloud_consent_granted = False
logger.info("Cloud consent revoked")
if self._on_consent_change:
await self._on_consent_change(False)

View File

@@ -0,0 +1,123 @@
"""Provider registry for summarization modes."""
from __future__ import annotations
from typing import TYPE_CHECKING
from noteflow.domain.summarization import ProviderUnavailableError
from noteflow.infrastructure.logging import get_logger
if TYPE_CHECKING:
from noteflow.domain.summarization import SummarizerProvider
from .summarization_service import SummarizationMode, SummarizationServiceSettings
logger = get_logger(__name__)
class ProviderRegistry:
"""Manage provider registration and availability."""
def __init__(
self,
providers: "dict[SummarizationMode, SummarizerProvider]",
settings: "SummarizationServiceSettings",
) -> None:
self._providers = providers
self._settings = settings
def register(self, mode: "SummarizationMode", provider: "SummarizerProvider") -> None:
"""Register a provider for a specific mode.
Args:
mode: The mode this provider handles.
provider: The provider implementation.
"""
self._providers[mode] = provider
logger.debug("Registered %s provider: %s", mode.value, provider.provider_name)
def get_available_modes(self) -> "list[SummarizationMode]":
"""Get list of currently available summarization modes.
Returns:
List of available modes based on registered providers.
"""
return [mode for mode in self._providers if self.is_mode_available(mode)]
def is_mode_available(self, mode: "SummarizationMode") -> bool:
"""Check if a specific mode is available.
Args:
mode: The mode to check.
Returns:
True if mode is available (provider exists, available, and consent satisfied).
"""
provider = self._providers.get(mode)
if provider is None or not provider.is_available:
return False
if mode == SummarizationMode.CLOUD:
return self._settings.cloud_consent_granted
return True
def get_provider_with_fallback(
self, mode: "SummarizationMode"
) -> "tuple[SummarizerProvider, SummarizationMode]":
"""Get provider for mode, with fallback if unavailable.
Args:
mode: Requested mode.
Returns:
Tuple of (provider, actual_mode).
Raises:
ProviderUnavailableError: If no provider available.
"""
if mode not in self._providers:
raise ProviderUnavailableError(f"No provider available for mode: {mode.value}")
provider = self._providers[mode]
# Cloud mode requires consent check
if mode == SummarizationMode.CLOUD and not self._settings.cloud_consent_granted:
logger.warning("Cloud mode requested but consent not granted")
if not self._settings.fallback_to_local:
raise ProviderUnavailableError("Cloud consent not granted")
return self._get_fallback_provider(mode)
if provider.is_available:
return provider, mode
# Provider exists but unavailable - try fallback
if self._settings.fallback_to_local and mode != SummarizationMode.MOCK:
return self._get_fallback_provider(mode)
raise ProviderUnavailableError(f"No provider available for mode: {mode.value}")
def _get_fallback_provider(
self, original_mode: "SummarizationMode"
) -> "tuple[SummarizerProvider, SummarizationMode]":
"""Get fallback provider when primary unavailable.
Fallback order: LOCAL -> MOCK
Args:
original_mode: The mode that was unavailable.
Returns:
Tuple of (provider, mode).
Raises:
ProviderUnavailableError: If no fallback available.
"""
fallback_order = [SummarizationMode.LOCAL, SummarizationMode.MOCK]
for fallback_mode in fallback_order:
if fallback_mode == original_mode:
continue
provider = self._providers.get(fallback_mode)
if provider is not None and provider.is_available:
return provider, fallback_mode
raise ProviderUnavailableError("No fallback provider available")

View File

@@ -0,0 +1,312 @@
"""Summarization orchestration service.
Coordinate provider selection, consent handling, and citation verification.
"""
from __future__ import annotations
from collections.abc import Awaitable, Callable
from dataclasses import dataclass, field
from enum import Enum
from typing import TYPE_CHECKING, TypedDict, Unpack
from noteflow.application.observability.ports import (
NullUsageEventSink,
UsageEventSink,
UsageMetrics,
)
from noteflow.domain.summarization import (
DEFAULT_MAX_ACTION_ITEMS,
DEFAULT_MAX_KEY_POINTS,
CitationVerificationResult,
SummarizationRequest,
SummarizationResult,
)
from noteflow.infrastructure.logging import get_logger
from ._citation_helper import CitationHelper
from ._consent_manager import ConsentManager
from ._provider_registry import ProviderRegistry
# Type aliases must be defined at runtime for re-export
PersistCallback = Callable[["Summary"], Awaitable[None]]
ConsentPersistCallback = Callable[[bool], Awaitable[None]]
if TYPE_CHECKING:
from collections.abc import Sequence
from noteflow.domain.entities import Segment, Summary
from noteflow.domain.summarization import CitationVerifier, SummarizerProvider
from noteflow.domain.value_objects import MeetingId
logger = get_logger(__name__)
class _SummarizationOptionsKwargs(TypedDict, total=False):
"""Optional overrides for summarization behavior."""
mode: SummarizationMode | None
max_key_points: int | None
max_action_items: int | None
style_prompt: str | None
class SummarizationMode(Enum):
"""Available summarization modes."""
MOCK = "mock"
LOCAL = "local" # Ollama
CLOUD = "cloud" # OpenAI/Anthropic
@dataclass
class SummarizationServiceSettings:
"""Configuration for summarization service.
Attributes:
default_mode: Default summarization mode.
cloud_consent_granted: Whether user has consented to cloud processing.
fallback_to_local: Fall back to local if cloud unavailable.
verify_citations: Whether to verify citations after summarization.
filter_invalid_citations: Remove invalid citations from result.
max_key_points: Default maximum key points.
max_action_items: Default maximum action items.
"""
default_mode: SummarizationMode = SummarizationMode.LOCAL
cloud_consent_granted: bool = False
fallback_to_local: bool = True
verify_citations: bool = True
filter_invalid_citations: bool = True
max_key_points: int = DEFAULT_MAX_KEY_POINTS
max_action_items: int = DEFAULT_MAX_ACTION_ITEMS
@dataclass(frozen=True)
class _SummarizationContext:
"""Context for summarization execution (for metrics and logging)."""
meeting_id: MeetingId
segment_count: int
fallback_used: bool
@dataclass
class SummarizationServiceResult:
"""Result from summarization service.
Attributes:
result: The raw summarization result from the provider.
verification: Citation verification result (if verification enabled).
filtered_summary: Summary with invalid citations removed (if filtering enabled).
provider_used: Which provider was actually used.
fallback_used: Whether a fallback provider was used.
"""
result: SummarizationResult
verification: CitationVerificationResult | None = None
filtered_summary: Summary | None = None
provider_used: str = ""
fallback_used: bool = False
@property
def summary(self) -> Summary:
"""Get the best available summary (filtered if available)."""
return self.filtered_summary or self.result.summary
@property
def has_invalid_citations(self) -> bool:
"""Check if summary has invalid citations."""
return self.verification is not None and not self.verification.is_valid
# ---------------------------------------------------------------------------
# Main Service
# ---------------------------------------------------------------------------
@dataclass
class SummarizationService:
"""Orchestrate summarization with provider selection and citation verification.
Manages provider selection based on mode and availability, handles
cloud consent requirements, and verifies/filters citation integrity.
"""
providers: dict[SummarizationMode, SummarizerProvider] = field(default_factory=dict)
verifier: CitationVerifier | None = None
settings: SummarizationServiceSettings = field(default_factory=SummarizationServiceSettings)
on_persist: PersistCallback | None = None
on_consent_change: ConsentPersistCallback | None = None
usage_events: UsageEventSink = field(default_factory=NullUsageEventSink)
# Helper instances (initialized in __post_init__)
_consent: ConsentManager = field(init=False, repr=False)
_registry: ProviderRegistry = field(init=False, repr=False)
_citations: CitationHelper = field(init=False, repr=False)
def __post_init__(self) -> None:
"""Initialize helper classes after dataclass initialization."""
self._consent = ConsentManager(self.settings, self.on_consent_change)
self._registry = ProviderRegistry(self.providers, self.settings)
self._citations = CitationHelper(self.settings)
if self.verifier is not None:
self._citations.set_verifier(self.verifier)
# --- Delegated properties and methods ---
@property
def registry(self) -> ProviderRegistry:
"""Access provider registry for mode queries."""
return self._registry
@property
def citations(self) -> CitationHelper:
"""Access citation helper for filtering."""
return self._citations
async def grant_cloud_consent(self) -> None:
"""Grant consent for cloud processing."""
await self._consent.grant()
async def revoke_cloud_consent(self) -> None:
"""Revoke consent for cloud processing."""
await self._consent.revoke()
def register_provider(self, mode: SummarizationMode, provider: SummarizerProvider) -> None:
"""Register a provider for a specific mode."""
self._registry.register(mode, provider)
def set_verifier(self, verifier: CitationVerifier) -> None:
"""Set the citation verifier."""
self._citations.set_verifier(verifier)
self.verifier = verifier
# --- Core methods ---
async def summarize(
self,
meeting_id: MeetingId,
segments: Sequence[Segment],
**kwargs: Unpack[_SummarizationOptionsKwargs],
) -> SummarizationServiceResult:
"""Generate evidence-linked summary for meeting transcript.
Args:
meeting_id: The meeting ID.
segments: Transcript segments to summarize.
**kwargs: Optional overrides (mode, max_key_points, max_action_items, style_prompt).
Returns:
SummarizationServiceResult with summary and verification.
Raises:
SummarizationError: If summarization fails and no fallback available.
ProviderUnavailableError: If no provider is available for the mode.
"""
request = self._build_request(meeting_id, segments, kwargs)
provider, fallback_used = self._resolve_provider(kwargs.get("mode"))
context = _SummarizationContext(
meeting_id=meeting_id,
segment_count=len(segments),
fallback_used=fallback_used,
)
result = await self._execute_summarization(provider, request, context)
service_result = SummarizationServiceResult(
result=result, provider_used=provider.provider_name, fallback_used=fallback_used
)
self._citations.apply_verification(service_result, segments)
await self._persist_if_configured(service_result, meeting_id)
return service_result
def _build_request(
self,
meeting_id: MeetingId,
segments: Sequence[Segment],
options: _SummarizationOptionsKwargs,
) -> SummarizationRequest:
"""Build summarization request from meeting data and options."""
return SummarizationRequest(
meeting_id=meeting_id,
segments=segments,
max_key_points=options.get("max_key_points") or self.settings.max_key_points,
max_action_items=options.get("max_action_items") or self.settings.max_action_items,
style_prompt=options.get("style_prompt"),
)
def _resolve_provider(
self, mode: SummarizationMode | None
) -> tuple[SummarizerProvider, bool]:
"""Resolve provider and determine if fallback was used."""
target_mode = mode or self.settings.default_mode
provider, actual_mode = self._registry.get_provider_with_fallback(target_mode)
fallback_used = actual_mode != target_mode
if fallback_used:
logger.info("Falling back from %s to %s mode", target_mode.value, actual_mode.value)
return provider, fallback_used
async def _execute_summarization(
self,
provider: SummarizerProvider,
request: SummarizationRequest,
context: _SummarizationContext,
) -> SummarizationResult:
"""Execute summarization and emit usage event."""
logger.info(
"Summarizing %d segments with %s provider",
context.segment_count,
provider.provider_name,
)
result = await provider.summarize(request)
# Transfer timing info to summary
summary = result.summary
summary.tokens_used = result.tokens_used
summary.latency_ms = result.latency_ms
# Emit usage event
self._record_usage(result, context)
return result
def _record_usage(
self,
result: SummarizationResult,
context: _SummarizationContext,
) -> None:
"""Record usage metrics for observability."""
self.usage_events.record_simple(
"summarization.completed",
UsageMetrics(
provider_name=result.provider_name,
model_name=result.model_name,
tokens_input=result.tokens_used,
latency_ms=result.latency_ms,
),
meeting_id=str(context.meeting_id),
success=True,
segment_count=context.segment_count,
fallback_used=context.fallback_used,
)
async def _persist_if_configured(
self, service_result: SummarizationServiceResult, meeting_id: MeetingId
) -> None:
"""Persist summary if callback is configured."""
if self.on_persist is not None:
await self.on_persist(service_result.summary)
logger.debug("Summary persisted for meeting %s", meeting_id)
def set_default_mode(self, mode: SummarizationMode) -> None:
"""Set the default summarization mode.
Args:
mode: New default mode.
"""
self.settings.default_mode = mode
logger.info("Default summarization mode set to %s", mode.value)
def set_persist_callback(self, callback: PersistCallback | None) -> None:
"""Set callback for persisting summaries after generation.
Args:
callback: Async function that persists a Summary, or None to disable.
"""
self.on_persist = callback

View File

@@ -1,367 +0,0 @@
"""Summarization orchestration service.
Coordinate provider selection, consent handling, and citation verification.
"""
from __future__ import annotations
from dataclasses import dataclass, field
from enum import Enum
from typing import TYPE_CHECKING, TypedDict, Unpack
from noteflow.application.observability.ports import (
NullUsageEventSink,
UsageEventSink,
UsageMetrics,
)
from noteflow.domain.summarization import (
DEFAULT_MAX_ACTION_ITEMS,
DEFAULT_MAX_KEY_POINTS,
CitationVerificationResult,
ProviderUnavailableError,
SummarizationRequest,
SummarizationResult,
)
from noteflow.infrastructure.logging import get_logger
if TYPE_CHECKING:
from collections.abc import Awaitable, Callable, Sequence
from noteflow.domain.entities import Segment, Summary
from noteflow.domain.summarization import CitationVerifier, SummarizerProvider
from noteflow.domain.value_objects import MeetingId
# Type alias for persistence callback
PersistCallback = Callable[[Summary], Awaitable[None]]
# Type alias for consent persistence callback
ConsentPersistCallback = Callable[[bool], Awaitable[None]]
logger = get_logger(__name__)
class _SummarizationOptionsKwargs(TypedDict, total=False):
"""Optional overrides for summarization behavior."""
mode: SummarizationMode | None
max_key_points: int | None
max_action_items: int | None
style_prompt: str | None
class SummarizationMode(Enum):
"""Available summarization modes."""
MOCK = "mock"
LOCAL = "local" # Ollama
CLOUD = "cloud" # OpenAI/Anthropic
@dataclass
class SummarizationServiceSettings:
"""Configuration for summarization service.
Attributes:
default_mode: Default summarization mode.
cloud_consent_granted: Whether user has consented to cloud processing.
fallback_to_local: Fall back to local if cloud unavailable.
verify_citations: Whether to verify citations after summarization.
filter_invalid_citations: Remove invalid citations from result.
max_key_points: Default maximum key points.
max_action_items: Default maximum action items.
"""
default_mode: SummarizationMode = SummarizationMode.LOCAL
cloud_consent_granted: bool = False
fallback_to_local: bool = True
verify_citations: bool = True
filter_invalid_citations: bool = True
max_key_points: int = DEFAULT_MAX_KEY_POINTS
max_action_items: int = DEFAULT_MAX_ACTION_ITEMS
@dataclass
class SummarizationServiceResult:
"""Result from summarization service.
Attributes:
result: The raw summarization result from the provider.
verification: Citation verification result (if verification enabled).
filtered_summary: Summary with invalid citations removed (if filtering enabled).
provider_used: Which provider was actually used.
fallback_used: Whether a fallback provider was used.
"""
result: SummarizationResult
verification: CitationVerificationResult | None = None
filtered_summary: Summary | None = None
provider_used: str = ""
fallback_used: bool = False
@property
def summary(self) -> Summary:
"""Get the best available summary (filtered if available)."""
return self.filtered_summary or self.result.summary
@property
def has_invalid_citations(self) -> bool:
"""Check if summary has invalid citations."""
return self.verification is not None and not self.verification.is_valid
@dataclass
class SummarizationService:
"""Orchestrate summarization with provider selection and citation verification.
Manages provider selection based on mode and availability, handles
cloud consent requirements, and verifies/filters citation integrity.
"""
providers: dict[SummarizationMode, SummarizerProvider] = field(default_factory=dict)
verifier: CitationVerifier | None = None
settings: SummarizationServiceSettings = field(default_factory=SummarizationServiceSettings)
on_persist: PersistCallback | None = None
on_consent_change: ConsentPersistCallback | None = None
usage_events: UsageEventSink = field(default_factory=NullUsageEventSink)
@property
def cloud_consent_granted(self) -> bool:
"""Return whether cloud consent is currently granted."""
return self.settings.cloud_consent_granted
def register_provider(self, mode: SummarizationMode, provider: SummarizerProvider) -> None:
"""Register a provider for a specific mode.
Args:
mode: The mode this provider handles.
provider: The provider implementation.
"""
self.providers[mode] = provider
logger.debug("Registered %s provider: %s", mode.value, provider.provider_name)
def set_verifier(self, verifier: CitationVerifier) -> None:
"""Set the citation verifier.
Args:
verifier: Citation verifier implementation.
"""
self.verifier = verifier
def get_available_modes(self) -> list[SummarizationMode]:
"""Get list of currently available summarization modes.
Returns:
List of available modes based on registered providers.
"""
return [mode for mode in self.providers if self.is_mode_available(mode)]
def is_mode_available(self, mode: SummarizationMode) -> bool:
"""Check if a specific mode is available (provider exists, available, and consent satisfied).
Args:
mode: The mode to check.
Returns:
True if mode is available.
"""
provider = self.providers.get(mode)
if provider is None or not provider.is_available:
return False
if mode == SummarizationMode.CLOUD:
return self.settings.cloud_consent_granted
return True
async def grant_cloud_consent(self) -> None:
"""Grant consent for cloud processing."""
self.settings.cloud_consent_granted = True
logger.info("Cloud consent granted")
if self.on_consent_change:
await self.on_consent_change(True)
async def revoke_cloud_consent(self) -> None:
"""Revoke consent for cloud processing."""
self.settings.cloud_consent_granted = False
logger.info("Cloud consent revoked")
if self.on_consent_change:
await self.on_consent_change(False)
async def summarize(
self,
meeting_id: MeetingId,
segments: Sequence[Segment],
**kwargs: Unpack[_SummarizationOptionsKwargs],
) -> SummarizationServiceResult:
"""Generate evidence-linked summary for meeting transcript.
Args:
meeting_id: The meeting ID.
segments: Transcript segments to summarize.
**kwargs: Optional overrides (mode, max_key_points, max_action_items, style_prompt).
Returns:
SummarizationServiceResult with summary and verification.
Raises:
SummarizationError: If summarization fails and no fallback available.
ProviderUnavailableError: If no provider is available for the mode.
"""
mode = kwargs.get("mode")
max_key_points = kwargs.get("max_key_points")
max_action_items = kwargs.get("max_action_items")
style_prompt = kwargs.get("style_prompt")
target_mode = mode or self.settings.default_mode
provider, actual_mode = self._get_provider_with_fallback(target_mode)
fallback_used = actual_mode != target_mode
if fallback_used:
logger.info("Falling back from %s to %s mode", target_mode.value, actual_mode.value)
# Build and execute request
request = SummarizationRequest(
meeting_id=meeting_id,
segments=segments,
max_key_points=max_key_points or self.settings.max_key_points,
max_action_items=max_action_items or self.settings.max_action_items,
style_prompt=style_prompt,
)
logger.info("Summarizing %d segments with %s provider", len(segments), provider.provider_name)
result = await provider.summarize(request)
result.summary.tokens_used = result.tokens_used
result.summary.latency_ms = result.latency_ms
self._emit_usage_event(result, meeting_id, len(segments), fallback_used)
# Build and verify result
service_result = SummarizationServiceResult(
result=result, provider_used=provider.provider_name, fallback_used=fallback_used
)
self._apply_citation_verification(service_result, segments)
if self.on_persist is not None:
await self.on_persist(service_result.summary)
logger.debug("Summary persisted for meeting %s", meeting_id)
return service_result
def _emit_usage_event(
self, result: SummarizationResult, meeting_id: MeetingId, segment_count: int, fallback_used: bool
) -> None:
"""Emit usage event for observability."""
metrics = UsageMetrics(
provider_name=result.provider_name,
model_name=result.model_name,
tokens_input=result.tokens_used,
latency_ms=result.latency_ms,
)
self.usage_events.record_simple(
"summarization.completed",
metrics,
meeting_id=str(meeting_id),
success=True,
segment_count=segment_count,
fallback_used=fallback_used,
)
def _apply_citation_verification(
self, service_result: SummarizationServiceResult, segments: Sequence[Segment]
) -> None:
"""Apply citation verification and filtering if enabled."""
if not self.settings.verify_citations or self.verifier is None:
return
verification = self.verifier.verify_citations(service_result.result.summary, list(segments))
service_result.verification = verification
if not verification.is_valid:
logger.warning("Summary has %d invalid citations", verification.invalid_count)
if self.settings.filter_invalid_citations:
service_result.filtered_summary = self.filter_citations(
service_result.result.summary, list(segments)
)
def _get_provider_with_fallback(
self, mode: SummarizationMode
) -> tuple[SummarizerProvider, SummarizationMode]:
"""Get provider for mode, with fallback if unavailable.
Args:
mode: Requested mode.
Returns:
Tuple of (provider, actual_mode).
Raises:
ProviderUnavailableError: If no provider available.
"""
if mode not in self.providers:
raise ProviderUnavailableError(f"No provider available for mode: {mode.value}")
provider = self.providers[mode]
# Cloud mode requires consent check
if mode == SummarizationMode.CLOUD and not self.settings.cloud_consent_granted:
logger.warning("Cloud mode requested but consent not granted")
if not self.settings.fallback_to_local:
raise ProviderUnavailableError("Cloud consent not granted")
return self._get_fallback_provider(mode)
if provider.is_available:
return provider, mode
# Provider exists but unavailable - try fallback
if self.settings.fallback_to_local and mode != SummarizationMode.MOCK:
return self._get_fallback_provider(mode)
raise ProviderUnavailableError(f"No provider available for mode: {mode.value}")
def _get_fallback_provider(
self, original_mode: SummarizationMode
) -> tuple[SummarizerProvider, SummarizationMode]:
"""Get fallback provider when primary unavailable.
Fallback order: LOCAL -> MOCK
Args:
original_mode: The mode that was unavailable.
Returns:
Tuple of (provider, mode).
Raises:
ProviderUnavailableError: If no fallback available.
"""
fallback_order = [SummarizationMode.LOCAL, SummarizationMode.MOCK]
for fallback_mode in fallback_order:
if fallback_mode == original_mode:
continue
provider = self.providers.get(fallback_mode)
if provider is not None and provider.is_available:
return provider, fallback_mode
raise ProviderUnavailableError("No fallback provider available")
def filter_citations(self, summary: Summary, segments: list[Segment]) -> Summary:
"""Filter invalid citations from summary.
Args:
summary: Summary to filter.
segments: Available segments.
Returns:
Summary with invalid citations removed.
"""
if self.verifier is None:
return summary
return self.verifier.filter_invalid_citations(summary, segments)
def set_default_mode(self, mode: SummarizationMode) -> None:
"""Set the default summarization mode.
Args:
mode: New default mode.
"""
self.settings.default_mode = mode
logger.info("Default summarization mode set to %s", mode.value)
def set_persist_callback(self, callback: PersistCallback | None) -> None:
"""Set callback for persisting summaries after generation.
Args:
callback: Async function that persists a Summary, or None to disable.
"""
self.on_persist = callback

View File

@@ -1,15 +1,19 @@
"""Authentication domain entities and configuration."""
from noteflow.domain.auth.oidc import (
ClaimMapping,
OidcDiscoveryConfig,
OidcProviderConfig,
OidcProviderCreateParams,
OidcProviderPreset,
OidcProviderRegistration,
)
from noteflow.domain.auth.oidc_claims import ClaimMapping
from noteflow.domain.auth.oidc_discovery import OidcDiscoveryConfig
__all__ = [
"ClaimMapping",
"OidcDiscoveryConfig",
"OidcProviderConfig",
"OidcProviderCreateParams",
"OidcProviderPreset",
"OidcProviderRegistration",
]

View File

@@ -10,15 +10,11 @@ from __future__ import annotations
from dataclasses import dataclass, field
from datetime import datetime
from enum import StrEnum
from typing import NotRequired, Required, Self, TypedDict, Unpack, cast
from typing import NotRequired, Required, TypedDict, Unpack, cast
from uuid import UUID, uuid4
from noteflow.domain.auth.oidc_claims import ClaimMapping
from noteflow.domain.auth.oidc_constants import (
CLAIM_EMAIL,
CLAIM_EMAIL_VERIFIED,
CLAIM_GROUPS,
CLAIM_PICTURE,
CLAIM_PREFERRED_USERNAME,
FIELD_ALLOWED_GROUPS,
FIELD_CLAIM_MAPPING,
FIELD_DISCOVERY,
@@ -31,30 +27,22 @@ from noteflow.domain.auth.oidc_constants import (
OIDC_SCOPE_OPENID,
OIDC_SCOPE_PROFILE,
)
from noteflow.domain.constants.fields import (
END_SESSION_ENDPOINT,
INTROSPECTION_ENDPOINT,
JWKS_URI,
REVOCATION_ENDPOINT,
from noteflow.domain.auth.oidc_discovery import (
OidcDiscoveryConfig,
tuple_from_list,
tuple_from_list_or_default,
)
from noteflow.domain.utils.time import utc_now
def _tuple_from_list(value: object) -> tuple[str, ...]:
if isinstance(value, list):
items = cast(list[object], value)
return tuple(str(item) for item in items)
return ()
def _tuple_from_list_or_default(
value: object,
default: tuple[str, ...],
) -> tuple[str, ...]:
if isinstance(value, list):
items = cast(list[object], value)
return tuple(str(item) for item in items)
return default
# Re-export for backward compatibility
__all__ = [
"ClaimMapping",
"OidcDiscoveryConfig",
"OidcProviderConfig",
"OidcProviderCreateParams",
"OidcProviderPreset",
"OidcProviderRegistration",
]
class OidcProviderPreset(StrEnum):
@@ -69,142 +57,6 @@ class OidcProviderPreset(StrEnum):
CUSTOM = "custom"
@dataclass(frozen=True, slots=True)
class ClaimMapping:
"""Map OIDC claims to NoteFlow user attributes.
OIDC providers may use different claim names for user attributes.
This mapping allows configuring which claims to use for each attribute.
"""
# Standard OIDC claims with sensible defaults
subject_claim: str = "sub"
email_claim: str = CLAIM_EMAIL
email_verified_claim: str = CLAIM_EMAIL_VERIFIED
name_claim: str = "name"
preferred_username_claim: str = CLAIM_PREFERRED_USERNAME
groups_claim: str = CLAIM_GROUPS
picture_claim: str = CLAIM_PICTURE
# Optional custom claims
first_name_claim: str | None = None
last_name_claim: str | None = None
phone_claim: str | None = None
def as_dict(self) -> dict[str, str | None]:
"""Convert to dictionary for serialization."""
return {
"subject_claim": self.subject_claim,
"email_claim": self.email_claim,
"email_verified_claim": self.email_verified_claim,
"name_claim": self.name_claim,
"preferred_username_claim": self.preferred_username_claim,
"groups_claim": self.groups_claim,
"picture_claim": self.picture_claim,
"first_name_claim": self.first_name_claim,
"last_name_claim": self.last_name_claim,
"phone_claim": self.phone_claim,
}
@classmethod
def from_dict(cls, data: dict[str, str | None]) -> Self:
"""Create from dictionary."""
get = data.get
return cls(
subject_claim=get("subject_claim") or "sub",
email_claim=get("email_claim") or CLAIM_EMAIL,
email_verified_claim=get("email_verified_claim") or CLAIM_EMAIL_VERIFIED,
name_claim=get("name_claim") or "name",
preferred_username_claim=get("preferred_username_claim") or CLAIM_PREFERRED_USERNAME,
groups_claim=get("groups_claim") or CLAIM_GROUPS,
picture_claim=get("picture_claim") or CLAIM_PICTURE,
first_name_claim=get("first_name_claim"),
last_name_claim=get("last_name_claim"),
phone_claim=get("phone_claim"),
)
to_dict = as_dict
decode = from_dict
@dataclass(frozen=True, slots=True)
class OidcDiscoveryConfig:
"""OIDC discovery document fields.
These fields are populated from the provider's
`.well-known/openid-configuration` endpoint.
"""
issuer: str
authorization_endpoint: str
token_endpoint: str
userinfo_endpoint: str | None = None
jwks_uri: str | None = None
end_session_endpoint: str | None = None
revocation_endpoint: str | None = None
introspection_endpoint: str | None = None
scopes_supported: tuple[str, ...] = field(default_factory=tuple)
response_types_supported: tuple[str, ...] = field(default_factory=tuple)
grant_types_supported: tuple[str, ...] = field(default_factory=tuple)
claims_supported: tuple[str, ...] = field(default_factory=tuple)
code_challenge_methods_supported: tuple[str, ...] = field(default_factory=tuple)
def as_dict(self) -> dict[str, object]:
"""Convert to dictionary for serialization."""
return {
"issuer": self.issuer,
"authorization_endpoint": self.authorization_endpoint,
"token_endpoint": self.token_endpoint,
"userinfo_endpoint": self.userinfo_endpoint,
JWKS_URI: self.jwks_uri,
END_SESSION_ENDPOINT: self.end_session_endpoint,
REVOCATION_ENDPOINT: self.revocation_endpoint,
INTROSPECTION_ENDPOINT: self.introspection_endpoint,
"scopes_supported": list(self.scopes_supported),
"response_types_supported": list(self.response_types_supported),
"grant_types_supported": list(self.grant_types_supported),
"claims_supported": list(self.claims_supported),
"code_challenge_methods_supported": list(self.code_challenge_methods_supported),
}
@classmethod
def from_dict(cls, data: dict[str, object]) -> Self:
"""Create from dictionary (e.g., discovery document)."""
get = data.get
scopes = get("scopes_supported")
response_types = get("response_types_supported")
grant_types = get("grant_types_supported")
claims = get("claims_supported")
code_challenge = get("code_challenge_methods_supported")
return cls(
issuer=str(get("issuer", "")),
authorization_endpoint=str(get("authorization_endpoint", "")),
token_endpoint=str(get("token_endpoint", "")),
userinfo_endpoint=str(data["userinfo_endpoint"]) if get("userinfo_endpoint") else None,
jwks_uri=str(data[JWKS_URI]) if get(JWKS_URI) else None,
end_session_endpoint=str(data[END_SESSION_ENDPOINT])
if get(END_SESSION_ENDPOINT)
else None,
revocation_endpoint=str(data[REVOCATION_ENDPOINT]) if get(REVOCATION_ENDPOINT) else None,
introspection_endpoint=str(data[INTROSPECTION_ENDPOINT])
if get(INTROSPECTION_ENDPOINT)
else None,
scopes_supported=_tuple_from_list(scopes),
response_types_supported=_tuple_from_list(response_types),
grant_types_supported=_tuple_from_list(grant_types),
claims_supported=_tuple_from_list(claims),
code_challenge_methods_supported=_tuple_from_list(code_challenge),
)
to_dict = as_dict
decode = from_dict
def supports_pkce(self) -> bool:
"""Check if provider supports PKCE with S256."""
return "S256" in self.code_challenge_methods_supported
@dataclass(frozen=True, slots=True)
class OidcProviderCreateParams:
"""Parameters for creating an OIDC provider configuration.
@@ -406,12 +258,12 @@ class OidcProviderConfig:
if isinstance(claim_mapping_data, dict)
else ClaimMapping()
),
scopes=_tuple_from_list_or_default(
scopes=tuple_from_list_or_default(
scopes_data,
(OIDC_SCOPE_OPENID, OIDC_SCOPE_PROFILE, OIDC_SCOPE_EMAIL),
),
require_email_verified=bool(get(FIELD_REQUIRE_EMAIL_VERIFIED, True)),
allowed_groups=_tuple_from_list(allowed_groups_data),
allowed_groups=tuple_from_list(allowed_groups_data),
created_at=datetime.fromisoformat(str(created_at_str)) if created_at_str else utc_now(),
updated_at=datetime.fromisoformat(str(updated_at_str)) if updated_at_str else utc_now(),
discovery_refreshed_at=datetime.fromisoformat(str(discovery_refreshed_str)) if discovery_refreshed_str else None,

View File

@@ -0,0 +1,75 @@
"""OIDC claim mapping entity.
Contains the ClaimMapping dataclass for mapping OIDC claims to NoteFlow user attributes.
"""
from __future__ import annotations
from dataclasses import dataclass
from typing import Self
from noteflow.domain.auth.oidc_constants import (
CLAIM_EMAIL,
CLAIM_EMAIL_VERIFIED,
CLAIM_GROUPS,
CLAIM_PICTURE,
CLAIM_PREFERRED_USERNAME,
)
@dataclass(frozen=True, slots=True)
class ClaimMapping:
"""Map OIDC claims to NoteFlow user attributes.
OIDC providers may use different claim names for user attributes.
This mapping allows configuring which claims to use for each attribute.
"""
# Standard OIDC claims with sensible defaults
subject_claim: str = "sub"
email_claim: str = CLAIM_EMAIL
email_verified_claim: str = CLAIM_EMAIL_VERIFIED
name_claim: str = "name"
preferred_username_claim: str = CLAIM_PREFERRED_USERNAME
groups_claim: str = CLAIM_GROUPS
picture_claim: str = CLAIM_PICTURE
# Optional custom claims
first_name_claim: str | None = None
last_name_claim: str | None = None
phone_claim: str | None = None
def as_dict(self) -> dict[str, str | None]:
"""Convert to dictionary for serialization."""
return {
"subject_claim": self.subject_claim,
"email_claim": self.email_claim,
"email_verified_claim": self.email_verified_claim,
"name_claim": self.name_claim,
"preferred_username_claim": self.preferred_username_claim,
"groups_claim": self.groups_claim,
"picture_claim": self.picture_claim,
"first_name_claim": self.first_name_claim,
"last_name_claim": self.last_name_claim,
"phone_claim": self.phone_claim,
}
@classmethod
def from_dict(cls, data: dict[str, str | None]) -> Self:
"""Create from dictionary."""
get = data.get
return cls(
subject_claim=get("subject_claim") or "sub",
email_claim=get("email_claim") or CLAIM_EMAIL,
email_verified_claim=get("email_verified_claim") or CLAIM_EMAIL_VERIFIED,
name_claim=get("name_claim") or "name",
preferred_username_claim=get("preferred_username_claim") or CLAIM_PREFERRED_USERNAME,
groups_claim=get("groups_claim") or CLAIM_GROUPS,
picture_claim=get("picture_claim") or CLAIM_PICTURE,
first_name_claim=get("first_name_claim"),
last_name_claim=get("last_name_claim"),
phone_claim=get("phone_claim"),
)
to_dict = as_dict
decode = from_dict

View File

@@ -0,0 +1,129 @@
"""OIDC discovery configuration entity.
Contains the OidcDiscoveryConfig dataclass representing fields
from the OpenID Connect Discovery document (.well-known/openid-configuration).
"""
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Self, cast
from noteflow.domain.constants.fields import (
END_SESSION_ENDPOINT,
INTROSPECTION_ENDPOINT,
JWKS_URI,
REVOCATION_ENDPOINT,
)
def tuple_from_list(value: object) -> tuple[str, ...]:
"""Convert a list to a tuple of strings.
Args:
value: Value to convert (expected to be a list).
Returns:
Tuple of string values, or empty tuple if not a list.
"""
if isinstance(value, list):
items = cast(list[object], value)
return tuple(str(item) for item in items)
return ()
def tuple_from_list_or_default(
value: object,
default: tuple[str, ...],
) -> tuple[str, ...]:
"""Convert a list to a tuple of strings, with a default fallback.
Args:
value: Value to convert (expected to be a list).
default: Default tuple to return if value is not a list.
Returns:
Tuple of string values, or default if not a list.
"""
if isinstance(value, list):
items = cast(list[object], value)
return tuple(str(item) for item in items)
return default
@dataclass(frozen=True, slots=True)
class OidcDiscoveryConfig:
"""OIDC discovery document fields.
These fields are populated from the provider's
`.well-known/openid-configuration` endpoint.
"""
issuer: str
authorization_endpoint: str
token_endpoint: str
userinfo_endpoint: str | None = None
jwks_uri: str | None = None
end_session_endpoint: str | None = None
revocation_endpoint: str | None = None
introspection_endpoint: str | None = None
scopes_supported: tuple[str, ...] = field(default_factory=tuple)
response_types_supported: tuple[str, ...] = field(default_factory=tuple)
grant_types_supported: tuple[str, ...] = field(default_factory=tuple)
claims_supported: tuple[str, ...] = field(default_factory=tuple)
code_challenge_methods_supported: tuple[str, ...] = field(default_factory=tuple)
def as_dict(self) -> dict[str, object]:
"""Convert to dictionary for serialization."""
return {
"issuer": self.issuer,
"authorization_endpoint": self.authorization_endpoint,
"token_endpoint": self.token_endpoint,
"userinfo_endpoint": self.userinfo_endpoint,
JWKS_URI: self.jwks_uri,
END_SESSION_ENDPOINT: self.end_session_endpoint,
REVOCATION_ENDPOINT: self.revocation_endpoint,
INTROSPECTION_ENDPOINT: self.introspection_endpoint,
"scopes_supported": list(self.scopes_supported),
"response_types_supported": list(self.response_types_supported),
"grant_types_supported": list(self.grant_types_supported),
"claims_supported": list(self.claims_supported),
"code_challenge_methods_supported": list(self.code_challenge_methods_supported),
}
@classmethod
def from_dict(cls, data: dict[str, object]) -> Self:
"""Create from dictionary (e.g., discovery document)."""
get = data.get
scopes = get("scopes_supported")
response_types = get("response_types_supported")
grant_types = get("grant_types_supported")
claims = get("claims_supported")
code_challenge = get("code_challenge_methods_supported")
return cls(
issuer=str(get("issuer", "")),
authorization_endpoint=str(get("authorization_endpoint", "")),
token_endpoint=str(get("token_endpoint", "")),
userinfo_endpoint=str(data["userinfo_endpoint"]) if get("userinfo_endpoint") else None,
jwks_uri=str(data[JWKS_URI]) if get(JWKS_URI) else None,
end_session_endpoint=str(data[END_SESSION_ENDPOINT])
if get(END_SESSION_ENDPOINT)
else None,
revocation_endpoint=str(data[REVOCATION_ENDPOINT]) if get(REVOCATION_ENDPOINT) else None,
introspection_endpoint=str(data[INTROSPECTION_ENDPOINT])
if get(INTROSPECTION_ENDPOINT)
else None,
scopes_supported=tuple_from_list(scopes),
response_types_supported=tuple_from_list(response_types),
grant_types_supported=tuple_from_list(grant_types),
claims_supported=tuple_from_list(claims),
code_challenge_methods_supported=tuple_from_list(code_challenge),
)
to_dict = as_dict
decode = from_dict
def supports_pkce(self) -> bool:
"""Check if provider supports PKCE with S256."""
return "S256" in self.code_challenge_methods_supported

View File

@@ -0,0 +1,50 @@
"""Placeholder definitions for summarization templates."""
from __future__ import annotations
from dataclasses import dataclass
from typing import Final
@dataclass(frozen=True)
class PlaceholderDefinition:
"""Definition for a supported template placeholder."""
key: str
description: str
example: str | None = None
PLACEHOLDERS: Final[tuple[PlaceholderDefinition, ...]] = (
# Meeting
PlaceholderDefinition("meeting.id", "Meeting identifier."),
PlaceholderDefinition("meeting.title", "Meeting title."),
PlaceholderDefinition("meeting.state", "Meeting state (created/recording/stopped/completed)."),
PlaceholderDefinition("meeting.created_at", "Meeting creation time (ISO 8601)."),
PlaceholderDefinition("meeting.started_at", "Meeting start time (ISO 8601)."),
PlaceholderDefinition("meeting.ended_at", "Meeting end time (ISO 8601)."),
PlaceholderDefinition("meeting.duration_seconds", "Meeting duration in seconds."),
PlaceholderDefinition("meeting.duration_minutes", "Meeting duration in minutes."),
PlaceholderDefinition("meeting.segment_count", "Number of transcript segments."),
PlaceholderDefinition("meeting.word_count", "Number of words in transcript."),
PlaceholderDefinition("meeting.metadata.<key>", "Meeting metadata value for <key>."),
# Project
PlaceholderDefinition("project.id", "Project identifier."),
PlaceholderDefinition("project.name", "Project name."),
PlaceholderDefinition("project.slug", "Project slug."),
PlaceholderDefinition("project.description", "Project description."),
# Workspace
PlaceholderDefinition("workspace.id", "Workspace identifier."),
PlaceholderDefinition("workspace.name", "Workspace name."),
PlaceholderDefinition("workspace.slug", "Workspace slug."),
# User
PlaceholderDefinition("user.display_name", "User display name."),
PlaceholderDefinition("user.email", "User email."),
# Summary constraints
PlaceholderDefinition("summary.max_key_points", "Max key points allowed."),
PlaceholderDefinition("summary.max_action_items", "Max action items allowed."),
# Metadata passthrough
PlaceholderDefinition("metadata.<key>", "Metadata value for <key>."),
# Style helpers
PlaceholderDefinition("style_instructions", "Resolved tone/format/verbosity instructions."),
)

View File

@@ -2,8 +2,9 @@
from .annotation import Annotation
from .integration import Integration, IntegrationStatus, IntegrationType, SyncRun, SyncRunStatus
from .meeting import Meeting, ProcessingStatus, ProcessingStepState, ProcessingStepStatus
from .meeting import Meeting, MeetingLoadParams
from .named_entity import EntityCategory, NamedEntity
from .processing import ProcessingStatus, ProcessingStepState, ProcessingStepStatus
from .project import (
SYSTEM_DEFAULTS,
EffectiveRules,
@@ -15,6 +16,7 @@ from .project import (
)
from .segment import Segment, WordTiming
from .summary import ActionItem, KeyPoint, Summary
from .summarization_template import SummarizationTemplate, SummarizationTemplateVersion
__all__ = [
"SYSTEM_DEFAULTS",
@@ -28,6 +30,7 @@ __all__ = [
"IntegrationType",
"KeyPoint",
"Meeting",
"MeetingLoadParams",
"NamedEntity",
"ProcessingStatus",
"ProcessingStepState",
@@ -36,6 +39,8 @@ __all__ = [
"ProjectSettings",
"Segment",
"Summary",
"SummarizationTemplate",
"SummarizationTemplateVersion",
"SyncRun",
"SyncRunStatus",
"TriggerRules",

View File

@@ -4,164 +4,31 @@ from __future__ import annotations
from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
from typing import TYPE_CHECKING
from uuid import UUID, uuid4
from noteflow.domain.constants.fields import ASSET_PATH, PROJECT_ID, WRAPPED_DEK
from noteflow.domain.entities.processing import (
ProcessingStepState,
ProcessingStepStatus,
ProcessingStatus,
)
from noteflow.domain.utils.time import utc_now
from noteflow.domain.value_objects import MeetingId, MeetingState
# Re-export for backward compatibility
__all__ = [
"Meeting",
"MeetingLoadParams",
"ProcessingStatus",
"ProcessingStepState",
"ProcessingStepStatus",
]
if TYPE_CHECKING:
from noteflow.domain.entities.segment import Segment
from noteflow.domain.entities.summary import Summary
class ProcessingStepStatus(Enum):
"""Status of an individual post-processing step."""
PENDING = "pending"
"""Not yet started."""
RUNNING = "running"
"""Currently processing."""
COMPLETED = "completed"
"""Completed successfully."""
FAILED = "failed"
"""Failed with error."""
SKIPPED = "skipped"
"""Skipped (e.g., feature disabled)."""
@dataclass(frozen=True, slots=True)
class ProcessingStepState:
"""State of a single post-processing step with timing and error info."""
status: ProcessingStepStatus = ProcessingStepStatus.PENDING
"""Current status of this step."""
error_message: str = ""
"""Error message if status is FAILED."""
started_at: datetime | None = None
"""When this step started, None if not started."""
completed_at: datetime | None = None
"""When this step completed, None if not completed."""
@classmethod
def pending(cls) -> ProcessingStepState:
"""Create a pending step state."""
status = ProcessingStepStatus.PENDING
return cls(status=status)
@classmethod
def running(cls, started_at: datetime | None = None) -> ProcessingStepState:
"""Create a running step state."""
started = started_at or utc_now()
return cls(
status=ProcessingStepStatus.RUNNING,
started_at=started,
)
@classmethod
def completed(
cls,
started_at: datetime | None = None,
completed_at: datetime | None = None,
) -> ProcessingStepState:
"""Create a completed step state."""
completed = completed_at or utc_now()
return cls(
status=ProcessingStepStatus.COMPLETED,
started_at=started_at,
completed_at=completed,
)
@classmethod
def failed(
cls,
error_message: str,
started_at: datetime | None = None,
) -> ProcessingStepState:
"""Create a failed step state."""
completed = utc_now()
return cls(
status=ProcessingStepStatus.FAILED,
error_message=error_message,
started_at=started_at,
completed_at=completed,
)
@classmethod
def skipped(cls) -> ProcessingStepState:
"""Create a skipped step state."""
status = ProcessingStepStatus.SKIPPED
return cls(status=status)
def with_error(self, message: str) -> ProcessingStepState:
"""Return a failed state derived from this instance."""
started_at = self.started_at or utc_now()
return ProcessingStepState(
status=ProcessingStepStatus.FAILED,
error_message=message,
started_at=started_at,
completed_at=utc_now(),
)
@dataclass(frozen=True, slots=True)
class ProcessingStatus:
"""Aggregate status of all post-processing steps for a meeting."""
summary: ProcessingStepState = field(default_factory=ProcessingStepState.pending)
"""Summary generation status."""
entities: ProcessingStepState = field(default_factory=ProcessingStepState.pending)
"""Entity extraction status."""
diarization: ProcessingStepState = field(default_factory=ProcessingStepState.pending)
"""Speaker diarization status."""
@classmethod
def create_pending(cls) -> ProcessingStatus:
"""Create a processing status with all steps pending."""
return cls()
@property
def is_complete(self) -> bool:
"""Check if all processing steps are complete (or skipped/failed)."""
terminal_statuses = {
ProcessingStepStatus.COMPLETED,
ProcessingStepStatus.FAILED,
ProcessingStepStatus.SKIPPED,
}
return (
self.summary.status in terminal_statuses
and self.entities.status in terminal_statuses
and self.diarization.status in terminal_statuses
)
@property
def is_any_running(self) -> bool:
"""Check if any processing step is currently running."""
return (
self.summary.status == ProcessingStepStatus.RUNNING
or self.entities.status == ProcessingStepStatus.RUNNING
or self.diarization.status == ProcessingStepStatus.RUNNING
)
@property
def has_any_failed(self) -> bool:
"""Check if any processing step has failed."""
return (
self.summary.status == ProcessingStepStatus.FAILED
or self.entities.status == ProcessingStepStatus.FAILED
or self.diarization.status == ProcessingStepStatus.FAILED
)
@dataclass(frozen=True, slots=True)
class MeetingLoadParams:

View File

@@ -0,0 +1,190 @@
"""Post-processing status entities for meeting workflows.
Contains status tracking entities for post-processing steps:
summary generation, entity extraction, and speaker diarization.
"""
from __future__ import annotations
from dataclasses import dataclass, field
from datetime import datetime
from enum import Enum
from noteflow.domain.utils.time import utc_now
class ProcessingStepStatus(Enum):
"""Status of an individual post-processing step."""
PENDING = "pending"
"""Not yet started."""
RUNNING = "running"
"""Currently processing."""
COMPLETED = "completed"
"""Completed successfully."""
FAILED = "failed"
"""Failed with error."""
SKIPPED = "skipped"
"""Skipped (e.g., feature disabled)."""
@dataclass(frozen=True, slots=True)
class ProcessingStepState:
"""State of a single post-processing step with timing and error info."""
status: ProcessingStepStatus = ProcessingStepStatus.PENDING
"""Current status of this step."""
error_message: str = ""
"""Error message if status is FAILED."""
started_at: datetime | None = None
"""When this step started, None if not started."""
completed_at: datetime | None = None
"""When this step completed, None if not completed."""
@classmethod
def pending(cls) -> ProcessingStepState:
"""Create a pending step state."""
status = ProcessingStepStatus.PENDING
return cls(status=status)
@classmethod
def running(cls, started_at: datetime | None = None) -> ProcessingStepState:
"""Create a running step state."""
started = started_at or utc_now()
return cls(
status=ProcessingStepStatus.RUNNING,
started_at=started,
)
@classmethod
def completed(
cls,
started_at: datetime | None = None,
completed_at: datetime | None = None,
) -> ProcessingStepState:
"""Create a completed step state."""
completed = completed_at or utc_now()
return cls(
status=ProcessingStepStatus.COMPLETED,
started_at=started_at,
completed_at=completed,
)
@classmethod
def failed(
cls,
error_message: str,
started_at: datetime | None = None,
) -> ProcessingStepState:
"""Create a failed step state."""
completed = utc_now()
return cls(
status=ProcessingStepStatus.FAILED,
error_message=error_message,
started_at=started_at,
completed_at=completed,
)
@classmethod
def skipped(cls) -> ProcessingStepState:
"""Create a skipped step state."""
status = ProcessingStepStatus.SKIPPED
return cls(status=status)
def with_error(self, message: str) -> ProcessingStepState:
"""Return a failed state derived from this instance."""
started_at = self.started_at or utc_now()
return ProcessingStepState(
status=ProcessingStepStatus.FAILED,
error_message=message,
started_at=started_at,
completed_at=utc_now(),
)
@dataclass(frozen=True, slots=True)
class ProcessingStatus:
"""Aggregate status of all post-processing steps for a meeting."""
summary: ProcessingStepState = field(default_factory=ProcessingStepState.pending)
"""Summary generation status."""
entities: ProcessingStepState = field(default_factory=ProcessingStepState.pending)
"""Entity extraction status."""
diarization: ProcessingStepState = field(default_factory=ProcessingStepState.pending)
"""Speaker diarization status."""
queued_at: datetime | None = None
"""When post-processing was queued, None if not yet queued."""
@classmethod
def create_pending(cls) -> ProcessingStatus:
"""Create initial processing status for a newly stopped meeting.
Factory method that creates a ProcessingStatus with all steps
in PENDING state. This is the canonical entry point for
initiating post-processing workflows.
Records the queue timestamp for audit trail and monitoring.
All steps are explicitly initialized to PENDING state.
Use this factory instead of ``ProcessingStatus()`` to:
1. Communicate intent clearly at call sites
2. Record queue timestamp for monitoring
3. Maintain a single point of control for initial state
Returns:
ProcessingStatus with summary, entities, and diarization all PENDING,
and queued_at set to current UTC time.
Example::
meeting.processing_status = ProcessingStatus.create_pending()
"""
pending_step = ProcessingStepState.pending()
return cls(
summary=pending_step,
entities=pending_step,
diarization=pending_step,
queued_at=utc_now(),
)
@property
def is_complete(self) -> bool:
"""Check if all processing steps are complete (or skipped/failed)."""
terminal_statuses = {
ProcessingStepStatus.COMPLETED,
ProcessingStepStatus.FAILED,
ProcessingStepStatus.SKIPPED,
}
return (
self.summary.status in terminal_statuses
and self.entities.status in terminal_statuses
and self.diarization.status in terminal_statuses
)
@property
def is_any_running(self) -> bool:
"""Check if any processing step is currently running."""
return (
self.summary.status == ProcessingStepStatus.RUNNING
or self.entities.status == ProcessingStepStatus.RUNNING
or self.diarization.status == ProcessingStepStatus.RUNNING
)
@property
def has_any_failed(self) -> bool:
"""Check if any processing step has failed."""
return (
self.summary.status == ProcessingStepStatus.FAILED
or self.entities.status == ProcessingStepStatus.FAILED
or self.diarization.status == ProcessingStepStatus.FAILED
)

View File

@@ -0,0 +1,39 @@
"""Summarization template entities."""
from __future__ import annotations
from dataclasses import dataclass, field
from datetime import datetime
from uuid import UUID
from noteflow.domain.utils.time import utc_now
@dataclass(frozen=True)
class SummarizationTemplate:
"""Workspace-scoped summarization template."""
id: UUID
workspace_id: UUID | None
name: str
description: str | None = None
is_system: bool = False
is_archived: bool = False
current_version_id: UUID | None = None
created_at: datetime = field(default_factory=utc_now)
updated_at: datetime = field(default_factory=utc_now)
created_by: UUID | None = None
updated_by: UUID | None = None
@dataclass(frozen=True)
class SummarizationTemplateVersion:
"""Immutable template version."""
id: UUID
template_id: UUID
version_number: int
content: str
change_note: str | None = None
created_at: datetime = field(default_factory=utc_now)
created_by: UUID | None = None

View File

@@ -20,9 +20,12 @@ from noteflow.domain.ports.repositories.external import (
UsageEventRepository,
WebhookRepository,
)
# Note: external.py is deprecated; use the external/ package instead
from noteflow.domain.ports.repositories.identity import (
ProjectMembershipRepository,
ProjectRepository,
SummarizationTemplateRepository,
UserRepository,
WorkspaceRepository,
)
@@ -32,3 +35,22 @@ from noteflow.domain.ports.repositories.transcript import (
SegmentRepository,
SummaryRepository,
)
__all__ = [
"AssetRepository",
"DiarizationJobRepository",
"PreferencesRepository",
"EntityRepository",
"IntegrationRepository",
"UsageEventRepository",
"WebhookRepository",
"ProjectMembershipRepository",
"ProjectRepository",
"SummarizationTemplateRepository",
"UserRepository",
"WorkspaceRepository",
"AnnotationRepository",
"MeetingRepository",
"SegmentRepository",
"SummaryRepository",
]

View File

@@ -1,366 +0,0 @@
"""Repository protocols for external service entities.
Contains Entity (NER), Integration, and Webhook repository protocols.
"""
from __future__ import annotations
from collections.abc import Sequence
from typing import TYPE_CHECKING, Protocol
if TYPE_CHECKING:
from uuid import UUID
from noteflow.application.observability.ports import UsageEvent
from noteflow.domain.entities import Integration, SyncRun
from noteflow.domain.entities.named_entity import NamedEntity
from noteflow.domain.value_objects import MeetingId
from noteflow.domain.webhooks import WebhookConfig, WebhookDelivery
class EntityRepository(Protocol):
"""Repository protocol for NamedEntity operations (NER results)."""
async def save(self, entity: NamedEntity) -> NamedEntity:
"""Save or update a named entity.
Args:
entity: Entity to save.
Returns:
Saved entity with db_id populated.
"""
...
async def save_batch(
self, entities: Sequence[NamedEntity],
) -> Sequence[NamedEntity]:
"""Save multiple entities efficiently.
Args:
entities: Entities to save.
Returns:
Saved entities with db_ids populated.
"""
...
async def get(self, entity_id: UUID) -> NamedEntity | None:
"""Get entity by ID.
Args:
entity_id: Entity UUID.
Returns:
Entity if found, None otherwise.
"""
...
async def get_by_meeting(self, meeting_id: MeetingId) -> Sequence[NamedEntity]:
"""Get all entities for a meeting.
Args:
meeting_id: Meeting UUID.
Returns:
List of entities.
"""
...
async def delete_by_meeting(self, meeting_id: MeetingId) -> int:
"""Delete all entities for a meeting.
Args:
meeting_id: Meeting UUID.
Returns:
Number of deleted entities.
"""
...
async def update_pinned(self, entity_id: UUID, is_pinned: bool) -> bool:
"""Update the pinned status of an entity.
Args:
entity_id: Entity UUID.
is_pinned: New pinned status.
Returns:
True if entity was found and updated.
"""
...
async def exists_for_meeting(self, meeting_id: MeetingId) -> bool:
"""Check if any entities exist for a meeting.
Args:
meeting_id: Meeting UUID.
Returns:
True if at least one entity exists.
"""
...
async def update(
self,
entity_id: UUID,
text: str | None = None,
category: str | None = None,
) -> NamedEntity | None:
"""Update an existing entity.
Args:
entity_id: Entity UUID.
text: New text value (optional).
category: New category value (optional).
Returns:
Updated entity if found, None otherwise.
"""
...
async def delete(self, entity_id: UUID) -> bool:
"""Delete an entity by ID.
Args:
entity_id: Entity UUID.
Returns:
True if entity was found and deleted.
"""
...
class IntegrationRepository(Protocol):
"""Repository protocol for external service integrations.
Manages OAuth-connected services like calendars, email providers, and PKM tools.
"""
async def get(self, integration_id: UUID) -> Integration | None:
"""Retrieve an integration by ID.
Args:
integration_id: Integration UUID.
Returns:
Integration if found, None otherwise.
"""
...
async def get_by_provider(
self,
provider: str,
integration_type: str | None = None,
) -> Integration | None:
"""Retrieve an integration by provider name.
Args:
provider: Provider name (e.g., 'google', 'outlook').
integration_type: Optional type filter.
Returns:
Integration if found, None otherwise.
"""
...
async def create(self, integration: Integration) -> Integration:
"""Persist a new integration.
Args:
integration: Integration to create.
Returns:
Created integration.
"""
...
async def update(self, integration: Integration) -> Integration:
"""Update an existing integration.
Args:
integration: Integration with updated fields.
Returns:
Updated integration.
Raises:
ValueError: If integration does not exist.
"""
...
async def delete(self, integration_id: UUID) -> bool:
"""Delete an integration and its secrets.
Args:
integration_id: Integration UUID.
Returns:
Return whether the record was deleted.
"""
...
async def get_secrets(self, integration_id: UUID) -> dict[str, str] | None:
"""Get encrypted secrets for an integration.
Args:
integration_id: Integration UUID.
Returns:
Dictionary of secret key-value pairs, or None if not found.
"""
...
async def set_secrets(
self, integration_id: UUID, secrets: dict[str, str],
) -> None:
"""Store encrypted secrets for an integration.
Args:
integration_id: Integration UUID.
secrets: Dictionary of secret key-value pairs.
"""
...
async def list_by_type(self, integration_type: str) -> Sequence[Integration]:
"""List integrations by type.
Args:
integration_type: Integration type (e.g., 'calendar', 'email').
Returns:
List of integrations of the specified type.
"""
...
async def list_all(self) -> Sequence[Integration]:
"""List all integrations for the current workspace context.
Returns:
All integrations the user has access to.
"""
...
# Sync run operations
async def create_sync_run(self, sync_run: SyncRun) -> SyncRun:
"""Create a new sync run record.
Args:
sync_run: Sync run to persist.
Returns:
Created sync run.
"""
...
async def get_sync_run(self, sync_run_id: UUID) -> SyncRun | None:
"""Retrieve a sync run by ID.
Args:
sync_run_id: Sync run UUID.
Returns:
SyncRun if found, None otherwise.
"""
...
async def update_sync_run(self, sync_run: SyncRun) -> SyncRun:
"""Update an existing sync run.
Args:
sync_run: Sync run with updated fields.
Returns:
Updated sync run.
"""
...
async def list_sync_runs(
self,
integration_id: UUID,
limit: int = 20,
offset: int = 0,
) -> tuple[Sequence[SyncRun], int]:
"""List sync runs for an integration with pagination.
Args:
integration_id: Integration to list runs for.
limit: Maximum runs to return.
offset: Pagination offset.
Returns:
Tuple of (sync runs newest first, total count).
"""
...
class WebhookRepository(Protocol):
"""Repository for webhook configuration and delivery operations."""
async def get_all_enabled(
self, workspace_id: UUID | None = None,
) -> Sequence[WebhookConfig]:
"""Return all enabled webhooks, optionally filtered by workspace."""
...
async def get_all(
self, workspace_id: UUID | None = None,
) -> Sequence[WebhookConfig]:
"""Return all webhooks regardless of enabled status."""
...
async def get_by_id(self, webhook_id: UUID) -> WebhookConfig | None:
"""Return webhook by ID or None if not found."""
...
async def create(self, config: WebhookConfig) -> WebhookConfig:
"""Persist a new webhook configuration."""
...
async def update(self, config: WebhookConfig) -> WebhookConfig:
"""Update existing webhook. Raises ValueError if not found."""
...
async def delete(self, webhook_id: UUID) -> bool:
"""Delete webhook by ID and return whether a record was deleted."""
...
async def add_delivery(self, delivery: WebhookDelivery) -> WebhookDelivery:
"""Record a webhook delivery attempt."""
...
async def get_deliveries(
self, webhook_id: UUID, limit: int = 50,
) -> Sequence[WebhookDelivery]:
"""Return delivery history for webhook, newest first."""
...
class UsageEventRepository(Protocol):
"""Repository for usage event persistence and aggregation.
Tracks resource consumption for analytics, billing, and monitoring.
"""
async def add(self, event: UsageEvent) -> UsageEvent:
"""Persist a usage event.
Args:
event: UsageEvent to persist.
Returns:
Persisted event.
"""
...
async def add_batch(self, events: Sequence[UsageEvent]) -> int:
"""Persist multiple usage events efficiently.
Args:
events: UsageEvents to persist.
Returns:
Number of events persisted.
"""
...

View File

@@ -0,0 +1,16 @@
"""Repository protocols for external service entities.
Contains Entity (NER), Integration, Webhook, and UsageEvent repository protocols.
"""
from noteflow.domain.ports.repositories.external._entity import EntityRepository
from noteflow.domain.ports.repositories.external._integration import IntegrationRepository
from noteflow.domain.ports.repositories.external._usage import UsageEventRepository
from noteflow.domain.ports.repositories.external._webhook import WebhookRepository
__all__ = [
"EntityRepository",
"IntegrationRepository",
"UsageEventRepository",
"WebhookRepository",
]

View File

@@ -0,0 +1,125 @@
"""Repository protocol for NamedEntity operations (NER results)."""
from __future__ import annotations
from collections.abc import Sequence
from typing import TYPE_CHECKING, Protocol
if TYPE_CHECKING:
from uuid import UUID
from noteflow.domain.entities.named_entity import NamedEntity
from noteflow.domain.value_objects import MeetingId
class EntityRepository(Protocol):
"""Repository protocol for NamedEntity operations (NER results)."""
async def save(self, entity: NamedEntity) -> NamedEntity:
"""Save or update a named entity.
Args:
entity: Entity to save.
Returns:
Saved entity with db_id populated.
"""
...
async def save_batch(
self, entities: Sequence[NamedEntity],
) -> Sequence[NamedEntity]:
"""Save multiple entities efficiently.
Args:
entities: Entities to save.
Returns:
Saved entities with db_ids populated.
"""
...
async def get(self, entity_id: UUID) -> NamedEntity | None:
"""Get entity by ID.
Args:
entity_id: Entity UUID.
Returns:
Entity if found, None otherwise.
"""
...
async def get_by_meeting(self, meeting_id: MeetingId) -> Sequence[NamedEntity]:
"""Get all entities for a meeting.
Args:
meeting_id: Meeting UUID.
Returns:
List of entities.
"""
...
async def delete_by_meeting(self, meeting_id: MeetingId) -> int:
"""Delete all entities for a meeting.
Args:
meeting_id: Meeting UUID.
Returns:
Number of deleted entities.
"""
...
async def update_pinned(self, entity_id: UUID, is_pinned: bool) -> bool:
"""Update the pinned status of an entity.
Args:
entity_id: Entity UUID.
is_pinned: New pinned status.
Returns:
True if entity was found and updated.
"""
...
async def exists_for_meeting(self, meeting_id: MeetingId) -> bool:
"""Check if any entities exist for a meeting.
Args:
meeting_id: Meeting UUID.
Returns:
True if at least one entity exists.
"""
...
async def update(
self,
entity_id: UUID,
text: str | None = None,
category: str | None = None,
) -> NamedEntity | None:
"""Update an existing entity.
Args:
entity_id: Entity UUID.
text: New text value (optional).
category: New category value (optional).
Returns:
Updated entity if found, None otherwise.
"""
...
async def delete(self, entity_id: UUID) -> bool:
"""Delete an entity by ID.
Args:
entity_id: Entity UUID.
Returns:
True if entity was found and deleted.
"""
...

View File

@@ -0,0 +1,175 @@
"""Repository protocol for external service integrations."""
from __future__ import annotations
from collections.abc import Sequence
from typing import TYPE_CHECKING, Protocol
if TYPE_CHECKING:
from uuid import UUID
from noteflow.domain.entities import Integration, SyncRun
class IntegrationRepository(Protocol):
"""Repository protocol for external service integrations.
Manages OAuth-connected services like calendars, email providers, and PKM tools.
"""
async def get(self, integration_id: UUID) -> Integration | None:
"""Retrieve an integration by ID.
Args:
integration_id: Integration UUID.
Returns:
Integration if found, None otherwise.
"""
...
async def get_by_provider(
self,
provider: str,
integration_type: str | None = None,
) -> Integration | None:
"""Retrieve an integration by provider name.
Args:
provider: Provider name (e.g., 'google', 'outlook').
integration_type: Optional type filter.
Returns:
Integration if found, None otherwise.
"""
...
async def create(self, integration: Integration) -> Integration:
"""Persist a new integration.
Args:
integration: Integration to create.
Returns:
Created integration.
"""
...
async def update(self, integration: Integration) -> Integration:
"""Update an existing integration.
Args:
integration: Integration with updated fields.
Returns:
Updated integration.
Raises:
ValueError: If integration does not exist.
"""
...
async def delete(self, integration_id: UUID) -> bool:
"""Delete an integration and its secrets.
Args:
integration_id: Integration UUID.
Returns:
Return whether the record was deleted.
"""
...
async def get_secrets(self, integration_id: UUID) -> dict[str, str] | None:
"""Get encrypted secrets for an integration.
Args:
integration_id: Integration UUID.
Returns:
Dictionary of secret key-value pairs, or None if not found.
"""
...
async def set_secrets(
self, integration_id: UUID, secrets: dict[str, str],
) -> None:
"""Store encrypted secrets for an integration.
Args:
integration_id: Integration UUID.
secrets: Dictionary of secret key-value pairs.
"""
...
async def list_by_type(self, integration_type: str) -> Sequence[Integration]:
"""List integrations by type.
Args:
integration_type: Integration type (e.g., 'calendar', 'email').
Returns:
List of integrations of the specified type.
"""
...
async def list_all(self) -> Sequence[Integration]:
"""List all integrations for the current workspace context.
Returns:
All integrations the user has access to.
"""
...
# Sync run operations
async def create_sync_run(self, sync_run: SyncRun) -> SyncRun:
"""Create a new sync run record.
Args:
sync_run: Sync run to persist.
Returns:
Created sync run.
"""
...
async def get_sync_run(self, sync_run_id: UUID) -> SyncRun | None:
"""Retrieve a sync run by ID.
Args:
sync_run_id: Sync run UUID.
Returns:
SyncRun if found, None otherwise.
"""
...
async def update_sync_run(self, sync_run: SyncRun) -> SyncRun:
"""Update an existing sync run.
Args:
sync_run: Sync run with updated fields.
Returns:
Updated sync run.
"""
...
async def list_sync_runs(
self,
integration_id: UUID,
limit: int = 20,
offset: int = 0,
) -> tuple[Sequence[SyncRun], int]:
"""List sync runs for an integration with pagination.
Args:
integration_id: Integration to list runs for.
limit: Maximum runs to return.
offset: Pagination offset.
Returns:
Tuple of (sync runs newest first, total count).
"""
...

View File

@@ -0,0 +1,38 @@
"""Repository for usage event persistence and aggregation."""
from __future__ import annotations
from collections.abc import Sequence
from typing import TYPE_CHECKING, Protocol
if TYPE_CHECKING:
from noteflow.application.observability.ports import UsageEvent
class UsageEventRepository(Protocol):
"""Repository for usage event persistence and aggregation.
Tracks resource consumption for analytics, billing, and monitoring.
"""
async def add(self, event: UsageEvent) -> UsageEvent:
"""Persist a usage event.
Args:
event: UsageEvent to persist.
Returns:
Persisted event.
"""
...
async def add_batch(self, events: Sequence[UsageEvent]) -> int:
"""Persist multiple usage events efficiently.
Args:
events: UsageEvents to persist.
Returns:
Number of events persisted.
"""
...

View File

@@ -0,0 +1,53 @@
"""Repository for webhook configuration and delivery operations."""
from __future__ import annotations
from collections.abc import Sequence
from typing import TYPE_CHECKING, Protocol
if TYPE_CHECKING:
from uuid import UUID
from noteflow.domain.webhooks import WebhookConfig, WebhookDelivery
class WebhookRepository(Protocol):
"""Repository for webhook configuration and delivery operations."""
async def get_all_enabled(
self, workspace_id: UUID | None = None,
) -> Sequence[WebhookConfig]:
"""Return all enabled webhooks, optionally filtered by workspace."""
...
async def get_all(
self, workspace_id: UUID | None = None,
) -> Sequence[WebhookConfig]:
"""Return all webhooks regardless of enabled status."""
...
async def get_by_id(self, webhook_id: UUID) -> WebhookConfig | None:
"""Return webhook by ID or None if not found."""
...
async def create(self, config: WebhookConfig) -> WebhookConfig:
"""Persist a new webhook configuration."""
...
async def update(self, config: WebhookConfig) -> WebhookConfig:
"""Update existing webhook. Raises ValueError if not found."""
...
async def delete(self, webhook_id: UUID) -> bool:
"""Delete webhook by ID and return whether a record was deleted."""
...
async def add_delivery(self, delivery: WebhookDelivery) -> WebhookDelivery:
"""Record a webhook delivery attempt."""
...
async def get_deliveries(
self, webhook_id: UUID, limit: int = 50,
) -> Sequence[WebhookDelivery]:
"""Return delivery history for webhook, newest first."""
...

View File

@@ -8,5 +8,16 @@ from noteflow.domain.ports.repositories.identity._membership import (
ProjectMembershipRepository,
)
from noteflow.domain.ports.repositories.identity._project import ProjectRepository
from noteflow.domain.ports.repositories.identity._summarization_template import (
SummarizationTemplateRepository,
)
from noteflow.domain.ports.repositories.identity._user import UserRepository
from noteflow.domain.ports.repositories.identity._workspace import WorkspaceRepository
__all__ = [
"ProjectMembershipRepository",
"ProjectRepository",
"SummarizationTemplateRepository",
"UserRepository",
"WorkspaceRepository",
]

View File

@@ -0,0 +1,59 @@
"""Repository protocol for summarization templates."""
from __future__ import annotations
from collections.abc import Sequence
from typing import Protocol
from uuid import UUID
from noteflow.domain.entities import SummarizationTemplate, SummarizationTemplateVersion
class SummarizationTemplateRepository(Protocol):
"""Repository protocol for summarization template operations."""
async def get(self, template_id: UUID) -> SummarizationTemplate | None:
"""Get template by ID."""
...
async def get_version(self, version_id: UUID) -> SummarizationTemplateVersion | None:
"""Get template version by ID."""
...
async def list_for_workspace(
self,
workspace_id: UUID,
*,
include_system: bool,
include_archived: bool,
) -> Sequence[SummarizationTemplate]:
"""List templates for a workspace."""
...
async def list_versions(self, template_id: UUID) -> Sequence[SummarizationTemplateVersion]:
"""List versions for a template."""
...
async def create_with_version(
self,
template: SummarizationTemplate,
version: SummarizationTemplateVersion,
) -> SummarizationTemplate:
"""Create a template with its initial version."""
...
async def add_version(
self,
version: SummarizationTemplateVersion,
) -> SummarizationTemplateVersion:
"""Persist a new template version."""
...
async def update(self, template: SummarizationTemplate) -> SummarizationTemplate:
"""Update template metadata and current version."""
...
async def archive(self, template_id: UUID, updated_by: UUID | None) -> bool:
"""Archive a template by ID."""
...

View File

@@ -15,6 +15,7 @@ if TYPE_CHECKING:
PreferencesRepository,
SegmentRepository,
SummaryRepository,
SummarizationTemplateRepository,
UsageEventRepository,
UserRepository,
WebhookRepository,
@@ -167,6 +168,11 @@ class UnitOfWorkIdentityRepositories(Protocol):
"""Access the project memberships repository for access control."""
...
@property
def summarization_templates(self) -> SummarizationTemplateRepository:
"""Access the summarization template repository."""
...
class UnitOfWorkLifecycle(Protocol):
"""Lifecycle methods for transaction handling."""

View File

@@ -1,5 +1,10 @@
"""Webhook domain module for event notification system."""
from .config import (
WebhookConfig,
WebhookConfigCreateKwargs,
WebhookConfigCreateOptions,
)
from .constants import (
DEFAULT_WEBHOOK_BACKOFF_BASE,
DEFAULT_WEBHOOK_MAX_RESPONSE_LENGTH,
@@ -15,14 +20,19 @@ from .constants import (
WEBHOOK_REPLAY_TOLERANCE_SECONDS,
WEBHOOK_SIGNATURE_PREFIX,
)
from .events import (
from .delivery import (
DeliveryResult,
WebhookDelivery,
)
from .events import (
WebhookEventType,
)
from .payloads import (
DiarizationCompletedPayload,
EntitiesExtractedPayload,
MeetingCompletedPayload,
RecordingPayload,
SummaryGeneratedPayload,
WebhookConfig,
WebhookDelivery,
WebhookEventType,
WebhookPayload,
WebhookPayloadDict,
payload_to_dict,
@@ -43,14 +53,21 @@ __all__ = [
"RETRYABLE_STATUS_CODES",
"WEBHOOK_REPLAY_TOLERANCE_SECONDS",
"WEBHOOK_SIGNATURE_PREFIX",
# Entities
# Config entities
"WebhookConfig",
"WebhookConfigCreateKwargs",
"WebhookConfigCreateOptions",
# Delivery entities
"DeliveryResult",
"WebhookDelivery",
# Event types
"WebhookEventType",
# Payload entities
"DiarizationCompletedPayload",
"EntitiesExtractedPayload",
"MeetingCompletedPayload",
"RecordingPayload",
"SummaryGeneratedPayload",
"WebhookConfig",
"WebhookDelivery",
"WebhookEventType",
"WebhookPayload",
"WebhookPayloadDict",
# Helpers

View File

@@ -0,0 +1,119 @@
"""Webhook configuration entities.
Contains WebhookConfig and related types for webhook configuration management.
"""
from __future__ import annotations
from dataclasses import dataclass, field
from datetime import datetime
from typing import NotRequired, Required, TypedDict, Unpack
from uuid import UUID, uuid4
from noteflow.domain.constants.fields import MAX_RETRIES, SECRET, WEBHOOK
from noteflow.domain.utils.time import utc_now
from noteflow.domain.webhooks.constants import (
DEFAULT_WEBHOOK_MAX_RETRIES,
DEFAULT_WEBHOOK_TIMEOUT_MS,
)
from noteflow.domain.webhooks.events import WebhookEventType
class WebhookConfigCreateKwargs(TypedDict):
"""Keyword arguments for webhook config creation."""
workspace_id: Required[UUID]
url: Required[str]
events: Required[list[WebhookEventType]]
name: NotRequired[str]
secret: NotRequired[str | None]
timeout_ms: NotRequired[int]
max_retries: NotRequired[int]
@dataclass(frozen=True, slots=True)
class WebhookConfigCreateOptions:
"""Optional parameters for webhook config creation."""
name: str = WEBHOOK
secret: str | None = None
timeout_ms: int = DEFAULT_WEBHOOK_TIMEOUT_MS
max_retries: int = DEFAULT_WEBHOOK_MAX_RETRIES
@dataclass(frozen=True, slots=True)
class WebhookConfig:
"""Webhook configuration for event delivery.
Fields match WebhookConfigModel ORM for seamless conversion.
Attributes:
id: Unique webhook identifier.
workspace_id: Workspace this webhook belongs to.
url: Target URL for webhook delivery.
events: Set of event types this webhook is subscribed to.
name: Display name for the webhook.
secret: Optional HMAC signing secret.
enabled: Whether the webhook is active.
timeout_ms: HTTP request timeout in milliseconds.
max_retries: Maximum delivery retry attempts.
created_at: When the webhook was created.
updated_at: When the webhook was last modified.
"""
id: UUID
workspace_id: UUID
url: str
events: frozenset[WebhookEventType]
name: str = WEBHOOK
secret: str | None = None
enabled: bool = True
timeout_ms: int = DEFAULT_WEBHOOK_TIMEOUT_MS
max_retries: int = DEFAULT_WEBHOOK_MAX_RETRIES
created_at: datetime = field(default_factory=utc_now)
updated_at: datetime = field(default_factory=utc_now)
@classmethod
def create(
cls,
**kwargs: Unpack[WebhookConfigCreateKwargs],
) -> WebhookConfig:
"""Create a new webhook configuration.
Args:
**kwargs: Webhook config fields.
Returns:
New WebhookConfig with generated ID and timestamps.
"""
workspace_id = kwargs["workspace_id"]
url = kwargs["url"]
events = kwargs["events"]
name = kwargs.get("name", WEBHOOK)
secret = kwargs.get(SECRET)
timeout_ms = kwargs.get("timeout_ms", DEFAULT_WEBHOOK_TIMEOUT_MS)
max_retries = kwargs.get(MAX_RETRIES, DEFAULT_WEBHOOK_MAX_RETRIES)
now = utc_now()
return cls(
id=uuid4(),
workspace_id=workspace_id,
url=url,
events=frozenset(events),
name=name,
secret=secret,
timeout_ms=timeout_ms,
max_retries=max_retries,
created_at=now,
updated_at=now,
)
def subscribes_to(self, event_type: WebhookEventType) -> bool:
"""Check if this webhook subscribes to the given event type.
Args:
event_type: Event type to check.
Returns:
True if subscribed to this event.
"""
return event_type in self.events

View File

@@ -0,0 +1,153 @@
"""Webhook delivery entities.
Contains DeliveryResult and WebhookDelivery dataclasses for tracking
webhook delivery attempts and outcomes.
"""
from __future__ import annotations
from dataclasses import dataclass
from datetime import datetime
from uuid import UUID, uuid4
from noteflow.domain.constants.fields import DURATION_MS
from noteflow.domain.utils.time import utc_now
from noteflow.domain.webhooks.constants import (
DELIVERY_OUTCOME_FAILED,
DELIVERY_OUTCOME_SKIPPED,
DELIVERY_OUTCOME_SUCCEEDED,
)
from noteflow.domain.webhooks.payloads import WebhookPayloadDict
# Import WebhookEventType at runtime to avoid circular import
from noteflow.domain.webhooks.events import WebhookEventType
@dataclass(frozen=True, slots=True)
class DeliveryResult:
"""Result of a webhook delivery attempt.
Groups delivery outcome fields to reduce parameter count.
"""
status_code: int | None = None
"""HTTP response status code (None if request failed)."""
response_body: str | None = None
"""Response body (truncated if large)."""
error_message: str | None = None
"""Error description if delivery failed."""
attempt_count: int = 1
"""Number of delivery attempts made."""
duration_ms: int | None = None
"""Request duration in milliseconds."""
def to_delivery_kwargs(self) -> dict[str, int | str | None]:
"""Return kwargs for WebhookDelivery constructor.
Returns:
Dictionary with delivery result fields.
"""
return {
"status_code": self.status_code,
"response_body": self.response_body,
"error_message": self.error_message,
"attempt_count": self.attempt_count,
DURATION_MS: self.duration_ms,
}
@dataclass(frozen=True, slots=True)
class WebhookDelivery:
"""Record of a webhook delivery attempt.
Fields match WebhookDeliveryModel ORM for seamless conversion.
Attributes:
id: Unique delivery identifier.
webhook_id: Associated webhook config ID.
event_type: Type of event that triggered delivery.
payload: Event payload that was sent.
status_code: HTTP response status code (None if request failed).
response_body: Response body (truncated if large).
error_message: Error description if delivery failed.
attempt_count: Number of delivery attempts made.
duration_ms: Request duration in milliseconds.
delivered_at: When the delivery was attempted.
"""
id: UUID
webhook_id: UUID
event_type: WebhookEventType
payload: WebhookPayloadDict
status_code: int | None
response_body: str | None
error_message: str | None
attempt_count: int
duration_ms: int | None
delivered_at: datetime
@classmethod
def create(
cls,
webhook_id: UUID,
event_type: WebhookEventType,
payload: WebhookPayloadDict,
result: DeliveryResult | None = None,
) -> WebhookDelivery:
"""Create a new delivery record.
Args:
webhook_id: Associated webhook config ID.
event_type: Type of event.
payload: Event payload.
result: Optional delivery result (status, response, etc.).
Returns:
New WebhookDelivery with generated ID and timestamp.
"""
delivery_result = result or DeliveryResult()
return cls(
id=uuid4(),
webhook_id=webhook_id,
event_type=event_type,
payload=payload,
delivered_at=utc_now(),
**delivery_result.to_delivery_kwargs(),
)
@property
def succeeded(self) -> bool:
"""Check if delivery was successful.
Returns:
True if status code indicates success (2xx).
"""
return self.status_code is not None and 200 <= self.status_code < 3 * 100
@property
def was_attempted(self) -> bool:
"""Check if delivery was actually attempted.
Returns:
True if at least one attempt was made.
"""
return self.attempt_count > 0
@property
def log_outcome(self) -> tuple[str, str | int | None]:
"""Get outcome description for logging.
Returns:
Tuple of (outcome_type, detail) where:
- outcome_type is DELIVERY_OUTCOME_SUCCEEDED, DELIVERY_OUTCOME_FAILED, or DELIVERY_OUTCOME_SKIPPED
- detail is status_code (int) for success, error_message for failure/skip
"""
if self.succeeded:
return (DELIVERY_OUTCOME_SUCCEEDED, self.status_code)
if self.was_attempted:
return (DELIVERY_OUTCOME_FAILED, self.error_message)
return (DELIVERY_OUTCOME_SKIPPED, self.error_message)

View File

@@ -1,51 +1,11 @@
"""Webhook event types and domain entities.
"""Webhook event types.
Domain entities match the ORM models in
infrastructure/persistence/models/integrations/webhook.py for seamless conversion.
Contains the WebhookEventType enum defining available webhook events.
"""
from __future__ import annotations
from dataclasses import asdict, dataclass, field
from datetime import datetime
from enum import Enum
from typing import TYPE_CHECKING, NotRequired, Required, TypedDict, Unpack
from uuid import UUID, uuid4
from noteflow.domain.constants.fields import DURATION_MS, MAX_RETRIES, SECRET, WEBHOOK
from noteflow.domain.utils.time import utc_now
from noteflow.domain.webhooks.constants import (
DEFAULT_WEBHOOK_MAX_RETRIES,
DEFAULT_WEBHOOK_TIMEOUT_MS,
DELIVERY_OUTCOME_FAILED,
DELIVERY_OUTCOME_SKIPPED,
DELIVERY_OUTCOME_SUCCEEDED,
)
# Type alias for JSON-serializable webhook payload values
# Webhook payloads use flat structures with primitive types
type WebhookPayloadValue = str | int | float | bool | None
type WebhookPayloadDict = dict[str, WebhookPayloadValue]
if TYPE_CHECKING:
from typing import TypeVar
_PayloadT = TypeVar("_PayloadT", bound="WebhookPayload")
def payload_to_dict(payload: WebhookPayload) -> WebhookPayloadDict:
"""Convert webhook payload dataclass to typed dictionary.
Uses dataclasses.asdict() for conversion, filtering out None values
to keep payloads compact.
Args:
payload: Any WebhookPayload subclass instance.
Returns:
Dictionary with non-None field values.
"""
return {k: v for k, v in asdict(payload).items() if v is not None}
class WebhookEventType(Enum):
@@ -57,327 +17,3 @@ class WebhookEventType(Enum):
RECORDING_STOPPED = "recording.stopped"
ENTITIES_EXTRACTED = "entities.extracted" # GAP-W05
DIARIZATION_COMPLETED = "diarization.completed" # GAP-W05
@dataclass(frozen=True, slots=True)
class WebhookConfig:
"""Webhook configuration for event delivery.
Fields match WebhookConfigModel ORM for seamless conversion.
Attributes:
id: Unique webhook identifier.
workspace_id: Workspace this webhook belongs to.
url: Target URL for webhook delivery.
events: Set of event types this webhook is subscribed to.
name: Display name for the webhook.
secret: Optional HMAC signing secret.
enabled: Whether the webhook is active.
timeout_ms: HTTP request timeout in milliseconds.
max_retries: Maximum delivery retry attempts.
created_at: When the webhook was created.
updated_at: When the webhook was last modified.
"""
id: UUID
workspace_id: UUID
url: str
events: frozenset[WebhookEventType]
name: str = WEBHOOK
secret: str | None = None
enabled: bool = True
timeout_ms: int = DEFAULT_WEBHOOK_TIMEOUT_MS
max_retries: int = DEFAULT_WEBHOOK_MAX_RETRIES
created_at: datetime = field(default_factory=utc_now)
updated_at: datetime = field(default_factory=utc_now)
@classmethod
def create(
cls,
**kwargs: Unpack[WebhookConfigCreateKwargs],
) -> WebhookConfig:
"""Create a new webhook configuration.
Args:
**kwargs: Webhook config fields.
Returns:
New WebhookConfig with generated ID and timestamps.
"""
workspace_id = kwargs["workspace_id"]
url = kwargs["url"]
events = kwargs["events"]
name = kwargs.get("name", WEBHOOK)
secret = kwargs.get(SECRET)
timeout_ms = kwargs.get("timeout_ms", DEFAULT_WEBHOOK_TIMEOUT_MS)
max_retries = kwargs.get(MAX_RETRIES, DEFAULT_WEBHOOK_MAX_RETRIES)
now = utc_now()
return cls(
id=uuid4(),
workspace_id=workspace_id,
url=url,
events=frozenset(events),
name=name,
secret=secret,
timeout_ms=timeout_ms,
max_retries=max_retries,
created_at=now,
updated_at=now,
)
def subscribes_to(self, event_type: WebhookEventType) -> bool:
"""Check if this webhook subscribes to the given event type.
Args:
event_type: Event type to check.
Returns:
True if subscribed to this event.
"""
return event_type in self.events
@dataclass(frozen=True, slots=True)
class WebhookConfigCreateOptions:
"""Optional parameters for webhook config creation."""
name: str = WEBHOOK
secret: str | None = None
timeout_ms: int = DEFAULT_WEBHOOK_TIMEOUT_MS
max_retries: int = DEFAULT_WEBHOOK_MAX_RETRIES
class WebhookConfigCreateKwargs(TypedDict):
"""Keyword arguments for webhook config creation."""
workspace_id: Required[UUID]
url: Required[str]
events: Required[list[WebhookEventType]]
name: NotRequired[str]
secret: NotRequired[str | None]
timeout_ms: NotRequired[int]
max_retries: NotRequired[int]
@dataclass(frozen=True, slots=True)
class DeliveryResult:
"""Result of a webhook delivery attempt.
Groups delivery outcome fields to reduce parameter count.
"""
status_code: int | None = None
"""HTTP response status code (None if request failed)."""
response_body: str | None = None
"""Response body (truncated if large)."""
error_message: str | None = None
"""Error description if delivery failed."""
attempt_count: int = 1
"""Number of delivery attempts made."""
duration_ms: int | None = None
"""Request duration in milliseconds."""
def to_delivery_kwargs(self) -> dict[str, int | str | None]:
"""Return kwargs for WebhookDelivery constructor.
Returns:
Dictionary with delivery result fields.
"""
return {
"status_code": self.status_code,
"response_body": self.response_body,
"error_message": self.error_message,
"attempt_count": self.attempt_count,
DURATION_MS: self.duration_ms,
}
@dataclass(frozen=True, slots=True)
class WebhookDelivery:
"""Record of a webhook delivery attempt.
Fields match WebhookDeliveryModel ORM for seamless conversion.
Attributes:
id: Unique delivery identifier.
webhook_id: Associated webhook config ID.
event_type: Type of event that triggered delivery.
payload: Event payload that was sent.
status_code: HTTP response status code (None if request failed).
response_body: Response body (truncated if large).
error_message: Error description if delivery failed.
attempt_count: Number of delivery attempts made.
duration_ms: Request duration in milliseconds.
delivered_at: When the delivery was attempted.
"""
id: UUID
webhook_id: UUID
event_type: WebhookEventType
payload: WebhookPayloadDict
status_code: int | None
response_body: str | None
error_message: str | None
attempt_count: int
duration_ms: int | None
delivered_at: datetime
@classmethod
def create(
cls,
webhook_id: UUID,
event_type: WebhookEventType,
payload: WebhookPayloadDict,
result: DeliveryResult | None = None,
) -> WebhookDelivery:
"""Create a new delivery record.
Args:
webhook_id: Associated webhook config ID.
event_type: Type of event.
payload: Event payload.
result: Optional delivery result (status, response, etc.).
Returns:
New WebhookDelivery with generated ID and timestamp.
"""
delivery_result = result or DeliveryResult()
return cls(
id=uuid4(),
webhook_id=webhook_id,
event_type=event_type,
payload=payload,
delivered_at=utc_now(),
**delivery_result.to_delivery_kwargs(),
)
@property
def succeeded(self) -> bool:
"""Check if delivery was successful.
Returns:
True if status code indicates success (2xx).
"""
return self.status_code is not None and 200 <= self.status_code < 3 * 100
@property
def was_attempted(self) -> bool:
"""Check if delivery was actually attempted.
Returns:
True if at least one attempt was made.
"""
return self.attempt_count > 0
@property
def log_outcome(self) -> tuple[str, str | int | None]:
"""Get outcome description for logging.
Returns:
Tuple of (outcome_type, detail) where:
- outcome_type is DELIVERY_OUTCOME_SUCCEEDED, DELIVERY_OUTCOME_FAILED, or DELIVERY_OUTCOME_SKIPPED
- detail is status_code (int) for success, error_message for failure/skip
"""
if self.succeeded:
return (DELIVERY_OUTCOME_SUCCEEDED, self.status_code)
if self.was_attempted:
return (DELIVERY_OUTCOME_FAILED, self.error_message)
return (DELIVERY_OUTCOME_SKIPPED, self.error_message)
@dataclass(frozen=True, slots=True)
class WebhookPayload:
"""Base webhook event payload.
Use payload_to_dict() helper for JSON serialization.
Attributes:
event: Event type identifier string.
timestamp: ISO 8601 formatted event timestamp.
meeting_id: Associated meeting UUID as string.
"""
event: str
timestamp: str
meeting_id: str
@dataclass(frozen=True, slots=True)
class MeetingCompletedPayload(WebhookPayload):
"""Payload for meeting.completed event.
Attributes:
title: Meeting title.
duration_seconds: Total meeting duration.
segment_count: Number of transcript segments.
has_summary: Whether a summary exists.
"""
title: str
duration_seconds: float
segment_count: int
has_summary: bool
@dataclass(frozen=True, slots=True)
class SummaryGeneratedPayload(WebhookPayload):
"""Payload for summary.generated event.
Attributes:
title: Meeting title.
executive_summary: Summary executive overview text.
key_points_count: Number of key points in summary.
action_items_count: Number of action items in summary.
"""
title: str
executive_summary: str
key_points_count: int
action_items_count: int
@dataclass(frozen=True, slots=True)
class RecordingPayload(WebhookPayload):
"""Payload for recording.started and recording.stopped events.
Attributes:
title: Meeting title.
duration_seconds: Recording duration (only for stopped events).
"""
title: str
duration_seconds: float | None = None
@dataclass(frozen=True, slots=True)
class EntitiesExtractedPayload(WebhookPayload):
"""Payload for entities.extracted event (GAP-W05).
Attributes:
title: Meeting title.
entity_count: Number of entities extracted.
categories: List of entity categories found.
"""
title: str
entity_count: int
categories: str # Comma-separated list of categories
@dataclass(frozen=True, slots=True)
class DiarizationCompletedPayload(WebhookPayload):
"""Payload for diarization.completed event (GAP-W05).
Attributes:
title: Meeting title.
speaker_count: Number of distinct speakers detected.
segments_updated: Number of segments with speaker labels.
"""
title: str
speaker_count: int
segments_updated: int

View File

@@ -0,0 +1,122 @@
"""Webhook event payload dataclasses.
Contains typed payload structures for each webhook event type.
"""
from __future__ import annotations
from dataclasses import asdict, dataclass
# Type alias for JSON-serializable webhook payload values
# Webhook payloads use flat structures with primitive types
type WebhookPayloadValue = str | int | float | bool | None
type WebhookPayloadDict = dict[str, WebhookPayloadValue]
def payload_to_dict(payload: WebhookPayload) -> WebhookPayloadDict:
"""Convert webhook payload dataclass to typed dictionary.
Uses dataclasses.asdict() for conversion, filtering out None values
to keep payloads compact.
Args:
payload: Any WebhookPayload subclass instance.
Returns:
Dictionary with non-None field values.
"""
return {k: v for k, v in asdict(payload).items() if v is not None}
@dataclass(frozen=True, slots=True)
class WebhookPayload:
"""Base webhook event payload.
Use payload_to_dict() helper for JSON serialization.
Attributes:
event: Event type identifier string.
timestamp: ISO 8601 formatted event timestamp.
meeting_id: Associated meeting UUID as string.
"""
event: str
timestamp: str
meeting_id: str
@dataclass(frozen=True, slots=True)
class MeetingCompletedPayload(WebhookPayload):
"""Payload for meeting.completed event.
Attributes:
title: Meeting title.
duration_seconds: Total meeting duration.
segment_count: Number of transcript segments.
has_summary: Whether a summary exists.
"""
title: str
duration_seconds: float
segment_count: int
has_summary: bool
@dataclass(frozen=True, slots=True)
class SummaryGeneratedPayload(WebhookPayload):
"""Payload for summary.generated event.
Attributes:
title: Meeting title.
executive_summary: Summary executive overview text.
key_points_count: Number of key points in summary.
action_items_count: Number of action items in summary.
"""
title: str
executive_summary: str
key_points_count: int
action_items_count: int
@dataclass(frozen=True, slots=True)
class RecordingPayload(WebhookPayload):
"""Payload for recording.started and recording.stopped events.
Attributes:
title: Meeting title.
duration_seconds: Recording duration (only for stopped events).
"""
title: str
duration_seconds: float | None = None
@dataclass(frozen=True, slots=True)
class EntitiesExtractedPayload(WebhookPayload):
"""Payload for entities.extracted event (GAP-W05).
Attributes:
title: Meeting title.
entity_count: Number of entities extracted.
categories: List of entity categories found.
"""
title: str
entity_count: int
categories: str # Comma-separated list of categories
@dataclass(frozen=True, slots=True)
class DiarizationCompletedPayload(WebhookPayload):
"""Payload for diarization.completed event (GAP-W05).
Attributes:
title: Meeting title.
speaker_count: Number of distinct speakers detected.
segments_updated: Number of segments with speaker labels.
"""
title: str
speaker_count: int
segments_updated: int

View File

@@ -4,7 +4,7 @@ from __future__ import annotations
import queue
import threading
from collections.abc import Iterable, Sequence
from collections.abc import Iterable, Iterator, Sequence
from typing import TYPE_CHECKING, Protocol
if TYPE_CHECKING:
@@ -13,6 +13,7 @@ if TYPE_CHECKING:
from noteflow.grpc._client_mixins.converters import ProtoAnnotation, ProtoMeeting, ProtoSegment
from noteflow.grpc._types import ConnectionCallback, TranscriptCallback, TranscriptSegment
from noteflow.grpc.proto import noteflow_pb2
class ProtoListAnnotationsResponse(Protocol):
@@ -156,3 +157,10 @@ class ClientHost(Protocol):
def handle_stream_response(self, response: ProtoTranscriptUpdate) -> None:
"""Handle a single transcript update from the stream."""
...
def process_stream_responses(
self,
generator: Iterator[noteflow_pb2.AudioChunk],
) -> None:
"""Process stream responses until stop is requested."""
...

View File

@@ -154,15 +154,28 @@ class StreamingClientMixin:
generator = _audio_chunk_generator(self.audio_queue, self.stop_streaming_event)
try:
responses = self.stub.StreamTranscription(generator)
for response in responses:
if self.stop_streaming_event.is_set():
break
self.handle_stream_response(response)
self.process_stream_responses(generator)
except grpc.RpcError as e:
logger.error("Stream error: %s", e)
self.notify_connection(False, f"Stream error: {e}")
def process_stream_responses(
self: ClientHost,
generator: Iterator[noteflow_pb2.AudioChunk],
) -> None:
"""Process stream responses until stop is requested.
Args:
generator: Audio chunk generator.
"""
if not self.stub:
return
responses = self.stub.StreamTranscription(generator)
for response in responses:
if self.stop_streaming_event.is_set():
break
self.handle_stream_response(response)
def handle_stream_response(
self: ClientHost,
response: ProtoTranscriptUpdate,

View File

@@ -8,11 +8,11 @@ from typing import TYPE_CHECKING, Final
from noteflow.config.constants import DEFAULT_GRPC_PORT
if TYPE_CHECKING:
from noteflow.application.services.calendar_service import CalendarService
from noteflow.application.services.identity_service import IdentityService
from noteflow.application.services.calendar import CalendarService
from noteflow.application.services.identity import IdentityService
from noteflow.application.services.ner_service import NerService
from noteflow.application.services.project_service import ProjectService
from noteflow.application.services.summarization_service import SummarizationService
from noteflow.application.services.summarization import SummarizationService
from noteflow.application.services.webhook_service import WebhookService
from noteflow.infrastructure.diarization import DiarizationEngine

View File

@@ -2,7 +2,7 @@
from __future__ import annotations
from noteflow.application.services.identity_service import IdentityService
from noteflow.application.services.identity import IdentityService
_identity_service_instance: IdentityService | None = None

View File

@@ -0,0 +1,82 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Protocol
from noteflow.domain.ports.async_context import AsyncContextManager
if TYPE_CHECKING:
from noteflow.domain.ports.repositories import (
AnnotationRepository,
DiarizationJobRepository,
EntityRepository,
MeetingRepository,
PreferencesRepository,
SegmentRepository,
SummaryRepository,
WebhookRepository,
)
from noteflow.domain.ports.repositories.identity import (
ProjectMembershipRepository,
ProjectRepository,
WorkspaceRepository,
)
class AnnotationRepositoryProvider(AsyncContextManager, Protocol):
supports_annotations: bool
annotations: AnnotationRepository
meetings: MeetingRepository
async def commit(self) -> None: ...
class MeetingRepositoryProvider(AsyncContextManager, Protocol):
meetings: MeetingRepository
segments: SegmentRepository
summaries: SummaryRepository
diarization_jobs: DiarizationJobRepository
projects: ProjectRepository
workspaces: WorkspaceRepository
supports_diarization_jobs: bool
supports_projects: bool
supports_workspaces: bool
async def commit(self) -> None: ...
class PreferencesRepositoryProvider(AsyncContextManager, Protocol):
supports_preferences: bool
preferences: PreferencesRepository
async def commit(self) -> None: ...
class WebhooksRepositoryProvider(AsyncContextManager, Protocol):
supports_webhooks: bool
webhooks: WebhookRepository
async def commit(self) -> None: ...
class EntitiesRepositoryProvider(AsyncContextManager, Protocol):
supports_entities: bool
entities: EntityRepository
async def commit(self) -> None: ...
class DiarizationJobRepositoryProvider(AsyncContextManager, Protocol):
supports_diarization_jobs: bool
diarization_jobs: DiarizationJobRepository
async def commit(self) -> None: ...
class ProjectRepositoryProvider(AsyncContextManager, Protocol):
supports_projects: bool
supports_workspaces: bool
projects: ProjectRepository
project_memberships: ProjectMembershipRepository
workspaces: WorkspaceRepository
async def commit(self) -> None: ...

View File

@@ -0,0 +1,87 @@
"""Servicer core methods protocol definition."""
from __future__ import annotations
from typing import TYPE_CHECKING, Protocol
if TYPE_CHECKING:
from noteflow.domain.entities import Meeting
from noteflow.domain.identity.context import OperationContext
from noteflow.domain.ports.unit_of_work import UnitOfWork
from noteflow.infrastructure.auth.oidc_registry import OidcAuthService
from noteflow.infrastructure.persistence.unit_of_work import SqlAlchemyUnitOfWork
from ..meeting_store import MeetingStore
from ..stream_state import MeetingStreamState
from ._types import GrpcContext
class ServicerCoreMethods(Protocol):
"""Core helper methods shared across mixins."""
@property
def diarization_job_ttl_seconds(self) -> float:
"""Return diarization job TTL from settings."""
...
def use_database(self) -> bool:
"""Check if database persistence is configured."""
...
def get_memory_store(self) -> MeetingStore:
"""Get the in-memory store, raising if not configured."""
...
def get_operation_context(self, context: GrpcContext) -> OperationContext:
"""Build operation context from the gRPC request."""
...
def create_uow(self) -> SqlAlchemyUnitOfWork:
"""Create a new Unit of Work (database-backed)."""
...
def create_repository_provider(self) -> UnitOfWork:
"""Create a repository provider (database or memory backed)."""
...
def next_segment_id(self, meeting_id: str, fallback: int = 0) -> int:
"""Get and increment the next segment id for a meeting."""
...
def init_streaming_state(self, meeting_id: str, next_segment_id: int) -> None:
"""Initialize VAD, Segmenter, speaking state, and partial buffers."""
...
def cleanup_streaming_state(self, meeting_id: str) -> None:
"""Clean up streaming state for a meeting."""
...
def get_stream_state(self, meeting_id: str) -> MeetingStreamState | None:
"""Get consolidated streaming state for a meeting."""
...
def ensure_meeting_dek(self, meeting: Meeting) -> tuple[bytes, bytes, bool]:
"""Ensure meeting has a DEK, generating one if needed."""
...
def start_meeting_if_needed(self, meeting: Meeting) -> tuple[bool, str | None]:
"""Start recording on meeting if not already recording."""
...
def open_meeting_audio_writer(
self,
meeting_id: str,
dek: bytes,
wrapped_dek: bytes,
asset_path: str | None = None,
) -> None:
"""Open audio writer for a meeting."""
...
def close_audio_writer(self, meeting_id: str) -> None:
"""Close and remove the audio writer for a meeting."""
...
def get_oidc_service(self) -> OidcAuthService:
"""Get or create the OIDC auth service."""
...

View File

@@ -0,0 +1,139 @@
"""Servicer diarization methods protocol definition."""
from __future__ import annotations
import asyncio
from typing import TYPE_CHECKING, Protocol
if TYPE_CHECKING:
import numpy as np
from numpy.typing import NDArray
from noteflow.infrastructure.diarization import DiarizationSession, SpeakerTurn
from noteflow.infrastructure.persistence.repositories import DiarizationJob
from ..proto import noteflow_pb2
from ..stream_state import MeetingStreamState
from ._types import GrpcStatusContext
from .diarization._streaming import DiarizationChunkContext
class ServicerDiarizationMethods(Protocol):
"""Diarization helpers used by streaming and job mixins."""
async def prune_diarization_jobs(self) -> None:
"""Prune expired diarization jobs from in-memory cache."""
...
async def run_diarization_job(self, job_id: str, num_speakers: int | None) -> None:
"""Run background diarization job."""
...
async def collect_speaker_ids(self, meeting_id: str) -> list[str]:
"""Collect unique speaker IDs for a meeting."""
...
def run_diarization_inference(
self,
meeting_id: str,
num_speakers: int | None,
) -> list[SpeakerTurn]:
"""Run diarization inference synchronously."""
...
async def apply_diarization_turns(
self,
meeting_id: str,
turns: list[SpeakerTurn],
) -> int:
"""Apply diarization turns to meeting segments."""
...
async def refine_speaker_diarization(
self,
meeting_id: str,
num_speakers: int | None = None,
) -> int:
"""Run post-meeting speaker diarization refinement."""
...
async def update_job_completed(
self,
job_id: str,
job: DiarizationJob | None,
updated_count: int,
speaker_ids: list[str],
) -> None:
"""Update job status to COMPLETED."""
...
async def handle_job_timeout(
self,
job_id: str,
job: DiarizationJob | None,
meeting_id: str | None,
) -> None:
"""Handle job timeout."""
...
async def handle_job_cancelled(
self,
job_id: str,
job: DiarizationJob | None,
meeting_id: str | None,
) -> None:
"""Handle job cancellation."""
...
async def handle_job_failed(
self,
job_id: str,
job: DiarizationJob | None,
meeting_id: str | None,
exc: Exception,
) -> None:
"""Handle job failure."""
...
async def start_diarization_job(
self,
request: noteflow_pb2.RefineSpeakerDiarizationRequest,
context: GrpcStatusContext,
) -> noteflow_pb2.RefineSpeakerDiarizationResponse:
"""Start a new diarization refinement job."""
...
async def persist_streaming_turns(
self,
meeting_id: str,
new_turns: list[SpeakerTurn],
) -> None:
"""Persist streaming turns to database (fire-and-forget)."""
...
async def process_streaming_diarization(
self,
meeting_id: str,
audio: NDArray[np.float32],
) -> None:
"""Process audio chunk for streaming diarization (best-effort)."""
...
async def ensure_diarization_session(
self,
meeting_id: str,
state: MeetingStreamState,
loop: asyncio.AbstractEventLoop,
) -> DiarizationSession | None:
"""Return an initialized diarization session or None on failure."""
...
async def process_diarization_chunk(
self,
context: DiarizationChunkContext,
session: DiarizationSession,
audio: NDArray[np.float32],
loop: asyncio.AbstractEventLoop,
) -> list[SpeakerTurn] | None:
"""Process a diarization chunk, returning new turns or None on failure."""
...

View File

@@ -0,0 +1,182 @@
"""Servicer other methods protocol definitions (webhook, preferences, streaming, summarization, sync)."""
from __future__ import annotations
from typing import TYPE_CHECKING, Protocol
if TYPE_CHECKING:
from collections.abc import AsyncIterator
from uuid import UUID
from noteflow.domain.entities import Integration, Meeting, Segment, Summary, SyncRun
from noteflow.domain.ports.unit_of_work import UnitOfWork
from noteflow.domain.value_objects import MeetingId
from noteflow.grpc._mixins.preferences import PreferencesRepositoryProvider
from noteflow.infrastructure.persistence.repositories.preferences_repo import (
PreferenceWithMetadata,
)
from ..proto import noteflow_pb2
from ._types import GrpcContext
from .streaming._types import StreamSessionInit
class ServicerWebhookMethods(Protocol):
"""Webhook helpers."""
async def fire_stop_webhooks(self, meeting: Meeting) -> None:
"""Trigger webhooks for meeting stop (fire-and-forget)."""
...
class ServicerPreferencesMethods(Protocol):
"""Preferences helpers."""
async def decode_and_validate_prefs(
self,
request: noteflow_pb2.SetPreferencesRequest,
context: GrpcContext,
) -> dict[str, object]:
"""Decode and validate JSON preferences from request."""
...
async def apply_preferences(
self,
repo: PreferencesRepositoryProvider,
request: noteflow_pb2.SetPreferencesRequest,
current_prefs: list[PreferenceWithMetadata],
decoded_prefs: dict[str, object],
) -> None:
"""Apply preferences based on merge mode."""
...
class ServicerStreamingMethods(Protocol):
"""Streaming helpers."""
async def init_stream_for_meeting(
self,
meeting_id: str,
context: GrpcContext,
) -> StreamSessionInit | None:
"""Initialize streaming for a meeting."""
...
def process_stream_chunk(
self,
meeting_id: str,
chunk: noteflow_pb2.AudioChunk,
context: GrpcContext,
) -> AsyncIterator[noteflow_pb2.TranscriptUpdate]:
"""Process a single audio chunk from the stream."""
...
def flush_segmenter(
self,
meeting_id: str,
) -> AsyncIterator[noteflow_pb2.TranscriptUpdate]:
"""Flush remaining audio from segmenter at stream end."""
...
async def prepare_stream_chunk(
self,
current_meeting_id: str | None,
initialized_meeting_id: str | None,
chunk: noteflow_pb2.AudioChunk,
context: GrpcContext,
) -> tuple[str, str | None] | None:
"""Validate and initialize streaming state for a chunk."""
...
def yield_chunk_updates(
self,
meeting_id: str,
chunk: noteflow_pb2.AudioChunk,
context: GrpcContext,
) -> AsyncIterator[noteflow_pb2.TranscriptUpdate]:
"""Yield transcript updates from processing a single chunk."""
...
def flush_remaining_audio(
self,
meeting_id: str | None,
) -> AsyncIterator[noteflow_pb2.TranscriptUpdate]:
"""Flush any remaining audio from segmenter at stream end."""
...
class ServicerSummarizationMethods(Protocol):
"""Summarization helpers."""
async def summarize_or_placeholder(
self,
meeting_id: MeetingId,
segments: list[Segment],
style_prompt: str | None = None,
) -> Summary:
"""Try to summarize via service, fallback to placeholder on failure."""
...
def generate_placeholder_summary(
self,
meeting_id: MeetingId,
segments: list[Segment],
) -> Summary:
"""Generate a lightweight placeholder summary when summarization fails."""
...
class ServicerSyncMethods(Protocol):
"""Sync helpers."""
def ensure_sync_runs_cache(self) -> dict[UUID, SyncRun]:
"""Ensure the sync runs cache exists."""
...
def cache_sync_run(self, sync_run: SyncRun) -> None:
"""Cache a sync run with timestamp tracking (Sprint GAP-002)."""
...
def get_sync_run_expires_at(self, sync_run_id: UUID) -> str | None:
"""Get expiry timestamp for a cached sync run (Sprint GAP-002)."""
...
async def resolve_integration(
self,
uow: UnitOfWork,
integration_id: UUID,
context: GrpcContext,
request: noteflow_pb2.StartIntegrationSyncRequest,
) -> tuple[Integration | None, UUID]:
"""Resolve integration by ID with provider fallback."""
...
async def perform_sync(
self,
integration_id: UUID,
sync_run_id: UUID,
provider: str,
) -> None:
"""Perform the actual sync operation (background task)."""
...
async def execute_sync_fetch(self, provider: str) -> int:
"""Execute the calendar fetch and return items count."""
...
async def complete_sync_run(
self,
integration_id: UUID,
sync_run_id: UUID,
items_synced: int,
) -> SyncRun | None:
"""Mark sync run as complete and update integration last_sync."""
...
async def fail_sync_run(
self,
sync_run_id: UUID,
error_message: str,
) -> SyncRun | None:
"""Mark sync run as failed with error message."""
...

View File

@@ -0,0 +1,43 @@
from __future__ import annotations
from typing import Protocol
from ._servicer_core_methods import ServicerCoreMethods
from ._servicer_diarization_methods import ServicerDiarizationMethods
from ._servicer_other_methods import (
ServicerPreferencesMethods,
ServicerStreamingMethods,
ServicerSummarizationMethods,
ServicerSyncMethods,
ServicerWebhookMethods,
)
from ._servicer_state import ServicerState
class ServicerHost(
ServicerState,
ServicerCoreMethods,
ServicerDiarizationMethods,
ServicerWebhookMethods,
ServicerPreferencesMethods,
ServicerStreamingMethods,
ServicerSummarizationMethods,
ServicerSyncMethods,
Protocol,
):
"""Combined protocol for servicer host interface."""
pass
__all__ = [
"ServicerHost",
"ServicerCoreMethods",
"ServicerDiarizationMethods",
"ServicerPreferencesMethods",
"ServicerStreamingMethods",
"ServicerSummarizationMethods",
"ServicerSyncMethods",
"ServicerWebhookMethods",
"ServicerState",
]

View File

@@ -0,0 +1,94 @@
"""Servicer state protocol definition."""
from __future__ import annotations
import asyncio
from pathlib import Path
from typing import TYPE_CHECKING, ClassVar, Final, Protocol
if TYPE_CHECKING:
from collections import deque
from datetime import datetime
from uuid import UUID
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
from noteflow.application.services.calendar import CalendarService
from noteflow.application.services.identity import IdentityService
from noteflow.application.services.ner_service import NerService
from noteflow.application.services.project_service import ProjectService
from noteflow.application.services.summarization import SummarizationService
from noteflow.application.services.webhook_service import WebhookService
from noteflow.domain.entities import SyncRun
from noteflow.infrastructure.asr import FasterWhisperEngine, Segmenter, StreamingVad
from noteflow.infrastructure.audio.writer import MeetingAudioWriter
from noteflow.infrastructure.auth.oidc_registry import OidcAuthService
from noteflow.infrastructure.diarization import DiarizationEngine
from noteflow.infrastructure.persistence.repositories import DiarizationJob
from noteflow.infrastructure.persistence.unit_of_work import SqlAlchemyUnitOfWork
from noteflow.infrastructure.security.crypto import AesGcmCryptoBox
from ..meeting_store import MeetingStore
from ..stream_state import MeetingStreamState
class ServicerState(Protocol):
"""Protocol defining servicer state attributes."""
# Configuration
session_factory: async_sessionmaker[AsyncSession] | None
memory_store: MeetingStore | None
meetings_dir: Path
crypto: AesGcmCryptoBox
# Engines and services
asr_engine: FasterWhisperEngine | None
diarization_engine: DiarizationEngine | None
summarization_service: SummarizationService | None
ner_service: NerService | None
calendar_service: CalendarService | None
webhook_service: WebhookService | None
project_service: ProjectService | None
identity_service: IdentityService
diarization_refinement_enabled: bool
# Audio writers
audio_writers: dict[str, MeetingAudioWriter]
audio_write_failed: set[str]
# VAD and segmentation state per meeting
vad_instances: dict[str, StreamingVad]
segmenters: dict[str, Segmenter]
segment_counters: dict[str, int]
stream_formats: dict[str, tuple[int, int]]
active_streams: set[str]
stop_requested: set[str] # Meeting IDs with pending stop requests
# Chunk sequence tracking for acknowledgments
chunk_sequences: dict[str, int] # Highest received sequence per meeting
chunk_counts: dict[str, int] # Chunks since last ack (emit ack every 5)
chunk_receipt_times: dict[str, deque[float]] # Receipt timestamps per meeting
pending_chunks: dict[str, int] # Pending chunks counter per meeting
# Consolidated per-meeting streaming state (single lookup replaces 13+ dict accesses)
stream_states: dict[str, MeetingStreamState]
# Background diarization task references (for cancellation)
diarization_jobs: dict[str, DiarizationJob]
diarization_tasks: dict[str, asyncio.Task[None]]
diarization_lock: asyncio.Lock
stream_init_lock: asyncio.Lock # Guards concurrent stream initialization
# Integration sync runs cache
sync_runs: dict[UUID, SyncRun]
# Track when each sync run was cached (Sprint GAP-002: State Synchronization)
sync_run_cache_times: dict[UUID, datetime]
# Constants
DEFAULT_SAMPLE_RATE: Final[int]
SUPPORTED_SAMPLE_RATES: ClassVar[list[int]] # Converted to frozenset when passed to validate_stream_format
PARTIAL_CADENCE_SECONDS: Final[float]
MIN_PARTIAL_AUDIO_SECONDS: Final[float]
# OIDC service
oidc_service: OidcAuthService | None

View File

@@ -4,7 +4,7 @@ from __future__ import annotations
from typing import TYPE_CHECKING
from noteflow.application.services.calendar_service import CalendarService, CalendarServiceError
from noteflow.application.services.calendar import CalendarService, CalendarServiceError
from noteflow.domain.constants.fields import CALENDAR
from noteflow.domain.entities.integration import IntegrationStatus
from noteflow.domain.ports.calendar import CalendarEventInfo, OAuthConnectionInfo

View File

@@ -4,7 +4,7 @@ from __future__ import annotations
from noteflow.domain.entities import SyncRun
from noteflow.domain.entities.named_entity import NamedEntity
from noteflow.domain.webhooks.events import WebhookConfig, WebhookDelivery
from noteflow.domain.webhooks import WebhookConfig, WebhookDelivery
from noteflow.infrastructure.logging import LogEntry
from noteflow.infrastructure.metrics import PerformanceMetrics

View File

@@ -20,7 +20,7 @@ if TYPE_CHECKING:
from noteflow.domain.entities.meeting import Meeting, MeetingId
from noteflow.domain.entities.project import Project
from noteflow.domain.ports.unit_of_work import UnitOfWork
from noteflow.domain.webhooks.events import WebhookConfig
from noteflow.domain.webhooks import WebhookConfig
# Entity type names for abort_not_found calls
ENTITY_MEETING = ENTITY_MEETING_NAME

View File

@@ -18,7 +18,7 @@ if TYPE_CHECKING:
from collections.abc import Callable
from uuid import UUID
from noteflow.application.services.identity_service import IdentityService
from noteflow.application.services.identity import IdentityService
from noteflow.domain.identity.context import OperationContext
from noteflow.domain.identity.entities import Workspace, WorkspaceMembership

View File

@@ -1,420 +0,0 @@
"""OIDC provider management mixin for gRPC service."""
from __future__ import annotations
from collections.abc import Sequence
from dataclasses import dataclass
from typing import cast
from uuid import UUID
from noteflow.config.constants import ERROR_INVALID_WORKSPACE_ID_FORMAT
from noteflow.domain.auth.oidc import (
ClaimMapping,
OidcProviderConfig,
OidcProviderPreset,
OidcProviderRegistration,
)
from noteflow.domain.constants.fields import ALLOWED_GROUPS, CLAIM_MAPPING, REQUIRE_EMAIL_VERIFIED
from noteflow.infrastructure.auth.oidc_discovery import OidcDiscoveryError
from noteflow.infrastructure.auth.oidc_registry import (
PROVIDER_PRESETS,
OidcAuthService,
ProviderPresetConfig,
)
from ..proto import noteflow_pb2
from ._types import GrpcContext
from .converters import oidc_provider_to_proto, proto_to_claim_mapping
from .errors import abort_invalid_argument, abort_not_found, parse_workspace_id
# Error message constants
_ENTITY_OIDC_PROVIDER = "OIDC Provider"
_ERR_INVALID_PROVIDER_ID = "Invalid provider_id format"
_ERR_INVALID_PRESET = "Invalid preset value"
# Field name constants
_FIELD_NAME = "name"
_FIELD_SCOPES = "scopes"
_FIELD_ENABLED = "enabled"
def _parse_provider_id(provider_id_str: str) -> UUID:
"""Parse provider ID string to UUID, raising ValueError if invalid."""
return UUID(provider_id_str)
def _parse_preset(preset_str: str) -> OidcProviderPreset:
"""Parse preset string to OidcProviderPreset enum."""
return OidcProviderPreset(preset_str.lower())
async def _validate_register_request(
request: noteflow_pb2.RegisterOidcProviderRequest,
context: GrpcContext,
) -> None:
"""Validate required fields in RegisterOidcProvider request."""
if not request.name:
await abort_invalid_argument(context, "name is required")
if not request.issuer_url:
await abort_invalid_argument(context, "issuer_url is required")
if not request.issuer_url.startswith(("http://", "https://")):
await abort_invalid_argument(
context, "issuer_url must start with http:// or https://"
)
if not request.client_id:
await abort_invalid_argument(context, "client_id is required")
@dataclass(frozen=True)
class OidcCustomConfig:
"""Optional configuration overrides for OIDC providers."""
claim_mapping: ClaimMapping | None
scopes: tuple[str, ...] | None
allowed_groups: tuple[str, ...] | None
require_email_verified: bool | None
def _parse_register_options(
request: noteflow_pb2.RegisterOidcProviderRequest,
) -> OidcCustomConfig:
"""Parse optional fields from RegisterOidcProvider request."""
claim_mapping: ClaimMapping | None = None
if request.HasField(CLAIM_MAPPING):
claim_mapping = proto_to_claim_mapping(request.claim_mapping)
scopes_values = cast(Sequence[str], request.scopes)
scopes = tuple(scopes_values) if scopes_values else None
allowed_groups: tuple[str, ...] | None = None
if allowed_values := cast(Sequence[str], request.allowed_groups):
allowed_groups = tuple(allowed_values)
require_email_verified = (
request.require_email_verified
if request.HasField(REQUIRE_EMAIL_VERIFIED)
else None
)
return OidcCustomConfig(
claim_mapping=claim_mapping,
scopes=scopes,
allowed_groups=allowed_groups,
require_email_verified=require_email_verified,
)
def _apply_custom_provider_config(
provider: OidcProviderConfig,
config: OidcCustomConfig,
) -> None:
"""Apply custom configuration options to a registered provider."""
if config.claim_mapping:
object.__setattr__(provider, CLAIM_MAPPING, config.claim_mapping)
if config.scopes:
object.__setattr__(provider, _FIELD_SCOPES, config.scopes)
if config.allowed_groups:
object.__setattr__(provider, ALLOWED_GROUPS, config.allowed_groups)
if config.require_email_verified is not None:
object.__setattr__(provider, REQUIRE_EMAIL_VERIFIED, config.require_email_verified)
def _apply_update_request_to_provider(
provider: OidcProviderConfig,
request: noteflow_pb2.UpdateOidcProviderRequest,
) -> None:
"""Apply update request fields to provider config.
Mutates the provider in place using object.__setattr__ since
OidcProviderConfig is a frozen dataclass.
Args:
provider: The provider config to update.
request: The gRPC update request with optional field values.
"""
if request.HasField(_FIELD_NAME):
object.__setattr__(provider, _FIELD_NAME, request.name)
if scopes_values := cast(Sequence[str], request.scopes):
object.__setattr__(provider, _FIELD_SCOPES, tuple(scopes_values))
if request.HasField(CLAIM_MAPPING):
object.__setattr__(provider, CLAIM_MAPPING, proto_to_claim_mapping(request.claim_mapping))
if allowed_values := cast(Sequence[str], request.allowed_groups):
object.__setattr__(provider, ALLOWED_GROUPS, tuple(allowed_values))
if request.HasField(REQUIRE_EMAIL_VERIFIED):
object.__setattr__(provider, REQUIRE_EMAIL_VERIFIED, request.require_email_verified)
if request.HasField(_FIELD_ENABLED):
if request.enabled:
provider.enable()
else:
provider.disable()
def _preset_config_to_proto(
preset_config: ProviderPresetConfig,
) -> noteflow_pb2.OidcPresetProto:
"""Convert a preset configuration to protobuf message.
Args:
preset_config: The preset configuration from PROVIDER_PRESETS values.
Returns:
The protobuf OidcPresetProto message.
"""
return noteflow_pb2.OidcPresetProto(
preset=preset_config.preset.value,
display_name=preset_config.display_name,
description=preset_config.description,
default_scopes=list(preset_config.default_scopes),
documentation_url=preset_config.documentation_url or "",
notes=preset_config.notes or "",
)
async def _refresh_single_provider(
oidc_service: OidcAuthService,
provider_id: UUID,
context: GrpcContext,
) -> noteflow_pb2.RefreshOidcDiscoveryResponse:
"""Refresh OIDC discovery for a single provider.
Args:
oidc_service: The OIDC auth service.
provider_id: The provider ID to refresh.
context: The gRPC context for error handling.
Returns:
The refresh response with results for the single provider.
"""
provider = oidc_service.registry.get_provider(provider_id)
if provider is None:
await abort_not_found(context, _ENTITY_OIDC_PROVIDER, str(provider_id))
return noteflow_pb2.RefreshOidcDiscoveryResponse()
try:
await oidc_service.registry.refresh_discovery(provider)
return noteflow_pb2.RefreshOidcDiscoveryResponse(
results={str(provider_id): ""},
success_count=1,
failure_count=0,
)
except OidcDiscoveryError as e:
return noteflow_pb2.RefreshOidcDiscoveryResponse(
results={str(provider_id): str(e)},
success_count=0,
failure_count=1,
)
def _build_bulk_refresh_response(
results: dict[UUID, str | None],
) -> noteflow_pb2.RefreshOidcDiscoveryResponse:
"""Build response for bulk OIDC discovery refresh.
Args:
results: Mapping of provider IDs to error messages (None for success).
Returns:
The refresh response with aggregated results.
"""
results_str = {str(k): v or "" for k, v in results.items()}
success_count = sum(v is None for v in results.values())
failure_count = sum(v is not None for v in results.values())
return noteflow_pb2.RefreshOidcDiscoveryResponse(
results=results_str,
success_count=success_count,
failure_count=failure_count,
)
class OidcMixin:
"""Mixin providing OIDC provider management operations.
Requires host to implement OidcServicer protocol.
OIDC providers are stored in the in-memory registry (not database).
"""
oidc_service: OidcAuthService | None
def get_oidc_service(self) -> OidcAuthService:
"""Get or create the OIDC auth service."""
if self.oidc_service is None:
self.oidc_service = OidcAuthService()
assert self.oidc_service is not None # Help type checker
return self.oidc_service
async def RegisterOidcProvider(
self,
request: noteflow_pb2.RegisterOidcProviderRequest,
context: GrpcContext,
) -> noteflow_pb2.OidcProviderProto:
"""Register a new OIDC provider."""
await _validate_register_request(request, context)
# Parse preset
try:
preset = _parse_preset(request.preset) if request.preset else OidcProviderPreset.CUSTOM
except ValueError:
await abort_invalid_argument(context, _ERR_INVALID_PRESET)
return noteflow_pb2.OidcProviderProto() # unreachable
# Parse workspace ID
try:
workspace_id = UUID(request.workspace_id) if request.workspace_id else UUID(int=0)
except ValueError:
await abort_invalid_argument(context, ERROR_INVALID_WORKSPACE_ID_FORMAT)
return noteflow_pb2.OidcProviderProto() # unreachable
custom_config = _parse_register_options(request)
# Register provider
oidc_service = self.get_oidc_service()
try:
registration = OidcProviderRegistration(
workspace_id=workspace_id,
name=request.name,
issuer_url=request.issuer_url,
client_id=request.client_id,
client_secret=(
request.client_secret
if request.HasField("client_secret")
else None
),
preset=preset,
)
provider, warnings = await oidc_service.register_provider(registration)
_apply_custom_provider_config(provider, custom_config)
return oidc_provider_to_proto(provider, warnings)
except OidcDiscoveryError as e:
await abort_invalid_argument(context, f"OIDC discovery failed: {e}")
return noteflow_pb2.OidcProviderProto() # unreachable
async def ListOidcProviders(
self,
request: noteflow_pb2.ListOidcProvidersRequest,
context: GrpcContext,
) -> noteflow_pb2.ListOidcProvidersResponse:
"""List all OIDC providers."""
# Parse optional workspace filter
workspace_id: UUID | None = None
if request.HasField("workspace_id"):
workspace_id = await parse_workspace_id(request.workspace_id, context)
oidc_service = self.get_oidc_service()
providers = oidc_service.registry.list_providers(
workspace_id=workspace_id,
enabled_only=request.enabled_only,
)
return noteflow_pb2.ListOidcProvidersResponse(
providers=[oidc_provider_to_proto(p) for p in providers],
total_count=len(providers),
)
async def GetOidcProvider(
self,
request: noteflow_pb2.GetOidcProviderRequest,
context: GrpcContext,
) -> noteflow_pb2.OidcProviderProto:
"""Get a specific OIDC provider by ID."""
try:
provider_id = _parse_provider_id(request.provider_id)
except ValueError:
await abort_invalid_argument(context, _ERR_INVALID_PROVIDER_ID)
return noteflow_pb2.OidcProviderProto() # unreachable
oidc_service = self.get_oidc_service()
provider = oidc_service.registry.get_provider(provider_id)
if provider is None:
await abort_not_found(context, _ENTITY_OIDC_PROVIDER, str(provider_id))
return noteflow_pb2.OidcProviderProto() # unreachable
return oidc_provider_to_proto(provider)
async def UpdateOidcProvider(
self,
request: noteflow_pb2.UpdateOidcProviderRequest,
context: GrpcContext,
) -> noteflow_pb2.OidcProviderProto:
"""Update an existing OIDC provider."""
try:
provider_id = _parse_provider_id(request.provider_id)
except ValueError:
await abort_invalid_argument(context, _ERR_INVALID_PROVIDER_ID)
return noteflow_pb2.OidcProviderProto() # unreachable
oidc_service = self.get_oidc_service()
provider = oidc_service.registry.get_provider(provider_id)
if provider is None:
await abort_not_found(context, _ENTITY_OIDC_PROVIDER, str(provider_id))
return noteflow_pb2.OidcProviderProto() # unreachable
_apply_update_request_to_provider(provider, request)
return oidc_provider_to_proto(provider)
async def DeleteOidcProvider(
self,
request: noteflow_pb2.DeleteOidcProviderRequest,
context: GrpcContext,
) -> noteflow_pb2.DeleteOidcProviderResponse:
"""Delete an OIDC provider."""
try:
provider_id = _parse_provider_id(request.provider_id)
except ValueError:
await abort_invalid_argument(context, _ERR_INVALID_PROVIDER_ID)
return noteflow_pb2.DeleteOidcProviderResponse(success=False)
oidc_service = self.get_oidc_service()
success = oidc_service.registry.remove_provider(provider_id)
if not success:
await abort_not_found(context, _ENTITY_OIDC_PROVIDER, str(provider_id))
return noteflow_pb2.DeleteOidcProviderResponse(success=success)
async def RefreshOidcDiscovery(
self,
request: noteflow_pb2.RefreshOidcDiscoveryRequest,
context: GrpcContext,
) -> noteflow_pb2.RefreshOidcDiscoveryResponse:
"""Refresh OIDC discovery for one or all providers."""
oidc_service = self.get_oidc_service()
# Single provider refresh
if request.HasField("provider_id"):
try:
provider_id = _parse_provider_id(request.provider_id)
except ValueError:
await abort_invalid_argument(context, _ERR_INVALID_PROVIDER_ID)
return noteflow_pb2.RefreshOidcDiscoveryResponse()
return await _refresh_single_provider(oidc_service, provider_id, context)
# Bulk refresh
workspace_id: UUID | None = None
if request.HasField("workspace_id"):
workspace_id = await parse_workspace_id(request.workspace_id, context)
results = await oidc_service.refresh_all_discovery(workspace_id=workspace_id)
return _build_bulk_refresh_response(results)
async def ListOidcPresets(
self,
request: noteflow_pb2.ListOidcPresetsRequest,
context: GrpcContext,
) -> noteflow_pb2.ListOidcPresetsResponse:
"""List available OIDC provider presets."""
presets = [_preset_config_to_proto(config) for config in PROVIDER_PRESETS.values()]
return noteflow_pb2.ListOidcPresetsResponse(presets=presets)

View File

@@ -0,0 +1,7 @@
"""OIDC provider management mixin package."""
from __future__ import annotations
from .oidc_mixin import OidcMixin
__all__ = ["OidcMixin"]

View File

@@ -0,0 +1,225 @@
"""Helper functions for OIDC provider management."""
from __future__ import annotations
from collections.abc import Sequence
from dataclasses import dataclass
from typing import cast
from uuid import UUID
from noteflow.domain.auth.oidc import ClaimMapping, OidcProviderConfig, OidcProviderPreset
from noteflow.domain.constants.fields import ALLOWED_GROUPS, CLAIM_MAPPING, REQUIRE_EMAIL_VERIFIED
from noteflow.infrastructure.auth._presets import ProviderPresetConfig
from noteflow.infrastructure.auth.oidc_discovery import OidcDiscoveryError
from noteflow.infrastructure.auth.oidc_registry import OidcAuthService
from ...proto import noteflow_pb2
from .._types import GrpcContext
from ..converters import proto_to_claim_mapping
from ..errors import abort_invalid_argument, abort_not_found
# Error message constants (exported for use in mixin)
ENTITY_OIDC_PROVIDER = "OIDC Provider"
ERR_INVALID_PROVIDER_ID = "Invalid provider_id format"
ERR_INVALID_PRESET = "Invalid preset value"
# Field name constants
_FIELD_NAME = "name"
_FIELD_SCOPES = "scopes"
_FIELD_ENABLED = "enabled"
def parse_provider_id(provider_id_str: str) -> UUID:
"""Parse provider ID string to UUID, raising ValueError if invalid."""
return UUID(provider_id_str)
def parse_preset(preset_str: str) -> OidcProviderPreset:
"""Parse preset string to OidcProviderPreset enum."""
return OidcProviderPreset(preset_str.lower())
async def validate_register_request(
request: noteflow_pb2.RegisterOidcProviderRequest,
context: GrpcContext,
) -> None:
"""Validate required fields in RegisterOidcProvider request."""
if not request.name:
await abort_invalid_argument(context, "name is required")
if not request.issuer_url:
await abort_invalid_argument(context, "issuer_url is required")
if not request.issuer_url.startswith(("http://", "https://")):
await abort_invalid_argument(
context, "issuer_url must start with http:// or https://"
)
if not request.client_id:
await abort_invalid_argument(context, "client_id is required")
@dataclass(frozen=True)
class OidcCustomConfig:
"""Optional configuration overrides for OIDC providers."""
claim_mapping: ClaimMapping | None
scopes: tuple[str, ...] | None
allowed_groups: tuple[str, ...] | None
require_email_verified: bool | None
def parse_register_options(
request: noteflow_pb2.RegisterOidcProviderRequest,
) -> OidcCustomConfig:
"""Parse optional fields from RegisterOidcProvider request."""
claim_mapping: ClaimMapping | None = None
if request.HasField(CLAIM_MAPPING):
claim_mapping = proto_to_claim_mapping(request.claim_mapping)
scopes_values = cast(Sequence[str], request.scopes)
scopes = tuple(scopes_values) if scopes_values else None
allowed_groups: tuple[str, ...] | None = None
if allowed_values := cast(Sequence[str], request.allowed_groups):
allowed_groups = tuple(allowed_values)
require_email_verified = (
request.require_email_verified
if request.HasField(REQUIRE_EMAIL_VERIFIED)
else None
)
return OidcCustomConfig(
claim_mapping=claim_mapping,
scopes=scopes,
allowed_groups=allowed_groups,
require_email_verified=require_email_verified,
)
def apply_custom_provider_config(
provider: OidcProviderConfig,
config: OidcCustomConfig,
) -> None:
"""Apply custom configuration options to a registered provider."""
if config.claim_mapping:
object.__setattr__(provider, CLAIM_MAPPING, config.claim_mapping)
if config.scopes:
object.__setattr__(provider, _FIELD_SCOPES, config.scopes)
if config.allowed_groups:
object.__setattr__(provider, ALLOWED_GROUPS, config.allowed_groups)
if config.require_email_verified is not None:
object.__setattr__(provider, REQUIRE_EMAIL_VERIFIED, config.require_email_verified)
def apply_update_request_to_provider(
provider: OidcProviderConfig,
request: noteflow_pb2.UpdateOidcProviderRequest,
) -> None:
"""Apply update request fields to provider config.
Mutates the provider in place using object.__setattr__ since
OidcProviderConfig is a frozen dataclass.
Args:
provider: The provider config to update.
request: The gRPC update request with optional field values.
"""
if request.HasField(_FIELD_NAME):
object.__setattr__(provider, _FIELD_NAME, request.name)
if scopes_values := cast(Sequence[str], request.scopes):
object.__setattr__(provider, _FIELD_SCOPES, tuple(scopes_values))
if request.HasField(CLAIM_MAPPING):
object.__setattr__(provider, CLAIM_MAPPING, proto_to_claim_mapping(request.claim_mapping))
if allowed_values := cast(Sequence[str], request.allowed_groups):
object.__setattr__(provider, ALLOWED_GROUPS, tuple(allowed_values))
if request.HasField(REQUIRE_EMAIL_VERIFIED):
object.__setattr__(provider, REQUIRE_EMAIL_VERIFIED, request.require_email_verified)
if request.HasField(_FIELD_ENABLED):
if request.enabled:
provider.enable()
else:
provider.disable()
def preset_config_to_proto(
preset_config: ProviderPresetConfig,
) -> noteflow_pb2.OidcPresetProto:
"""Convert a preset configuration to protobuf message.
Args:
preset_config: The preset configuration from PROVIDER_PRESETS values.
Returns:
The protobuf OidcPresetProto message.
"""
return noteflow_pb2.OidcPresetProto(
preset=preset_config.preset.value,
display_name=preset_config.display_name,
description=preset_config.description,
default_scopes=list(preset_config.default_scopes),
documentation_url=preset_config.documentation_url or "",
notes=preset_config.notes or "",
)
async def refresh_single_provider(
oidc_service: OidcAuthService,
provider_id: UUID,
context: GrpcContext,
) -> noteflow_pb2.RefreshOidcDiscoveryResponse:
"""Refresh OIDC discovery for a single provider.
Args:
oidc_service: The OIDC auth service.
provider_id: The provider ID to refresh.
context: The gRPC context for error handling.
Returns:
The refresh response with results for the single provider.
"""
provider = oidc_service.registry.get_provider(provider_id)
if provider is None:
await abort_not_found(context, ENTITY_OIDC_PROVIDER, str(provider_id))
return noteflow_pb2.RefreshOidcDiscoveryResponse()
try:
await oidc_service.registry.refresh_discovery(provider)
return noteflow_pb2.RefreshOidcDiscoveryResponse(
results={str(provider_id): ""},
success_count=1,
failure_count=0,
)
except OidcDiscoveryError as e:
return noteflow_pb2.RefreshOidcDiscoveryResponse(
results={str(provider_id): str(e)},
success_count=0,
failure_count=1,
)
def build_bulk_refresh_response(
results: dict[UUID, str | None],
) -> noteflow_pb2.RefreshOidcDiscoveryResponse:
"""Build response for bulk OIDC discovery refresh.
Args:
results: Mapping of provider IDs to error messages (None for success).
Returns:
The refresh response with aggregated results.
"""
results_str = {str(k): v or "" for k, v in results.items()}
success_count = sum(v is None for v in results.values())
failure_count = sum(v is not None for v in results.values())
return noteflow_pb2.RefreshOidcDiscoveryResponse(
results=results_str,
success_count=success_count,
failure_count=failure_count,
)

View File

@@ -0,0 +1,222 @@
"""OIDC provider management mixin for gRPC service."""
from __future__ import annotations
from uuid import UUID
from noteflow.config.constants import ERROR_INVALID_WORKSPACE_ID_FORMAT
from noteflow.domain.auth.oidc import OidcProviderPreset, OidcProviderRegistration
from noteflow.infrastructure.auth._presets import PROVIDER_PRESETS
from noteflow.infrastructure.auth.oidc_discovery import OidcDiscoveryError
from noteflow.infrastructure.auth.oidc_registry import OidcAuthService
from ...proto import noteflow_pb2
from .._types import GrpcContext
from ..converters import oidc_provider_to_proto
from ..errors import abort_invalid_argument, parse_workspace_id
from ._helpers import (
ERR_INVALID_PRESET,
ENTITY_OIDC_PROVIDER,
ERR_INVALID_PROVIDER_ID,
apply_custom_provider_config,
apply_update_request_to_provider,
build_bulk_refresh_response,
parse_provider_id,
parse_preset,
parse_register_options,
preset_config_to_proto,
refresh_single_provider,
validate_register_request,
)
class OidcMixin:
"""Mixin providing OIDC provider management operations.
Requires host to implement OidcServicer protocol.
OIDC providers are stored in the in-memory registry (not database).
"""
oidc_service: OidcAuthService | None
def get_oidc_service(self) -> OidcAuthService:
"""Get or create the OIDC auth service."""
if self.oidc_service is None:
self.oidc_service = OidcAuthService()
assert self.oidc_service is not None # Help type checker
return self.oidc_service
async def RegisterOidcProvider(
self,
request: noteflow_pb2.RegisterOidcProviderRequest,
context: GrpcContext,
) -> noteflow_pb2.OidcProviderProto:
"""Register a new OIDC provider."""
await validate_register_request(request, context)
# Parse preset
try:
preset = parse_preset(request.preset) if request.preset else OidcProviderPreset.CUSTOM
except ValueError:
await abort_invalid_argument(context, ERR_INVALID_PRESET)
return noteflow_pb2.OidcProviderProto() # unreachable
# Parse workspace ID
try:
workspace_id = UUID(request.workspace_id) if request.workspace_id else UUID(int=0)
except ValueError:
await abort_invalid_argument(context, ERROR_INVALID_WORKSPACE_ID_FORMAT)
return noteflow_pb2.OidcProviderProto() # unreachable
custom_config = parse_register_options(request)
# Register provider
oidc_service = self.get_oidc_service()
try:
registration = OidcProviderRegistration(
workspace_id=workspace_id,
name=request.name,
issuer_url=request.issuer_url,
client_id=request.client_id,
client_secret=(
request.client_secret
if request.HasField("client_secret")
else None
),
preset=preset,
)
provider, warnings = await oidc_service.register_provider(registration)
apply_custom_provider_config(provider, custom_config)
return oidc_provider_to_proto(provider, warnings)
except OidcDiscoveryError as e:
await abort_invalid_argument(context, f"OIDC discovery failed: {e}")
return noteflow_pb2.OidcProviderProto() # unreachable
async def ListOidcProviders(
self,
request: noteflow_pb2.ListOidcProvidersRequest,
context: GrpcContext,
) -> noteflow_pb2.ListOidcProvidersResponse:
"""List all OIDC providers."""
# Parse optional workspace filter
workspace_id: UUID | None = None
if request.HasField("workspace_id"):
workspace_id = await parse_workspace_id(request.workspace_id, context)
oidc_service = self.get_oidc_service()
providers = oidc_service.registry.list_providers(
workspace_id=workspace_id,
enabled_only=request.enabled_only,
)
return noteflow_pb2.ListOidcProvidersResponse(
providers=[oidc_provider_to_proto(p) for p in providers],
total_count=len(providers),
)
async def GetOidcProvider(
self,
request: noteflow_pb2.GetOidcProviderRequest,
context: GrpcContext,
) -> noteflow_pb2.OidcProviderProto:
"""Get a specific OIDC provider by ID."""
from ..errors import abort_not_found
try:
provider_id = parse_provider_id(request.provider_id)
except ValueError:
await abort_invalid_argument(context, ERR_INVALID_PROVIDER_ID)
return noteflow_pb2.OidcProviderProto() # unreachable
oidc_service = self.get_oidc_service()
provider = oidc_service.registry.get_provider(provider_id)
if provider is None:
await abort_not_found(context, ENTITY_OIDC_PROVIDER, str(provider_id))
return noteflow_pb2.OidcProviderProto() # unreachable
return oidc_provider_to_proto(provider)
async def UpdateOidcProvider(
self,
request: noteflow_pb2.UpdateOidcProviderRequest,
context: GrpcContext,
) -> noteflow_pb2.OidcProviderProto:
"""Update an existing OIDC provider."""
from ..errors import abort_not_found
try:
provider_id = parse_provider_id(request.provider_id)
except ValueError:
await abort_invalid_argument(context, ERR_INVALID_PROVIDER_ID)
return noteflow_pb2.OidcProviderProto() # unreachable
oidc_service = self.get_oidc_service()
provider = oidc_service.registry.get_provider(provider_id)
if provider is None:
await abort_not_found(context, ENTITY_OIDC_PROVIDER, str(provider_id))
return noteflow_pb2.OidcProviderProto() # unreachable
apply_update_request_to_provider(provider, request)
return oidc_provider_to_proto(provider)
async def DeleteOidcProvider(
self,
request: noteflow_pb2.DeleteOidcProviderRequest,
context: GrpcContext,
) -> noteflow_pb2.DeleteOidcProviderResponse:
"""Delete an OIDC provider."""
from ..errors import abort_not_found
try:
provider_id = parse_provider_id(request.provider_id)
except ValueError:
await abort_invalid_argument(context, ERR_INVALID_PROVIDER_ID)
return noteflow_pb2.DeleteOidcProviderResponse(success=False)
oidc_service = self.get_oidc_service()
success = oidc_service.registry.remove_provider(provider_id)
if not success:
await abort_not_found(context, ENTITY_OIDC_PROVIDER, str(provider_id))
return noteflow_pb2.DeleteOidcProviderResponse(success=success)
async def RefreshOidcDiscovery(
self,
request: noteflow_pb2.RefreshOidcDiscoveryRequest,
context: GrpcContext,
) -> noteflow_pb2.RefreshOidcDiscoveryResponse:
"""Refresh OIDC discovery for one or all providers."""
oidc_service = self.get_oidc_service()
# Single provider refresh
if request.HasField("provider_id"):
try:
provider_id = parse_provider_id(request.provider_id)
except ValueError:
await abort_invalid_argument(context, ERR_INVALID_PROVIDER_ID)
return noteflow_pb2.RefreshOidcDiscoveryResponse()
return await refresh_single_provider(oidc_service, provider_id, context)
# Bulk refresh
workspace_id: UUID | None = None
if request.HasField("workspace_id"):
workspace_id = await parse_workspace_id(request.workspace_id, context)
results = await oidc_service.refresh_all_discovery(workspace_id=workspace_id)
return build_bulk_refresh_response(results)
async def ListOidcPresets(
self,
request: noteflow_pb2.ListOidcPresetsRequest,
context: GrpcContext,
) -> noteflow_pb2.ListOidcPresetsResponse:
"""List available OIDC provider presets."""
presets = [preset_config_to_proto(config) for config in PROVIDER_PRESETS.values()]
return noteflow_pb2.ListOidcPresetsResponse(presets=presets)

View File

@@ -1,537 +1,38 @@
"""Protocol definitions for gRPC servicer and repository providers.
This module re-exports protocols from separate modules for backward compatibility.
"""
from __future__ import annotations
import asyncio
from pathlib import Path
from typing import TYPE_CHECKING, ClassVar, Final, Protocol
from noteflow.domain.ports.async_context import AsyncContextManager
if TYPE_CHECKING:
from collections import deque
from collections.abc import AsyncIterator
from datetime import datetime
from uuid import UUID
import numpy as np
from numpy.typing import NDArray
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
from noteflow.application.services.calendar_service import CalendarService
from noteflow.application.services.identity_service import IdentityService
from noteflow.application.services.ner_service import NerService
from noteflow.application.services.project_service import ProjectService
from noteflow.application.services.summarization_service import SummarizationService
from noteflow.application.services.webhook_service import WebhookService
from noteflow.domain.entities import Integration, Meeting, Segment, Summary, SyncRun
from noteflow.domain.identity.context import OperationContext
from noteflow.domain.ports.repositories import (
AnnotationRepository,
DiarizationJobRepository,
EntityRepository,
MeetingRepository,
PreferencesRepository,
SegmentRepository,
SummaryRepository,
WebhookRepository,
)
from noteflow.domain.ports.repositories.identity import (
ProjectMembershipRepository,
ProjectRepository,
WorkspaceRepository,
)
from noteflow.domain.ports.unit_of_work import UnitOfWork
from noteflow.domain.value_objects import MeetingId
from noteflow.grpc._mixins.preferences import PreferencesRepositoryProvider
from noteflow.infrastructure.asr import FasterWhisperEngine, Segmenter, StreamingVad
from noteflow.infrastructure.audio.writer import MeetingAudioWriter
from noteflow.infrastructure.auth.oidc_registry import OidcAuthService
from noteflow.infrastructure.diarization import (
DiarizationEngine,
DiarizationSession,
SpeakerTurn,
)
from noteflow.infrastructure.persistence.repositories import DiarizationJob
from noteflow.infrastructure.persistence.repositories.preferences_repo import (
PreferenceWithMetadata,
)
from noteflow.infrastructure.persistence.unit_of_work import SqlAlchemyUnitOfWork
from noteflow.infrastructure.security.crypto import AesGcmCryptoBox
from ..meeting_store import MeetingStore
from ..proto import noteflow_pb2
from ..stream_state import MeetingStreamState
from ._types import GrpcContext, GrpcStatusContext
from .diarization._streaming import DiarizationChunkContext
from .streaming._types import StreamSessionInit
class _ServicerState(Protocol):
# Configuration
session_factory: async_sessionmaker[AsyncSession] | None
memory_store: MeetingStore | None
meetings_dir: Path
crypto: AesGcmCryptoBox
# Engines and services
asr_engine: FasterWhisperEngine | None
diarization_engine: DiarizationEngine | None
summarization_service: SummarizationService | None
ner_service: NerService | None
calendar_service: CalendarService | None
webhook_service: WebhookService | None
project_service: ProjectService | None
identity_service: IdentityService
diarization_refinement_enabled: bool
# Audio writers
audio_writers: dict[str, MeetingAudioWriter]
audio_write_failed: set[str]
# VAD and segmentation state per meeting
vad_instances: dict[str, StreamingVad]
segmenters: dict[str, Segmenter]
segment_counters: dict[str, int]
stream_formats: dict[str, tuple[int, int]]
active_streams: set[str]
stop_requested: set[str] # Meeting IDs with pending stop requests
# Chunk sequence tracking for acknowledgments
chunk_sequences: dict[str, int] # Highest received sequence per meeting
chunk_counts: dict[str, int] # Chunks since last ack (emit ack every 5)
chunk_receipt_times: dict[str, deque[float]] # Receipt timestamps per meeting
pending_chunks: dict[str, int] # Pending chunks counter per meeting
# Consolidated per-meeting streaming state (single lookup replaces 13+ dict accesses)
stream_states: dict[str, MeetingStreamState]
# Background diarization task references (for cancellation)
diarization_jobs: dict[str, DiarizationJob]
diarization_tasks: dict[str, asyncio.Task[None]]
diarization_lock: asyncio.Lock
stream_init_lock: asyncio.Lock # Guards concurrent stream initialization
# Integration sync runs cache
sync_runs: dict[UUID, SyncRun]
# Track when each sync run was cached (Sprint GAP-002: State Synchronization)
sync_run_cache_times: dict[UUID, datetime]
# Constants
DEFAULT_SAMPLE_RATE: Final[int]
SUPPORTED_SAMPLE_RATES: ClassVar[list[int]] # Converted to frozenset when passed to validate_stream_format
PARTIAL_CADENCE_SECONDS: Final[float]
MIN_PARTIAL_AUDIO_SECONDS: Final[float]
# OIDC service
oidc_service: OidcAuthService | None
class _ServicerCoreMethods(Protocol):
"""Core helper methods shared across mixins."""
@property
def diarization_job_ttl_seconds(self) -> float:
"""Return diarization job TTL from settings."""
...
def use_database(self) -> bool:
"""Check if database persistence is configured."""
...
def get_memory_store(self) -> MeetingStore:
"""Get the in-memory store, raising if not configured."""
...
def get_operation_context(self, context: GrpcContext) -> OperationContext:
"""Build operation context from the gRPC request."""
...
def create_uow(self) -> SqlAlchemyUnitOfWork:
"""Create a new Unit of Work (database-backed)."""
...
def create_repository_provider(self) -> UnitOfWork:
"""Create a repository provider (database or memory backed)."""
...
def next_segment_id(self, meeting_id: str, fallback: int = 0) -> int:
"""Get and increment the next segment id for a meeting."""
...
def init_streaming_state(self, meeting_id: str, next_segment_id: int) -> None:
"""Initialize VAD, Segmenter, speaking state, and partial buffers."""
...
def cleanup_streaming_state(self, meeting_id: str) -> None:
"""Clean up streaming state for a meeting."""
...
def get_stream_state(self, meeting_id: str) -> MeetingStreamState | None:
"""Get consolidated streaming state for a meeting."""
...
def ensure_meeting_dek(self, meeting: Meeting) -> tuple[bytes, bytes, bool]:
"""Ensure meeting has a DEK, generating one if needed."""
...
def start_meeting_if_needed(self, meeting: Meeting) -> tuple[bool, str | None]:
"""Start recording on meeting if not already recording."""
...
def open_meeting_audio_writer(
self,
meeting_id: str,
dek: bytes,
wrapped_dek: bytes,
asset_path: str | None = None,
) -> None:
"""Open audio writer for a meeting."""
...
def close_audio_writer(self, meeting_id: str) -> None:
"""Close and remove the audio writer for a meeting."""
...
def get_oidc_service(self) -> OidcAuthService:
"""Get or create the OIDC auth service."""
...
class _ServicerDiarizationMethods(Protocol):
"""Diarization helpers used by streaming and job mixins."""
async def prune_diarization_jobs(self) -> None:
"""Prune expired diarization jobs from in-memory cache."""
...
async def run_diarization_job(self, job_id: str, num_speakers: int | None) -> None:
"""Run background diarization job."""
...
async def collect_speaker_ids(self, meeting_id: str) -> list[str]:
"""Collect unique speaker IDs for a meeting."""
...
def run_diarization_inference(
self,
meeting_id: str,
num_speakers: int | None,
) -> list[SpeakerTurn]:
"""Run diarization inference synchronously."""
...
async def apply_diarization_turns(
self,
meeting_id: str,
turns: list[SpeakerTurn],
) -> int:
"""Apply diarization turns to meeting segments."""
...
async def refine_speaker_diarization(
self,
meeting_id: str,
num_speakers: int | None = None,
) -> int:
"""Run post-meeting speaker diarization refinement."""
...
async def update_job_completed(
self,
job_id: str,
job: DiarizationJob | None,
updated_count: int,
speaker_ids: list[str],
) -> None:
"""Update job status to COMPLETED."""
...
async def handle_job_timeout(
self,
job_id: str,
job: DiarizationJob | None,
meeting_id: str | None,
) -> None:
"""Handle job timeout."""
...
async def handle_job_cancelled(
self,
job_id: str,
job: DiarizationJob | None,
meeting_id: str | None,
) -> None:
"""Handle job cancellation."""
...
async def handle_job_failed(
self,
job_id: str,
job: DiarizationJob | None,
meeting_id: str | None,
exc: Exception,
) -> None:
"""Handle job failure."""
...
async def start_diarization_job(
self,
request: noteflow_pb2.RefineSpeakerDiarizationRequest,
context: GrpcStatusContext,
) -> noteflow_pb2.RefineSpeakerDiarizationResponse:
"""Start a new diarization refinement job."""
...
async def persist_streaming_turns(
self,
meeting_id: str,
new_turns: list[SpeakerTurn],
) -> None:
"""Persist streaming turns to database (fire-and-forget)."""
...
async def process_streaming_diarization(
self,
meeting_id: str,
audio: NDArray[np.float32],
) -> None:
"""Process audio chunk for streaming diarization (best-effort)."""
...
async def ensure_diarization_session(
self,
meeting_id: str,
state: MeetingStreamState,
loop: asyncio.AbstractEventLoop,
) -> DiarizationSession | None:
"""Return an initialized diarization session or None on failure."""
...
async def process_diarization_chunk(
self,
context: DiarizationChunkContext,
session: DiarizationSession,
audio: NDArray[np.float32],
loop: asyncio.AbstractEventLoop,
) -> list[SpeakerTurn] | None:
"""Process a diarization chunk, returning new turns or None on failure."""
...
class _ServicerWebhookMethods(Protocol):
"""Webhook helpers."""
async def fire_stop_webhooks(self, meeting: Meeting) -> None:
"""Trigger webhooks for meeting stop (fire-and-forget)."""
...
class _ServicerPreferencesMethods(Protocol):
"""Preferences helpers."""
async def decode_and_validate_prefs(
self,
request: noteflow_pb2.SetPreferencesRequest,
context: GrpcContext,
) -> dict[str, object]:
"""Decode and validate JSON preferences from request."""
...
async def apply_preferences(
self,
repo: PreferencesRepositoryProvider,
request: noteflow_pb2.SetPreferencesRequest,
current_prefs: list[PreferenceWithMetadata],
decoded_prefs: dict[str, object],
) -> None:
"""Apply preferences based on merge mode."""
...
class _ServicerStreamingMethods(Protocol):
"""Streaming helpers."""
async def init_stream_for_meeting(
self,
meeting_id: str,
context: GrpcContext,
) -> StreamSessionInit | None:
"""Initialize streaming for a meeting."""
...
def process_stream_chunk(
self,
meeting_id: str,
chunk: noteflow_pb2.AudioChunk,
context: GrpcContext,
) -> AsyncIterator[noteflow_pb2.TranscriptUpdate]:
"""Process a single audio chunk from the stream."""
...
def flush_segmenter(
self,
meeting_id: str,
) -> AsyncIterator[noteflow_pb2.TranscriptUpdate]:
"""Flush remaining audio from segmenter at stream end."""
...
async def prepare_stream_chunk(
self,
current_meeting_id: str | None,
initialized_meeting_id: str | None,
chunk: noteflow_pb2.AudioChunk,
context: GrpcContext,
) -> tuple[str, str | None] | None:
"""Validate and initialize streaming state for a chunk."""
...
class _ServicerSummarizationMethods(Protocol):
"""Summarization helpers."""
async def summarize_or_placeholder(
self,
meeting_id: MeetingId,
segments: list[Segment],
style_prompt: str | None = None,
) -> Summary:
"""Try to summarize via service, fallback to placeholder on failure."""
...
def generate_placeholder_summary(
self,
meeting_id: MeetingId,
segments: list[Segment],
) -> Summary:
"""Generate a lightweight placeholder summary when summarization fails."""
...
class _ServicerSyncMethods(Protocol):
"""Sync helpers."""
def ensure_sync_runs_cache(self) -> dict[UUID, SyncRun]:
"""Ensure the sync runs cache exists."""
...
def cache_sync_run(self, sync_run: SyncRun) -> None:
"""Cache a sync run with timestamp tracking (Sprint GAP-002)."""
...
def get_sync_run_expires_at(self, sync_run_id: UUID) -> str | None:
"""Get expiry timestamp for a cached sync run (Sprint GAP-002)."""
...
async def resolve_integration(
self,
uow: UnitOfWork,
integration_id: UUID,
context: GrpcContext,
request: noteflow_pb2.StartIntegrationSyncRequest,
) -> tuple[Integration | None, UUID]:
"""Resolve integration by ID with provider fallback."""
...
async def perform_sync(
self,
integration_id: UUID,
sync_run_id: UUID,
provider: str,
) -> None:
"""Perform the actual sync operation (background task)."""
...
async def execute_sync_fetch(self, provider: str) -> int:
"""Execute the calendar fetch and return items count."""
...
async def complete_sync_run(
self,
integration_id: UUID,
sync_run_id: UUID,
items_synced: int,
) -> SyncRun | None:
"""Mark sync run as complete and update integration last_sync."""
...
async def fail_sync_run(
self,
sync_run_id: UUID,
error_message: str,
) -> SyncRun | None:
"""Mark sync run as failed with error message."""
...
class ServicerHost(
_ServicerState,
_ServicerCoreMethods,
_ServicerDiarizationMethods,
_ServicerWebhookMethods,
_ServicerPreferencesMethods,
_ServicerStreamingMethods,
_ServicerSummarizationMethods,
_ServicerSyncMethods,
Protocol,
):
pass
class AnnotationRepositoryProvider(AsyncContextManager, Protocol):
supports_annotations: bool
annotations: AnnotationRepository
meetings: MeetingRepository
async def commit(self) -> None: ...
class MeetingRepositoryProvider(AsyncContextManager, Protocol):
meetings: MeetingRepository
segments: SegmentRepository
summaries: SummaryRepository
diarization_jobs: DiarizationJobRepository
projects: ProjectRepository
workspaces: WorkspaceRepository
supports_diarization_jobs: bool
supports_projects: bool
supports_workspaces: bool
async def commit(self) -> None: ...
class PreferencesRepositoryProvider(AsyncContextManager, Protocol):
supports_preferences: bool
preferences: PreferencesRepository
async def commit(self) -> None: ...
class WebhooksRepositoryProvider(AsyncContextManager, Protocol):
supports_webhooks: bool
webhooks: WebhookRepository
async def commit(self) -> None: ...
class EntitiesRepositoryProvider(AsyncContextManager, Protocol):
supports_entities: bool
entities: EntityRepository
async def commit(self) -> None: ...
class DiarizationJobRepositoryProvider(AsyncContextManager, Protocol):
supports_diarization_jobs: bool
diarization_jobs: DiarizationJobRepository
async def commit(self) -> None: ...
class ProjectRepositoryProvider(AsyncContextManager, Protocol):
supports_projects: bool
supports_workspaces: bool
projects: ProjectRepository
project_memberships: ProjectMembershipRepository
workspaces: WorkspaceRepository
async def commit(self) -> None: ...
from ._repository_protocols import (
AnnotationRepositoryProvider,
DiarizationJobRepositoryProvider,
EntitiesRepositoryProvider,
MeetingRepositoryProvider,
PreferencesRepositoryProvider,
ProjectRepositoryProvider,
WebhooksRepositoryProvider,
)
from ._servicer_protocols import (
ServicerCoreMethods,
ServicerDiarizationMethods,
ServicerHost,
ServicerPreferencesMethods,
ServicerState,
ServicerStreamingMethods,
ServicerSummarizationMethods,
ServicerSyncMethods,
ServicerWebhookMethods,
)
__all__ = [
"ServicerHost",
"AnnotationRepositoryProvider",
"MeetingRepositoryProvider",
"PreferencesRepositoryProvider",
"WebhooksRepositoryProvider",
"EntitiesRepositoryProvider",
"DiarizationJobRepositoryProvider",
"ProjectRepositoryProvider",
]

View File

@@ -82,9 +82,6 @@ async def process_audio_segment(
) -> AsyncIterator[noteflow_pb2.TranscriptUpdate]:
"""Process a complete audio segment through ASR.
Uses unified repository provider for both DB and memory backends.
Batches all segments from ASR results and commits once per audio chunk.
Args:
host: The servicer host.
meeting_id: Meeting identifier.
@@ -94,39 +91,42 @@ async def process_audio_segment(
Yields:
TranscriptUpdates for transcribed segments.
"""
if len(audio) == 0 or host.asr_engine is None:
asr_engine = host.asr_engine
if len(audio) == 0 or asr_engine is None:
return
parsed_meeting_id = parse_meeting_id_or_none(meeting_id)
parsed_meeting_id = _validate_meeting_id(meeting_id)
if parsed_meeting_id is None:
logger.warning("Invalid meeting_id %s in streaming segment", meeting_id)
return
async with host.create_repository_provider() as repo:
meeting = await repo.meetings.get(parsed_meeting_id)
if meeting is None:
return
results = await host.asr_engine.transcribe_async(audio)
results = await asr_engine.transcribe_async(audio)
ctx = _SegmentBuildContext(
host=host,
repo=repo,
meeting=meeting,
meeting_id=meeting_id,
segment_start_time=segment_start_time,
host=host, repo=repo, meeting=meeting,
meeting_id=meeting_id, segment_start_time=segment_start_time,
)
segments_to_add = await _build_segments_from_results(ctx, results)
if segments_to_add:
await repo.commit()
for _, update in segments_to_add:
yield update
_finalize_chunk_processing(host, meeting_id)
# Lazy import to avoid circular import with _processing.py
from ._processing import decrement_pending_chunks
decrement_pending_chunks(host, meeting_id)
def _validate_meeting_id(meeting_id: str) -> MeetingId | None:
"""Validate and parse meeting ID, logging warning if invalid."""
parsed = parse_meeting_id_or_none(meeting_id)
if parsed is None:
logger.warning("Invalid meeting_id %s in streaming segment", meeting_id)
return parsed
def _finalize_chunk_processing(host: ServicerHost, meeting_id: str) -> None:
"""Finalize chunk processing by decrementing pending count."""
from ._processing import decrement_pending_chunks
decrement_pending_chunks(host, meeting_id)
async def _build_segments_from_results(

View File

@@ -3,6 +3,7 @@
from __future__ import annotations
from collections.abc import AsyncIterator
from dataclasses import dataclass, field
from typing import TYPE_CHECKING
import numpy as np
@@ -32,6 +33,26 @@ if TYPE_CHECKING:
logger = get_logger(__name__)
@dataclass
class _StreamState:
"""Mutable state for stream processing.
Tracks meeting IDs separately to guarantee cleanup even if exception
occurs between initialization and assignment.
"""
current: str | None = field(default=None)
initialized: str | None = field(default=None)
def update_from_prep(self, prep: tuple[str, str]) -> None:
"""Update state from prepare_stream_chunk result."""
self.current, self.initialized = prep
def get_current_or_none(self) -> str | None:
"""Return current meeting ID for operations that accept None."""
return self.current
def _should_stop_stream(host: ServicerHost, meeting_id: str) -> bool:
"""Check if stop has been requested for this meeting.
@@ -71,36 +92,87 @@ class StreamingMixin:
if self.asr_engine is None or not self.asr_engine.is_loaded:
await abort_failed_precondition(context, "ASR engine not loaded")
current_meeting_id: str | None = None
# Track separately to guarantee cleanup even if exception occurs
# between _init_stream_for_meeting returning and current_meeting_id assignment
initialized_meeting_id: str | None = None
stream_state = _StreamState()
try:
async for chunk in request_iterator:
prep = await self.prepare_stream_chunk(
current_meeting_id, initialized_meeting_id, chunk, context
)
if prep is None:
return # Error already sent via context.abort
current_meeting_id, initialized_meeting_id = prep
if _should_stop_stream(self, current_meeting_id):
break
async for update in self.process_stream_chunk(
current_meeting_id, chunk, context
):
yield update
# Flush any remaining audio from segmenter
if current_meeting_id and current_meeting_id in self.segmenters:
async for update in self.flush_segmenter(current_meeting_id):
yield update
# Access method via class to help type checker resolve it
# _process_stream_chunks is defined on StreamingMixin, not ServicerHost protocol
process_method = getattr(StreamingMixin, "_process_stream_chunks")
bound_method = process_method.__get__(self, StreamingMixin)
async for update in bound_method(request_iterator, context, stream_state):
yield update
finally:
if cleanup_meeting := current_meeting_id or initialized_meeting_id:
if cleanup_meeting := stream_state.current or stream_state.initialized:
cleanup_stream_resources(self, cleanup_meeting)
async def _process_stream_chunks(
self: ServicerHost,
request_iterator: AsyncIterator[noteflow_pb2.AudioChunk],
context: GrpcContext,
state: _StreamState,
) -> AsyncIterator[noteflow_pb2.TranscriptUpdate]:
"""Process all chunks from stream, yielding transcript updates.
Args:
request_iterator: Iterator of audio chunks from client.
context: gRPC context for error handling.
state: Mutable state tracking current/initialized meeting IDs.
Yields:
Transcript updates from processing.
"""
async for chunk in request_iterator:
current, initialized = state.current, state.initialized
prep = await self.prepare_stream_chunk(current, initialized, chunk, context)
if prep is None:
return # Error already sent via context.abort
state.update_from_prep(prep)
meeting_id = state.current
if _should_stop_stream(self, meeting_id):
break
async for update in self.yield_chunk_updates(meeting_id, chunk, context):
yield update
async for update in self.flush_remaining_audio(state.current):
yield update
async def yield_chunk_updates(
self: ServicerHost,
meeting_id: str,
chunk: noteflow_pb2.AudioChunk,
context: GrpcContext,
) -> AsyncIterator[noteflow_pb2.TranscriptUpdate]:
"""Yield transcript updates from processing a single chunk.
Args:
meeting_id: Meeting identifier.
chunk: Audio chunk to process.
context: gRPC context for error handling.
Yields:
Transcript updates from processing.
"""
async for update in self.process_stream_chunk(meeting_id, chunk, context):
yield update
async def flush_remaining_audio(
self: ServicerHost,
meeting_id: str | None,
) -> AsyncIterator[noteflow_pb2.TranscriptUpdate]:
"""Flush any remaining audio from segmenter at stream end.
Args:
meeting_id: Meeting identifier, or None if not initialized.
Yields:
Transcript updates from flushing.
"""
if not meeting_id or meeting_id not in self.segmenters:
return
async for update in self.flush_segmenter(meeting_id):
yield update
async def prepare_stream_chunk(
self: ServicerHost,
current_meeting_id: str | None,

View File

@@ -19,7 +19,7 @@ from .errors import ENTITY_MEETING, abort_failed_precondition, abort_not_found
if TYPE_CHECKING:
from collections.abc import Callable
from noteflow.application.services.summarization_service import SummarizationService
from noteflow.application.services.summarization import SummarizationService
from noteflow.application.services.webhook_service import WebhookService
from noteflow.domain.entities import Meeting
@@ -204,5 +204,5 @@ class SummarizationMixin:
# Default to not granted if service unavailable
return noteflow_pb2.GetCloudConsentStatusResponse(consent_granted=False)
return noteflow_pb2.GetCloudConsentStatusResponse(
consent_granted=self.summarization_service.cloud_consent_granted,
consent_granted=self.summarization_service.settings.cloud_consent_granted,
)

View File

@@ -14,7 +14,7 @@ from noteflow.config.constants import (
from noteflow.domain.constants.fields import ENABLED, MAX_RETRIES, SECRET, WEBHOOK
from noteflow.domain.utils.time import utc_now
from noteflow.domain.webhooks.constants import DEFAULT_WEBHOOK_TIMEOUT_MS
from noteflow.domain.webhooks.events import WebhookConfig, WebhookEventType
from noteflow.domain.webhooks import WebhookConfig, WebhookEventType
from noteflow.infrastructure.logging import get_logger
from noteflow.infrastructure.persistence.constants import (
DEFAULT_WEBHOOK_DELIVERY_HISTORY_LIMIT,

View File

@@ -0,0 +1,158 @@
"""Helper functions for server startup and shutdown."""
from __future__ import annotations
from collections.abc import Awaitable, Callable
from pathlib import Path
from typing import TYPE_CHECKING
from noteflow.config.constants import SETTING_CLOUD_CONSENT_GRANTED
from noteflow.config.settings import get_settings
from noteflow.infrastructure.logging import get_logger
from noteflow.infrastructure.persistence.unit_of_work import SqlAlchemyUnitOfWork
if TYPE_CHECKING:
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
from noteflow.application.services.summarization import SummarizationService
logger = get_logger(__name__)
async def recover_jobs_with_uow(uow: SqlAlchemyUnitOfWork) -> None:
"""Execute job recovery within an active unit of work.
Args:
uow: Active unit of work with database access.
"""
if not uow.supports_diarization_jobs:
logger.debug("Job recovery skipped (diarization jobs not supported)")
return
failed_count = await uow.diarization_jobs.mark_running_as_failed()
await uow.commit()
log_job_recovery_result(failed_count)
async def mark_orphaned_jobs_failed(
session_factory: async_sessionmaker[AsyncSession],
meetings_dir: Path,
) -> None:
"""Mark orphaned diarization jobs as failed using provided session factory.
Args:
session_factory: Async session factory for database access.
meetings_dir: Directory for meeting storage.
"""
try:
async with SqlAlchemyUnitOfWork(session_factory, meetings_dir) as uow:
await recover_jobs_with_uow(uow)
except Exception as exc:
logger.warning("Failed to recover orphaned jobs: %s", exc)
def log_job_recovery_result(failed_count: int) -> None:
"""Log the result of job recovery."""
if failed_count > 0:
logger.warning(
"Marked %d orphaned diarization job(s) as failed on startup",
failed_count,
)
else:
logger.debug("No orphaned diarization jobs to recover")
async def apply_stored_consent(
uow: SqlAlchemyUnitOfWork,
summarization_service: SummarizationService,
) -> None:
"""Apply stored consent from database to service.
Args:
uow: Active unit of work with database access.
summarization_service: Service to update with loaded consent.
"""
stored_consent = await uow.preferences.get(SETTING_CLOUD_CONSENT_GRANTED)
if stored_consent is None:
return
summarization_service.settings.cloud_consent_granted = bool(stored_consent)
logger.info(
"Loaded cloud consent from database: %s",
summarization_service.settings.cloud_consent_granted,
)
async def load_consent_from_db(
session_factory: async_sessionmaker[AsyncSession],
meetings_dir: Path,
summarization_service: SummarizationService,
) -> None:
"""Load cloud consent setting from database.
Args:
session_factory: Async session factory for database access.
meetings_dir: Directory for meeting storage.
summarization_service: Service to update with loaded consent.
"""
try:
async with SqlAlchemyUnitOfWork(session_factory, meetings_dir) as uow:
await apply_stored_consent(uow, summarization_service)
# INTENTIONAL BROAD HANDLER: Startup resilience
# - Database may be unavailable at startup
# - Consent loading should not block server startup
except Exception:
logger.exception("Failed to load cloud consent from database")
async def persist_consent_to_db(
uow: SqlAlchemyUnitOfWork,
granted: bool,
) -> None:
"""Persist consent setting to database within active unit of work.
Args:
uow: Active unit of work with database access.
granted: Whether cloud consent is granted.
"""
await uow.preferences.set(SETTING_CLOUD_CONSENT_GRANTED, granted)
await uow.commit()
logger.info("Persisted cloud consent: %s", granted)
async def execute_consent_persist(
session_factory: async_sessionmaker[AsyncSession],
granted: bool,
) -> None:
"""Execute consent persistence to database.
Args:
session_factory: Async session factory for database access.
granted: Whether cloud consent is granted.
"""
settings = get_settings()
async with SqlAlchemyUnitOfWork(session_factory, settings.meetings_dir) as uow:
await persist_consent_to_db(uow, granted)
def create_consent_persist_callback(
session_factory: async_sessionmaker[AsyncSession],
) -> Callable[[bool], Awaitable[None]]:
"""Create callback to persist consent changes to database.
Args:
session_factory: Async session factory for database access.
Returns:
Async callback that persists consent changes.
"""
async def persist_consent(granted: bool) -> None:
"""Persist consent change to database."""
try:
await execute_consent_persist(session_factory, granted)
# INTENTIONAL BROAD HANDLER: Fire-and-forget persistence
# - Consent persistence should not crash application
# - Next startup will retry
except Exception:
logger.exception("Failed to persist cloud consent")
return persist_consent

View File

@@ -0,0 +1,95 @@
"""Helper functions for servicer shutdown and cleanup."""
from __future__ import annotations
import asyncio
import contextlib
from typing import TYPE_CHECKING
from noteflow.infrastructure.logging import get_logger
if TYPE_CHECKING:
from .service import NoteFlowServicer
logger = get_logger(__name__)
async def cancel_diarization_tasks(servicer: NoteFlowServicer) -> list[str]:
"""Cancel all active diarization tasks and return their IDs."""
cancelled_job_ids = list(servicer.diarization_tasks.keys())
for job_id, task in list(servicer.diarization_tasks.items()):
if task.done():
continue
logger.debug("Cancelling diarization task %s", job_id)
task.cancel()
with contextlib.suppress(asyncio.CancelledError):
await task
servicer.diarization_tasks.clear()
return cancelled_job_ids
def mark_in_memory_jobs_failed(
servicer: NoteFlowServicer,
cancelled_job_ids: list[str],
) -> None:
"""Mark in-memory diarization jobs as failed."""
from .proto import noteflow_pb2
if servicer.session_factory is not None or not cancelled_job_ids:
return
failed_count = 0
for job_id in cancelled_job_ids:
job = servicer.diarization_jobs.get(job_id)
if job is None:
continue
if job.status in (
noteflow_pb2.JOB_STATUS_QUEUED,
noteflow_pb2.JOB_STATUS_RUNNING,
):
job.status = noteflow_pb2.JOB_STATUS_FAILED
job.error_message = "ERR_TASK_CANCELLED"
failed_count += 1
if failed_count > 0:
logger.warning(
"Marked %d in-memory diarization jobs as failed on shutdown",
failed_count,
)
def close_diarization_sessions(servicer: NoteFlowServicer) -> None:
"""Close all active diarization sessions."""
for meeting_id, state in list(servicer.stream_states.items()):
if state.diarization_session is None:
continue
logger.debug("Closing diarization session for meeting %s", meeting_id)
state.diarization_session.close()
state.diarization_session = None
def close_audio_writers(servicer: NoteFlowServicer) -> None:
"""Close all active audio writers."""
for meeting_id in list(servicer.audio_writers.keys()):
logger.debug("Closing audio writer for meeting %s", meeting_id)
servicer.close_audio_writer(meeting_id)
async def mark_running_jobs_failed_db(servicer: NoteFlowServicer) -> None:
"""Mark running diarization jobs as failed in database."""
if servicer.session_factory is None:
return
async with servicer.create_uow() as uow:
failed_count = await uow.diarization_jobs.mark_running_as_failed()
await uow.commit()
if failed_count > 0:
logger.warning(
"Marked %d running diarization jobs as failed on shutdown",
failed_count,
)
async def close_webhook_service(servicer: NoteFlowServicer) -> None:
"""Close webhook service HTTP client."""
if servicer.webhook_service is None:
return
logger.debug("Closing webhook service HTTP client")
await servicer.webhook_service.close()

View File

@@ -0,0 +1,333 @@
"""Mixin classes for NoteFlowServicer."""
from __future__ import annotations
import time
from collections import deque
from pathlib import Path
from typing import TYPE_CHECKING, ClassVar
from uuid import UUID
from noteflow.domain.entities import Meeting
from noteflow.domain.identity.context import OperationContext, UserContext, WorkspaceContext
from noteflow.domain.identity.roles import WorkspaceRole
from noteflow.domain.value_objects import MeetingState
from noteflow.grpc.meeting_store import MeetingStore
from noteflow.infrastructure.asr import Segmenter, SegmenterConfig, StreamingVad
from noteflow.infrastructure.audio.partial_buffer import PartialAudioBuffer
from noteflow.infrastructure.audio.writer import MeetingAudioWriter
from noteflow.infrastructure.logging import (
get_logger,
request_id_var,
user_id_var,
workspace_id_var,
)
from noteflow.infrastructure.persistence.memory import MemoryUnitOfWork
from noteflow.infrastructure.persistence.unit_of_work import SqlAlchemyUnitOfWork
from noteflow.infrastructure.security.crypto import AesGcmCryptoBox
from ._service_helpers import (
cancel_diarization_tasks,
close_audio_writers,
close_diarization_sessions,
close_webhook_service,
mark_in_memory_jobs_failed,
mark_running_jobs_failed_db,
)
from .proto import noteflow_pb2
from .stream_state import MeetingStreamState
if TYPE_CHECKING:
from collections.abc import Awaitable, Callable
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
from noteflow.infrastructure.asr import FasterWhisperEngine
from noteflow.infrastructure.diarization.engine import DiarizationEngine
from ._mixins._types import GrpcContext
else:
from ._mixins._types import GrpcContext
logger = get_logger(__name__)
class ServicerUowMixin:
"""Mixin for Unit of Work operations."""
session_factory: async_sessionmaker[AsyncSession] | None
meetings_dir: Path
memory_store: MeetingStore | None
def use_database(self) -> bool:
"""Check if database persistence is configured."""
return self.session_factory is not None
def get_memory_store(self) -> MeetingStore:
"""Get the in-memory store, raising if not configured."""
if self.memory_store is None:
raise RuntimeError("Memory store not configured")
return self.memory_store
def create_uow(self) -> SqlAlchemyUnitOfWork:
"""Create a new Unit of Work (database-backed)."""
if self.session_factory is None:
raise RuntimeError("Database not configured")
return SqlAlchemyUnitOfWork(self.session_factory, self.meetings_dir)
def create_repository_provider(self) -> SqlAlchemyUnitOfWork | MemoryUnitOfWork:
"""Create a repository provider (database or memory backed)."""
if self.session_factory is not None:
return SqlAlchemyUnitOfWork(self.session_factory, self.meetings_dir)
return MemoryUnitOfWork(self.get_memory_store())
async def _count_active_meetings_db(self) -> int:
"""Count active meetings using database state."""
async with self.create_uow() as uow:
total = 0
for state in (MeetingState.RECORDING, MeetingState.STOPPING):
total += await uow.meetings.count_by_state(state)
return total
class ServicerContextMixin:
"""Mixin for operation context handling."""
def get_operation_context(self, context: GrpcContext) -> OperationContext:
"""Get operation context from gRPC context variables."""
request_id = request_id_var.get()
user_id_str = user_id_var.get()
workspace_id_str = workspace_id_var.get()
default_user_id = UUID("00000000-0000-0000-0000-000000000001")
default_workspace_id = UUID("00000000-0000-0000-0000-000000000001")
user_id = UUID(user_id_str) if user_id_str else default_user_id
workspace_id = UUID(workspace_id_str) if workspace_id_str else default_workspace_id
return OperationContext(
user=UserContext(user_id=user_id, display_name=""),
workspace=WorkspaceContext(
workspace_id=workspace_id,
workspace_name="",
role=WorkspaceRole.OWNER,
),
request_id=request_id,
)
class ServicerStreamingStateMixin:
"""Mixin for streaming state management."""
stream_states: dict[str, MeetingStreamState]
vad_instances: dict[str, StreamingVad]
segmenters: dict[str, Segmenter]
segment_counters: dict[str, int]
stream_formats: dict[str, tuple[int, int]]
chunk_sequences: dict[str, int]
chunk_counts: dict[str, int]
chunk_receipt_times: dict[str, deque[float]]
pending_chunks: dict[str, int]
DEFAULT_SAMPLE_RATE: int
def init_streaming_state(self, meeting_id: str, next_segment_id: int) -> None:
"""Initialize VAD, Segmenter, speaking state, and partial buffers for a meeting."""
vad = StreamingVad()
segmenter = Segmenter(config=SegmenterConfig(sample_rate=self.DEFAULT_SAMPLE_RATE))
partial_buffer = PartialAudioBuffer(sample_rate=self.DEFAULT_SAMPLE_RATE)
current_time = time.time()
state = MeetingStreamState(
vad=vad,
segmenter=segmenter,
partial_buffer=partial_buffer,
sample_rate=self.DEFAULT_SAMPLE_RATE,
channels=1,
next_segment_id=next_segment_id,
was_speaking=False,
last_partial_time=current_time,
last_partial_text="",
diarization_session=None,
diarization_turns=[],
diarization_stream_time=0.0,
diarization_streaming_failed=False,
is_active=True,
stop_requested=False,
audio_write_failed=False,
)
self.stream_states[meeting_id] = state
self.vad_instances[meeting_id] = vad
self.segmenters[meeting_id] = segmenter
self.segment_counters[meeting_id] = next_segment_id
def cleanup_streaming_state(self, meeting_id: str) -> None:
"""Clean up VAD, Segmenter, speaking state, and partial buffers for a meeting."""
if (state := self.stream_states.pop(meeting_id, None)) and state.diarization_session is not None:
state.diarization_session.close()
self.vad_instances.pop(meeting_id, None)
self.segmenters.pop(meeting_id, None)
self.segment_counters.pop(meeting_id, None)
self.stream_formats.pop(meeting_id, None)
self.chunk_sequences.pop(meeting_id, None)
self.chunk_counts.pop(meeting_id, None)
if hasattr(self, "_chunk_receipt_times"):
self.chunk_receipt_times.pop(meeting_id, None)
if hasattr(self, "_pending_chunks"):
self.pending_chunks.pop(meeting_id, None)
def get_stream_state(self, meeting_id: str) -> MeetingStreamState | None:
"""Get consolidated streaming state for a meeting."""
state = self.stream_states.get(meeting_id)
return None if state is None else state
def next_segment_id(self, meeting_id: str, fallback: int = 0) -> int:
"""Get and increment the next segment id for a meeting."""
next_id = self.segment_counters.get(meeting_id)
if next_id is None:
next_id = fallback
self.segment_counters[meeting_id] = next_id + 1
return next_id
class ServicerAudioMixin:
"""Mixin for audio writer management."""
crypto: AesGcmCryptoBox
meetings_dir: Path
audio_writers: dict[str, MeetingAudioWriter]
audio_write_failed: set[str]
DEFAULT_SAMPLE_RATE: int
def ensure_meeting_dek(self, meeting: Meeting) -> tuple[bytes, bytes, bool]:
"""Ensure meeting has a DEK, generating one if needed."""
if meeting.wrapped_dek is None:
dek = self.crypto.generate_dek()
wrapped_dek = self.crypto.wrap_dek(dek)
meeting.wrapped_dek = wrapped_dek
return dek, wrapped_dek, True
wrapped_dek = meeting.wrapped_dek
dek = self.crypto.unwrap_dek(wrapped_dek)
return dek, wrapped_dek, False
def start_meeting_if_needed(self, meeting: Meeting) -> tuple[bool, str | None]:
"""Start recording on meeting if not already recording."""
if meeting.state == MeetingState.RECORDING:
return False, None
try:
meeting.start_recording()
return True, None
except ValueError as e:
return False, str(e)
def open_meeting_audio_writer(
self,
meeting_id: str,
dek: bytes,
wrapped_dek: bytes,
asset_path: str | None = None,
) -> None:
"""Open audio writer for a meeting."""
writer = MeetingAudioWriter(self.crypto, self.meetings_dir)
writer.open(
meeting_id=meeting_id,
dek=dek,
wrapped_dek=wrapped_dek,
sample_rate=self.DEFAULT_SAMPLE_RATE,
asset_path=asset_path,
)
self.audio_writers[meeting_id] = writer
logger.info("Audio writer opened for meeting %s", meeting_id)
def close_audio_writer(self, meeting_id: str) -> None:
"""Close and remove the audio writer for a meeting."""
self.audio_write_failed.discard(meeting_id)
if meeting_id not in self.audio_writers:
return
try:
writer = self.audio_writers.pop(meeting_id)
writer.close()
logger.info(
"Audio writer closed for meeting %s: %d bytes written",
meeting_id,
writer.bytes_written,
)
except (OSError, RuntimeError) as e:
logger.error(
"Failed to close audio writer for meeting %s: %s",
meeting_id,
e,
)
class ServicerInfoMixin:
"""Mixin for server info operations."""
asr_engine: FasterWhisperEngine | None
diarization_engine: DiarizationEngine | None
session_factory: async_sessionmaker[AsyncSession] | None
memory_store: MeetingStore | None
_start_time: float
SUPPORTED_SAMPLE_RATES: ClassVar[list[int]]
MAX_CHUNK_SIZE: int
VERSION: str
STATE_VERSION: int
_count_active_meetings_db: Callable[..., Awaitable[int]]
get_memory_store: Callable[..., MeetingStore]
async def GetServerInfo(
self,
request: noteflow_pb2.ServerInfoRequest,
context: GrpcContext,
) -> noteflow_pb2.ServerInfo:
"""Get server information."""
asr_model = ""
asr_ready = False
if self.asr_engine:
asr_ready = self.asr_engine.is_loaded
asr_model = self.asr_engine.model_size or ""
diarization_enabled = self.diarization_engine is not None
diarization_ready = self.diarization_engine is not None and (
self.diarization_engine.is_streaming_loaded
or self.diarization_engine.is_offline_loaded
)
if self.session_factory is not None:
active = await self._count_active_meetings_db()
else:
active = self.get_memory_store().active_count
return noteflow_pb2.ServerInfo(
version=self.VERSION,
asr_model=asr_model,
asr_ready=asr_ready,
supported_sample_rates=self.SUPPORTED_SAMPLE_RATES,
max_chunk_size=self.MAX_CHUNK_SIZE,
uptime_seconds=time.time() - self._start_time,
active_meetings=active,
diarization_enabled=diarization_enabled,
diarization_ready=diarization_ready,
state_version=self.STATE_VERSION,
)
class ServicerLifecycleMixin:
"""Mixin for servicer lifecycle operations."""
async def shutdown(self) -> None:
"""Clean up servicer state before server stops."""
logger.info("Shutting down servicer...")
cancelled_job_ids = await cancel_diarization_tasks(self)
mark_in_memory_jobs_failed(self, cancelled_job_ids)
close_diarization_sessions(self)
close_audio_writers(self)
await mark_running_jobs_failed_db(self)
await close_webhook_service(self)
logger.info("Servicer shutdown complete")

View File

@@ -6,44 +6,55 @@ clean separation of concerns for server initialization.
from __future__ import annotations
import sys
from dataclasses import dataclass
from typing import Protocol, TypedDict, cast
from typing import TYPE_CHECKING, Protocol, TypedDict, cast
from rich.console import Console
from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, async_sessionmaker
from noteflow.application.services import RecoveryService
from noteflow.application.services.calendar_service import CalendarService
from noteflow.application.services.ner_service import NerService
from noteflow.application.services.summarization_service import (
from noteflow.application.services.summarization import (
SummarizationMode,
SummarizationService,
)
from noteflow.application.services.webhook_service import WebhookService
from noteflow.config.constants import (
PROVIDER_NAME_OPENAI,
SETTING_CLOUD_CONSENT_GRANTED,
STATUS_DISABLED,
)
from noteflow.config.settings import (
Settings,
get_calendar_settings,
get_feature_flags,
get_settings,
)
from noteflow.domain.constants.fields import CALENDAR, PROVIDER
from noteflow.domain.entities.integration import IntegrationStatus
from noteflow.infrastructure.diarization import DiarizationEngine
from noteflow.config.settings import Settings, get_settings
from noteflow.domain.constants.fields import PROVIDER
from noteflow.infrastructure.logging import get_logger
from noteflow.infrastructure.ner import NerEngine
from noteflow.infrastructure.persistence.database import (
create_engine_and_session_factory,
ensure_schema_ready,
)
from noteflow.infrastructure.persistence.unit_of_work import SqlAlchemyUnitOfWork
from noteflow.infrastructure.summarization import CloudBackend, CloudSummarizer
from noteflow.infrastructure.webhooks import WebhookExecutor
# Re-export for backward compatibility
from ._startup_banner import print_startup_banner
from ._startup_services import (
check_calendar_needed_from_db,
create_calendar_service,
create_diarization_engine,
create_ner_service,
create_webhook_service,
)
__all__ = [
"AsrConfigLike",
"DiarizationConfigLike",
"GrpcServerConfigLike",
"StartupServices",
"auto_enable_cloud_llm",
"check_calendar_needed_from_db",
"create_calendar_service",
"create_diarization_engine",
"create_ner_service",
"create_webhook_service",
"init_database_and_recovery",
"print_startup_banner",
"setup_summarization_with_consent",
]
# Export functions for testing
__all__ = [
@@ -52,16 +63,6 @@ __all__ = [
]
class DiarizationEngineKwargs(TypedDict, total=False):
"""Type-safe kwargs for DiarizationEngine initialization."""
device: str
hf_token: str | None
streaming_latency: float
min_speakers: int
max_speakers: int
class _SummaryConfig(TypedDict, total=False):
provider: str
api_key: str
@@ -69,7 +70,7 @@ class _SummaryConfig(TypedDict, total=False):
model: str
class _AsrConfigLike(Protocol):
class AsrConfigLike(Protocol):
@property
def model(self) -> str: ...
@@ -80,7 +81,7 @@ class _AsrConfigLike(Protocol):
def compute_type(self) -> str: ...
class _DiarizationConfigLike(Protocol):
class DiarizationConfigLike(Protocol):
@property
def enabled(self) -> bool: ...
@@ -100,18 +101,20 @@ class _DiarizationConfigLike(Protocol):
def max_speakers(self) -> int | None: ...
class _GrpcServerConfigLike(Protocol):
class GrpcServerConfigLike(Protocol):
"""Protocol for gRPC server configuration objects."""
@property
def port(self) -> int: ...
@property
def asr(self) -> _AsrConfigLike: ...
def asr(self) -> AsrConfigLike: ...
@property
def database_url(self) -> str | None: ...
@property
def diarization(self) -> _DiarizationConfigLike: ...
def diarization(self) -> DiarizationConfigLike: ...
logger = get_logger(__name__)
@@ -161,32 +164,6 @@ async def auto_enable_cloud_llm(
return provider
async def check_calendar_needed_from_db(uow: SqlAlchemyUnitOfWork) -> bool:
"""Check if calendar should be enabled based on database OAuth connections.
Args:
uow: Unit of work with integrations access.
Returns:
True if connected calendar integrations exist.
"""
if not uow.supports_integrations:
return False
calendar_integrations = await uow.integrations.list_by_type(CALENDAR)
if connected := [
i
for i in calendar_integrations
if i.status == IntegrationStatus.CONNECTED
]:
logger.info(
"Auto-enabling calendar: found %d connected OAuth integration(s)",
len(connected),
)
return True
return False
async def init_database_and_recovery(
database_url: str,
) -> tuple[AsyncEngine, async_sessionmaker[AsyncSession]]:
@@ -259,243 +236,17 @@ async def setup_summarization_with_consent(
return cloud_llm_provider
def create_ner_service(
session_factory: async_sessionmaker[AsyncSession] | None,
settings: Settings,
) -> NerService | None:
"""Create NER service if enabled and database available.
Args:
session_factory: Database session factory.
settings: Application settings.
Returns:
NerService if enabled, None otherwise.
"""
if not get_feature_flags().ner_enabled:
return None
if not session_factory:
logger.warning(
"NER feature enabled but no database configured. "
"NER requires database for entity persistence."
)
return None
logger.info("Initializing NER service (spaCy)...")
ner_engine = NerEngine()
ner_service = NerService(
ner_engine=ner_engine,
uow_factory=lambda: SqlAlchemyUnitOfWork(session_factory, settings.meetings_dir),
)
logger.info("NER service initialized (model loaded on demand)")
return ner_service
async def create_calendar_service(
session_factory: async_sessionmaker[AsyncSession] | None,
settings: Settings,
) -> CalendarService | None:
"""Create calendar service if needed.
Args:
session_factory: Database session factory.
settings: Application settings.
Returns:
CalendarService if needed and database available, None otherwise.
"""
calendar_needed = get_feature_flags().calendar_enabled or settings.trigger_calendar_enabled
# Check database for existing OAuth connections
if session_factory and not calendar_needed:
async with SqlAlchemyUnitOfWork(session_factory, settings.meetings_dir) as uow:
calendar_needed = await check_calendar_needed_from_db(uow)
if not calendar_needed:
return None
if not session_factory:
logger.warning(
"Calendar feature enabled but no database configured. "
"Calendar requires database for OAuth token persistence."
)
return None
logger.info("Initializing calendar service...")
calendar_settings = get_calendar_settings()
calendar_service = CalendarService(
uow_factory=lambda: SqlAlchemyUnitOfWork(session_factory, settings.meetings_dir),
settings=calendar_settings,
)
logger.info("Calendar service initialized")
return calendar_service
def create_diarization_engine(diarization: _DiarizationConfigLike) -> DiarizationEngine | None:
"""Create diarization engine if enabled and configured.
Args:
diarization: Diarization configuration.
Returns:
DiarizationEngine if enabled, None otherwise.
"""
if not diarization.enabled:
return None
if not diarization.hf_token:
logger.warning(
"Diarization enabled but no HuggingFace token provided. "
"Set NOTEFLOW_DIARIZATION_HF_TOKEN or --diarization-hf-token."
)
return None
logger.info("Initializing diarization engine on %s...", diarization.device)
diarization_kwargs: DiarizationEngineKwargs = {
"device": diarization.device,
"hf_token": diarization.hf_token,
}
if diarization.streaming_latency is not None:
diarization_kwargs["streaming_latency"] = diarization.streaming_latency
if diarization.min_speakers is not None:
diarization_kwargs["min_speakers"] = diarization.min_speakers
if diarization.max_speakers is not None:
diarization_kwargs["max_speakers"] = diarization.max_speakers
engine = DiarizationEngine(**diarization_kwargs)
logger.info("Diarization engine initialized (models loaded on demand)")
return engine
async def create_webhook_service(
session_factory: async_sessionmaker[AsyncSession],
settings: Settings,
) -> WebhookService | None:
"""Create and configure webhook service if enabled.
Args:
session_factory: Database session factory.
settings: Application settings.
Returns:
WebhookService if enabled, None otherwise.
"""
if not get_feature_flags().webhooks_enabled:
return None
logger.info("Initializing webhook service...")
webhook_executor = WebhookExecutor()
webhook_service = WebhookService(executor=webhook_executor)
async with SqlAlchemyUnitOfWork(session_factory, settings.meetings_dir) as uow:
webhook_configs = await uow.webhooks.get_all_enabled()
for config_item in webhook_configs:
webhook_service.register_webhook(config_item)
logger.info(
"Webhook service initialized with %d active webhooks",
len(webhook_configs),
)
return webhook_service
if TYPE_CHECKING:
from noteflow.application.services.calendar import CalendarService
from noteflow.application.services.webhook_service import WebhookService
from noteflow.infrastructure.diarization import DiarizationEngine
@dataclass(frozen=True)
class StartupServices:
"""Optional services for startup diagnostics."""
diarization_engine: DiarizationEngine | None
diarization_engine: "DiarizationEngine | None"
cloud_llm_provider: str | None
calendar_service: CalendarService | None
webhook_service: WebhookService | None
def _log_startup_status(
config: _GrpcServerConfigLike,
services: StartupServices,
) -> None:
"""Log startup status for non-interactive contexts."""
logger.info("NoteFlow server starting on port %d", config.port)
logger.info(
"ASR model: %s (%s/%s)",
config.asr.model,
config.asr.device,
config.asr.compute_type,
)
logger.info("Database: %s", "Connected" if config.database_url else "In-memory mode")
logger.info(
"Diarization: %s",
f"Enabled ({config.diarization.device})"
if services.diarization_engine
else STATUS_DISABLED,
)
logger.info(
"Summarization: %s",
f"Cloud ({services.cloud_llm_provider})"
if services.cloud_llm_provider
else "Local only",
)
logger.info("Calendar: %s", "Enabled" if services.calendar_service else STATUS_DISABLED)
logger.info(
"Webhooks: %s",
f"Enabled ({len(services.webhook_service.configs)} registered)"
if services.webhook_service
else STATUS_DISABLED,
)
def _print_rich_banner(
config: _GrpcServerConfigLike,
services: StartupServices,
) -> None:
"""Print rich console banner for interactive terminals."""
console = Console()
console.print(f"\n[bold green]NoteFlow server running on port {config.port}[/bold green]")
console.print(
f"ASR model: {config.asr.model} ({config.asr.device}/{config.asr.compute_type})"
)
db_status = (
"[green]Connected[/green]" if config.database_url else "[yellow]In-memory mode[/yellow]"
)
console.print(f"Database: {db_status}")
diar_status = (
f"[green]Enabled[/green] ({config.diarization.device})"
if services.diarization_engine
else "[dim]Disabled[/dim]"
)
console.print(f"Diarization: {diar_status}")
summ_status = (
f"[green]Cloud enabled[/green] ({services.cloud_llm_provider})"
if services.cloud_llm_provider
else "[dim]Local only (Ollama/Mock)[/dim]"
)
console.print(f"Summarization: {summ_status}")
console.print(
f"Calendar: {'[green]Enabled[/green]' if services.calendar_service else '[dim]Disabled[/dim]'}"
)
_print_webhook_status(console, services.webhook_service)
console.print("[dim]Press Ctrl+C to stop[/dim]\n")
def _print_webhook_status(console: Console, webhook_service: WebhookService | None) -> None:
"""Print webhook service status to console."""
if webhook_service:
console.print(
f"Webhooks: [green]Enabled[/green] ({len(webhook_service.configs)} registered)"
)
else:
console.print("Webhooks: [dim]Disabled[/dim]")
def print_startup_banner(
config: _GrpcServerConfigLike,
services: StartupServices,
) -> None:
"""Print server startup status banner.
Args:
config: Server configuration.
services: Container with optional startup services.
"""
_log_startup_status(config, services)
if sys.stdout.isatty():
_print_rich_banner(config, services)
calendar_service: "CalendarService | None"
webhook_service: "WebhookService | None"

View File

@@ -0,0 +1,110 @@
"""Startup banner and logging functions."""
from __future__ import annotations
import sys
from typing import TYPE_CHECKING
from rich.console import Console
from noteflow.config.constants import STATUS_DISABLED
from noteflow.infrastructure.logging import get_logger
if TYPE_CHECKING:
from noteflow.application.services.webhook_service import WebhookService
from ._startup import GrpcServerConfigLike, StartupServices
logger = get_logger(__name__)
def log_startup_status(
config: "GrpcServerConfigLike",
services: "StartupServices",
) -> None:
"""Log startup status for non-interactive contexts."""
logger.info("NoteFlow server starting on port %d", config.port)
logger.info(
"ASR model: %s (%s/%s)",
config.asr.model,
config.asr.device,
config.asr.compute_type,
)
logger.info("Database: %s", "Connected" if config.database_url else "In-memory mode")
logger.info(
"Diarization: %s",
f"Enabled ({config.diarization.device})"
if services.diarization_engine
else STATUS_DISABLED,
)
logger.info(
"Summarization: %s",
f"Cloud ({services.cloud_llm_provider})"
if services.cloud_llm_provider
else "Local only",
)
logger.info("Calendar: %s", "Enabled" if services.calendar_service else STATUS_DISABLED)
logger.info(
"Webhooks: %s",
f"Enabled ({len(services.webhook_service.configs)} registered)"
if services.webhook_service
else STATUS_DISABLED,
)
def print_rich_banner(
config: "GrpcServerConfigLike",
services: "StartupServices",
) -> None:
"""Print rich console banner for interactive terminals."""
console = Console()
console.print(f"\n[bold green]NoteFlow server running on port {config.port}[/bold green]")
console.print(
f"ASR model: {config.asr.model} ({config.asr.device}/{config.asr.compute_type})"
)
db_status = (
"[green]Connected[/green]" if config.database_url else "[yellow]In-memory mode[/yellow]"
)
console.print(f"Database: {db_status}")
diar_status = (
f"[green]Enabled[/green] ({config.diarization.device})"
if services.diarization_engine
else "[dim]Disabled[/dim]"
)
console.print(f"Diarization: {diar_status}")
summ_status = (
f"[green]Cloud enabled[/green] ({services.cloud_llm_provider})"
if services.cloud_llm_provider
else "[dim]Local only (Ollama/Mock)[/dim]"
)
console.print(f"Summarization: {summ_status}")
console.print(
f"Calendar: {'[green]Enabled[/green]' if services.calendar_service else '[dim]Disabled[/dim]'}"
)
print_webhook_status(console, services.webhook_service)
console.print("[dim]Press Ctrl+C to stop[/dim]\n")
def print_webhook_status(console: Console, webhook_service: "WebhookService | None") -> None:
"""Print webhook service status to console."""
if webhook_service:
console.print(
f"Webhooks: [green]Enabled[/green] ({len(webhook_service.configs)} registered)"
)
else:
console.print("Webhooks: [dim]Disabled[/dim]")
def print_startup_banner(
config: "GrpcServerConfigLike",
services: "StartupServices",
) -> None:
"""Print server startup status banner.
Args:
config: Server configuration.
services: Container with optional startup services.
"""
log_startup_status(config, services)
if sys.stdout.isatty():
print_rich_banner(config, services)

View File

@@ -0,0 +1,200 @@
"""Service creation functions for server startup."""
from __future__ import annotations
from typing import TYPE_CHECKING, TypedDict
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
from noteflow.application.services.calendar import CalendarService
from noteflow.application.services.ner_service import NerService
from noteflow.application.services.webhook_service import WebhookService
from noteflow.config.settings import Settings, get_calendar_settings, get_feature_flags
from noteflow.domain.constants.fields import CALENDAR
from noteflow.domain.entities.integration import IntegrationStatus
from noteflow.infrastructure.diarization import DiarizationEngine
from noteflow.infrastructure.logging import get_logger
from noteflow.infrastructure.ner import NerEngine
from noteflow.infrastructure.persistence.unit_of_work import SqlAlchemyUnitOfWork
from noteflow.infrastructure.webhooks import WebhookExecutor
if TYPE_CHECKING:
from ._startup import DiarizationConfigLike
logger = get_logger(__name__)
async def check_calendar_needed_from_db(uow: SqlAlchemyUnitOfWork) -> bool:
"""Check if calendar should be enabled based on database OAuth connections.
Args:
uow: Unit of work with integrations access.
Returns:
True if connected calendar integrations exist.
"""
if not uow.supports_integrations:
return False
calendar_integrations = await uow.integrations.list_by_type(CALENDAR)
if connected := [
i
for i in calendar_integrations
if i.status == IntegrationStatus.CONNECTED
]:
logger.info(
"Auto-enabling calendar: found %d connected OAuth integration(s)",
len(connected),
)
return True
return False
class DiarizationEngineKwargs(TypedDict, total=False):
"""Type-safe kwargs for DiarizationEngine initialization."""
device: str
hf_token: str | None
streaming_latency: float
min_speakers: int
max_speakers: int
def create_ner_service(
session_factory: async_sessionmaker[AsyncSession] | None,
settings: Settings,
) -> NerService | None:
"""Create NER service if enabled and database available.
Args:
session_factory: Database session factory.
settings: Application settings.
Returns:
NerService if enabled, None otherwise.
"""
if not get_feature_flags().ner_enabled:
return None
if not session_factory:
logger.warning(
"NER feature enabled but no database configured. "
"NER requires database for entity persistence."
)
return None
logger.info("Initializing NER service (spaCy)...")
ner_engine = NerEngine()
ner_service = NerService(
ner_engine=ner_engine,
uow_factory=lambda: SqlAlchemyUnitOfWork(session_factory, settings.meetings_dir),
)
logger.info("NER service initialized (model loaded on demand)")
return ner_service
async def create_calendar_service(
session_factory: async_sessionmaker[AsyncSession] | None,
settings: Settings,
) -> CalendarService | None:
"""Create calendar service if needed.
Args:
session_factory: Database session factory.
settings: Application settings.
Returns:
CalendarService if needed and database available, None otherwise.
"""
calendar_needed = get_feature_flags().calendar_enabled or settings.trigger_calendar_enabled
# Check database for existing OAuth connections
if session_factory and not calendar_needed:
async with SqlAlchemyUnitOfWork(session_factory, settings.meetings_dir) as uow:
calendar_needed = await check_calendar_needed_from_db(uow)
if not calendar_needed:
return None
if not session_factory:
logger.warning(
"Calendar feature enabled but no database configured. "
"Calendar requires database for OAuth token persistence."
)
return None
logger.info("Initializing calendar service...")
calendar_settings = get_calendar_settings()
calendar_service = CalendarService(
uow_factory=lambda: SqlAlchemyUnitOfWork(session_factory, settings.meetings_dir),
settings=calendar_settings,
)
logger.info("Calendar service initialized")
return calendar_service
def create_diarization_engine(diarization: "DiarizationConfigLike") -> DiarizationEngine | None:
"""Create diarization engine if enabled and configured.
Args:
diarization: Diarization configuration.
Returns:
DiarizationEngine if enabled, None otherwise.
"""
if not diarization.enabled:
return None
if not diarization.hf_token:
logger.warning(
"Diarization enabled but no HuggingFace token provided. "
"Set NOTEFLOW_DIARIZATION_HF_TOKEN or --diarization-hf-token."
)
return None
logger.info("Initializing diarization engine on %s...", diarization.device)
diarization_kwargs: DiarizationEngineKwargs = {
"device": diarization.device,
"hf_token": diarization.hf_token,
}
if diarization.streaming_latency is not None:
diarization_kwargs["streaming_latency"] = diarization.streaming_latency
if diarization.min_speakers is not None:
diarization_kwargs["min_speakers"] = diarization.min_speakers
if diarization.max_speakers is not None:
diarization_kwargs["max_speakers"] = diarization.max_speakers
engine = DiarizationEngine(**diarization_kwargs)
logger.info("Diarization engine initialized (models loaded on demand)")
return engine
async def create_webhook_service(
session_factory: async_sessionmaker[AsyncSession],
settings: Settings,
) -> WebhookService | None:
"""Create and configure webhook service if enabled.
Args:
session_factory: Database session factory.
settings: Application settings.
Returns:
WebhookService if enabled, None otherwise.
"""
if not get_feature_flags().webhooks_enabled:
return None
logger.info("Initializing webhook service...")
webhook_executor = WebhookExecutor()
webhook_service = WebhookService(executor=webhook_executor)
async with SqlAlchemyUnitOfWork(session_factory, settings.meetings_dir) as uow:
webhook_configs = await uow.webhooks.get_all_enabled()
for config_item in webhook_configs:
webhook_service.register_webhook(config_item)
logger.info(
"Webhook service initialized with %d active webhooks",
len(webhook_configs),
)
return webhook_service

View File

@@ -6,33 +6,36 @@ import asyncio
import os
import signal
import time
from collections.abc import Awaitable, Callable
from pathlib import Path
from typing import TYPE_CHECKING, TypedDict, Unpack, cast
import grpc.aio
from pydantic import ValidationError
from noteflow.application.services.summarization_service import SummarizationService
from noteflow.config.constants import DEFAULT_GRPC_PORT, SETTING_CLOUD_CONSENT_GRANTED
from noteflow.config.constants import DEFAULT_GRPC_PORT
from noteflow.config.constants.core import MAIN_MODULE_NAME
from noteflow.config.settings import get_feature_flags, get_settings
from noteflow.infrastructure.asr import FasterWhisperEngine
from noteflow.infrastructure.logging import LoggingConfig, configure_logging, get_logger
from noteflow.infrastructure.persistence.unit_of_work import SqlAlchemyUnitOfWork
from noteflow.infrastructure.summarization import create_summarization_service
from ._cli import build_config_from_args, parse_args
from ._config import DEFAULT_BIND_ADDRESS, AsrConfig, GrpcServerConfig, ServicesConfig
from ._server_helpers import (
create_consent_persist_callback,
load_consent_from_db,
mark_orphaned_jobs_failed,
)
from ._startup import (
StartupServices,
init_database_and_recovery,
setup_summarization_with_consent,
)
from ._startup_banner import print_startup_banner
from ._startup_services import (
create_calendar_service,
create_diarization_engine,
create_ner_service,
create_webhook_service,
init_database_and_recovery,
print_startup_banner,
setup_summarization_with_consent,
)
from .interceptors import IdentityInterceptor, RequestLoggingInterceptor
from .proto import noteflow_pb2_grpc
@@ -58,130 +61,6 @@ logger = get_logger(__name__)
async def _recover_jobs_with_uow(uow: SqlAlchemyUnitOfWork) -> None:
"""Execute job recovery within an active unit of work.
Args:
uow: Active unit of work with database access.
"""
if not uow.supports_diarization_jobs:
logger.debug("Job recovery skipped (diarization jobs not supported)")
return
failed_count = await uow.diarization_jobs.mark_running_as_failed()
await uow.commit()
_log_job_recovery_result(failed_count)
async def _mark_orphaned_jobs_failed(
session_factory: async_sessionmaker[AsyncSession],
meetings_dir: Path,
) -> None:
"""Mark orphaned diarization jobs as failed using provided session factory.
Args:
session_factory: Async session factory for database access.
meetings_dir: Directory for meeting storage.
"""
try:
async with SqlAlchemyUnitOfWork(session_factory, meetings_dir) as uow:
await _recover_jobs_with_uow(uow)
except Exception as exc:
logger.warning("Failed to recover orphaned jobs: %s", exc)
def _log_job_recovery_result(failed_count: int) -> None:
"""Log the result of job recovery."""
if failed_count > 0:
logger.warning(
"Marked %d orphaned diarization job(s) as failed on startup",
failed_count,
)
else:
logger.debug("No orphaned diarization jobs to recover")
async def _apply_stored_consent(
uow: SqlAlchemyUnitOfWork,
summarization_service: SummarizationService,
) -> None:
"""Apply stored consent from database to service.
Args:
uow: Active unit of work with database access.
summarization_service: Service to update with loaded consent.
"""
stored_consent = await uow.preferences.get(SETTING_CLOUD_CONSENT_GRANTED)
if stored_consent is None:
return
summarization_service.settings.cloud_consent_granted = bool(stored_consent)
logger.info(
"Loaded cloud consent from database: %s",
summarization_service.cloud_consent_granted,
)
async def _load_consent_from_db(
session_factory: async_sessionmaker[AsyncSession],
meetings_dir: Path,
summarization_service: SummarizationService,
) -> None:
"""Load cloud consent setting from database.
Args:
session_factory: Async session factory for database access.
meetings_dir: Directory for meeting storage.
summarization_service: Service to update with loaded consent.
"""
try:
async with SqlAlchemyUnitOfWork(session_factory, meetings_dir) as uow:
await _apply_stored_consent(uow, summarization_service)
# INTENTIONAL BROAD HANDLER: Startup resilience
# - Database may be unavailable at startup
# - Consent loading should not block server startup
except Exception:
logger.exception("Failed to load cloud consent from database")
async def _persist_consent_to_db(
uow: SqlAlchemyUnitOfWork,
granted: bool,
) -> None:
"""Persist consent setting to database within active unit of work.
Args:
uow: Active unit of work with database access.
granted: Whether cloud consent is granted.
"""
await uow.preferences.set(SETTING_CLOUD_CONSENT_GRANTED, granted)
await uow.commit()
logger.info("Persisted cloud consent: %s", granted)
def _create_consent_persist_callback(
session_factory: async_sessionmaker[AsyncSession],
) -> Callable[[bool], Awaitable[None]]:
"""Create callback to persist consent changes to database.
Args:
session_factory: Async session factory for database access.
Returns:
Async callback that persists consent changes.
"""
async def persist_consent(granted: bool) -> None:
"""Persist consent change to database."""
try:
settings = get_settings()
async with SqlAlchemyUnitOfWork(session_factory, settings.meetings_dir) as uow:
await _persist_consent_to_db(uow, granted)
# INTENTIONAL BROAD HANDLER: Fire-and-forget persistence
# - Consent persistence should not crash application
# - Next startup will retry
except Exception:
logger.exception("Failed to persist cloud consent")
return persist_consent
class NoteFlowServer:
"""Async gRPC server for NoteFlow."""
@@ -342,7 +221,7 @@ class NoteFlowServer:
return
settings = get_settings()
await _mark_orphaned_jobs_failed(self._session_factory, settings.meetings_dir)
await mark_orphaned_jobs_failed(self._session_factory, settings.meetings_dir)
async def _wire_consent_persistence(self) -> None:
"""Load consent from database and wire persistence callback.
@@ -358,13 +237,13 @@ class NoteFlowServer:
settings = get_settings()
meetings_dir = settings.meetings_dir
await _load_consent_from_db(
await load_consent_from_db(
self._session_factory,
meetings_dir,
self._summarization_service,
)
persist_callback = _create_consent_persist_callback(self._session_factory)
persist_callback = create_consent_persist_callback(self._session_factory)
self._summarization_service.on_consent_change = persist_callback
logger.debug("Consent persistence callback wired")

View File

@@ -3,33 +3,19 @@
from __future__ import annotations
import asyncio
import contextlib
import time
from collections import deque
from pathlib import Path
from typing import TYPE_CHECKING, ClassVar, Final
from uuid import UUID
from noteflow import __version__
from noteflow.config.constants import APP_DIR_NAME
from noteflow.config.constants import DEFAULT_SAMPLE_RATE as _DEFAULT_SAMPLE_RATE
from noteflow.domain.entities import Meeting
from noteflow.domain.identity.context import OperationContext, UserContext, WorkspaceContext
from noteflow.domain.identity.roles import WorkspaceRole
from noteflow.domain.value_objects import MeetingState
from noteflow.grpc.meeting_store import MeetingStore
from noteflow.infrastructure.asr import Segmenter, SegmenterConfig, StreamingVad
from noteflow.infrastructure.audio.partial_buffer import PartialAudioBuffer
from noteflow.infrastructure.asr import Segmenter, StreamingVad
from noteflow.infrastructure.audio.writer import MeetingAudioWriter
from noteflow.infrastructure.logging import (
get_logger,
request_id_var,
user_id_var,
workspace_id_var,
)
from noteflow.infrastructure.persistence.memory import MemoryUnitOfWork
from noteflow.infrastructure.logging import get_logger
from noteflow.infrastructure.persistence.repositories import DiarizationJob
from noteflow.infrastructure.persistence.unit_of_work import SqlAlchemyUnitOfWork
from noteflow.infrastructure.security.crypto import AesGcmCryptoBox
from noteflow.infrastructure.security.keystore import KeyringKeyStore
@@ -42,7 +28,6 @@ from ._mixins import (
DiarizationMixin,
EntitiesMixin,
ExportMixin,
GrpcContext,
IdentityMixin,
MeetingMixin,
ObservabilityMixin,
@@ -56,373 +41,32 @@ from ._mixins import (
WebhooksMixin,
)
from ._service_base import GrpcBaseServicer, NoteFlowServicerStubs
from .proto import noteflow_pb2
from ._service_mixins import (
ServicerAudioMixin,
ServicerContextMixin,
ServicerInfoMixin,
ServicerLifecycleMixin,
ServicerStreamingStateMixin,
ServicerUowMixin,
)
from .stream_state import MeetingStreamState
if TYPE_CHECKING:
from collections.abc import Awaitable, Callable
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
from noteflow.infrastructure.asr import FasterWhisperEngine
from noteflow.infrastructure.auth.oidc_registry import OidcAuthService
from noteflow.infrastructure.diarization.engine import DiarizationEngine
from ._service_stubs import NoteFlowServicerStubs
logger = get_logger(__name__)
async def _cancel_diarization_tasks(servicer: NoteFlowServicer) -> list[str]:
"""Cancel all active diarization tasks and return their IDs."""
cancelled_job_ids = list(servicer.diarization_tasks.keys())
for job_id, task in list(servicer.diarization_tasks.items()):
if task.done():
continue
logger.debug("Cancelling diarization task %s", job_id)
task.cancel()
with contextlib.suppress(asyncio.CancelledError):
await task
servicer.diarization_tasks.clear()
return cancelled_job_ids
def _mark_in_memory_jobs_failed(
servicer: NoteFlowServicer,
cancelled_job_ids: list[str],
) -> None:
if servicer.session_factory is not None or not cancelled_job_ids:
return
failed_count = 0
for job_id in cancelled_job_ids:
job = servicer.diarization_jobs.get(job_id)
if job is None:
continue
if job.status in (
noteflow_pb2.JOB_STATUS_QUEUED,
noteflow_pb2.JOB_STATUS_RUNNING,
):
job.status = noteflow_pb2.JOB_STATUS_FAILED
job.error_message = "ERR_TASK_CANCELLED"
failed_count += 1
if failed_count > 0:
logger.warning(
"Marked %d in-memory diarization jobs as failed on shutdown",
failed_count,
)
def _close_diarization_sessions(servicer: NoteFlowServicer) -> None:
for meeting_id, state in list(servicer.stream_states.items()):
if state.diarization_session is None:
continue
logger.debug("Closing diarization session for meeting %s", meeting_id)
state.diarization_session.close()
state.diarization_session = None
def _close_audio_writers(servicer: NoteFlowServicer) -> None:
for meeting_id in list(servicer.audio_writers.keys()):
logger.debug("Closing audio writer for meeting %s", meeting_id)
servicer.close_audio_writer(meeting_id)
async def _mark_running_jobs_failed_db(servicer: NoteFlowServicer) -> None:
if servicer.session_factory is None:
return
async with servicer.create_uow() as uow:
failed_count = await uow.diarization_jobs.mark_running_as_failed()
await uow.commit()
if failed_count > 0:
logger.warning(
"Marked %d running diarization jobs as failed on shutdown",
failed_count,
)
async def _close_webhook_service(servicer: NoteFlowServicer) -> None:
if servicer.webhook_service is None:
return
logger.debug("Closing webhook service HTTP client")
await servicer.webhook_service.close()
class _ServicerUowMixin:
session_factory: async_sessionmaker[AsyncSession] | None
meetings_dir: Path
memory_store: MeetingStore | None
def use_database(self) -> bool:
"""Check if database persistence is configured."""
return self.session_factory is not None
def get_memory_store(self) -> MeetingStore:
"""Get the in-memory store, raising if not configured."""
if self.memory_store is None:
raise RuntimeError("Memory store not configured")
return self.memory_store
def create_uow(self) -> SqlAlchemyUnitOfWork:
"""Create a new Unit of Work (database-backed)."""
if self.session_factory is None:
raise RuntimeError("Database not configured")
return SqlAlchemyUnitOfWork(self.session_factory, self.meetings_dir)
def create_repository_provider(self) -> SqlAlchemyUnitOfWork | MemoryUnitOfWork:
"""Create a repository provider (database or memory backed)."""
if self.session_factory is not None:
return SqlAlchemyUnitOfWork(self.session_factory, self.meetings_dir)
return MemoryUnitOfWork(self.get_memory_store())
async def _count_active_meetings_db(self) -> int:
"""Count active meetings using database state."""
async with self.create_uow() as uow:
total = 0
for state in (MeetingState.RECORDING, MeetingState.STOPPING):
total += await uow.meetings.count_by_state(state)
return total
class _ServicerContextMixin:
def get_operation_context(self, context: GrpcContext) -> OperationContext:
"""Get operation context from gRPC context variables."""
request_id = request_id_var.get()
user_id_str = user_id_var.get()
workspace_id_str = workspace_id_var.get()
default_user_id = UUID("00000000-0000-0000-0000-000000000001")
default_workspace_id = UUID("00000000-0000-0000-0000-000000000001")
user_id = UUID(user_id_str) if user_id_str else default_user_id
workspace_id = UUID(workspace_id_str) if workspace_id_str else default_workspace_id
return OperationContext(
user=UserContext(user_id=user_id, display_name=""),
workspace=WorkspaceContext(
workspace_id=workspace_id,
workspace_name="",
role=WorkspaceRole.OWNER,
),
request_id=request_id,
)
class _ServicerStreamingStateMixin:
stream_states: dict[str, MeetingStreamState]
vad_instances: dict[str, StreamingVad]
segmenters: dict[str, Segmenter]
segment_counters: dict[str, int]
stream_formats: dict[str, tuple[int, int]]
chunk_sequences: dict[str, int]
chunk_counts: dict[str, int]
chunk_receipt_times: dict[str, deque[float]]
pending_chunks: dict[str, int]
DEFAULT_SAMPLE_RATE: int
def init_streaming_state(self, meeting_id: str, next_segment_id: int) -> None:
"""Initialize VAD, Segmenter, speaking state, and partial buffers for a meeting."""
vad = StreamingVad()
segmenter = Segmenter(config=SegmenterConfig(sample_rate=self.DEFAULT_SAMPLE_RATE))
partial_buffer = PartialAudioBuffer(sample_rate=self.DEFAULT_SAMPLE_RATE)
current_time = time.time()
state = MeetingStreamState(
vad=vad,
segmenter=segmenter,
partial_buffer=partial_buffer,
sample_rate=self.DEFAULT_SAMPLE_RATE,
channels=1,
next_segment_id=next_segment_id,
was_speaking=False,
last_partial_time=current_time,
last_partial_text="",
diarization_session=None,
diarization_turns=[],
diarization_stream_time=0.0,
diarization_streaming_failed=False,
is_active=True,
stop_requested=False,
audio_write_failed=False,
)
self.stream_states[meeting_id] = state
self.vad_instances[meeting_id] = vad
self.segmenters[meeting_id] = segmenter
self.segment_counters[meeting_id] = next_segment_id
def cleanup_streaming_state(self, meeting_id: str) -> None:
"""Clean up VAD, Segmenter, speaking state, and partial buffers for a meeting."""
if (state := self.stream_states.pop(meeting_id, None)) and state.diarization_session is not None:
state.diarization_session.close()
self.vad_instances.pop(meeting_id, None)
self.segmenters.pop(meeting_id, None)
self.segment_counters.pop(meeting_id, None)
self.stream_formats.pop(meeting_id, None)
self.chunk_sequences.pop(meeting_id, None)
self.chunk_counts.pop(meeting_id, None)
if hasattr(self, "_chunk_receipt_times"):
self.chunk_receipt_times.pop(meeting_id, None)
if hasattr(self, "_pending_chunks"):
self.pending_chunks.pop(meeting_id, None)
def get_stream_state(self, meeting_id: str) -> MeetingStreamState | None:
"""Get consolidated streaming state for a meeting."""
state = self.stream_states.get(meeting_id)
return None if state is None else state
def next_segment_id(self, meeting_id: str, fallback: int = 0) -> int:
"""Get and increment the next segment id for a meeting."""
next_id = self.segment_counters.get(meeting_id)
if next_id is None:
next_id = fallback
self.segment_counters[meeting_id] = next_id + 1
return next_id
class _ServicerAudioMixin:
crypto: AesGcmCryptoBox
meetings_dir: Path
audio_writers: dict[str, MeetingAudioWriter]
audio_write_failed: set[str]
DEFAULT_SAMPLE_RATE: int
def ensure_meeting_dek(self, meeting: Meeting) -> tuple[bytes, bytes, bool]:
"""Ensure meeting has a DEK, generating one if needed."""
if meeting.wrapped_dek is None:
dek = self.crypto.generate_dek()
wrapped_dek = self.crypto.wrap_dek(dek)
meeting.wrapped_dek = wrapped_dek
return dek, wrapped_dek, True
wrapped_dek = meeting.wrapped_dek
dek = self.crypto.unwrap_dek(wrapped_dek)
return dek, wrapped_dek, False
def start_meeting_if_needed(self, meeting: Meeting) -> tuple[bool, str | None]:
"""Start recording on meeting if not already recording."""
if meeting.state == MeetingState.RECORDING:
return False, None
try:
meeting.start_recording()
return True, None
except ValueError as e:
return False, str(e)
def open_meeting_audio_writer(
self,
meeting_id: str,
dek: bytes,
wrapped_dek: bytes,
asset_path: str | None = None,
) -> None:
"""Open audio writer for a meeting."""
writer = MeetingAudioWriter(self.crypto, self.meetings_dir)
writer.open(
meeting_id=meeting_id,
dek=dek,
wrapped_dek=wrapped_dek,
sample_rate=self.DEFAULT_SAMPLE_RATE,
asset_path=asset_path,
)
self.audio_writers[meeting_id] = writer
logger.info("Audio writer opened for meeting %s", meeting_id)
def close_audio_writer(self, meeting_id: str) -> None:
"""Close and remove the audio writer for a meeting."""
self.audio_write_failed.discard(meeting_id)
if meeting_id not in self.audio_writers:
return
try:
writer = self.audio_writers.pop(meeting_id)
writer.close()
logger.info(
"Audio writer closed for meeting %s: %d bytes written",
meeting_id,
writer.bytes_written,
)
except (OSError, RuntimeError) as e:
logger.error(
"Failed to close audio writer for meeting %s: %s",
meeting_id,
e,
)
class _ServicerInfoMixin:
asr_engine: FasterWhisperEngine | None
diarization_engine: DiarizationEngine | None
session_factory: async_sessionmaker[AsyncSession] | None
memory_store: MeetingStore | None
_start_time: float
SUPPORTED_SAMPLE_RATES: ClassVar[list[int]]
MAX_CHUNK_SIZE: int
VERSION: str
STATE_VERSION: int
_count_active_meetings_db: Callable[..., Awaitable[int]]
get_memory_store: Callable[..., MeetingStore]
async def GetServerInfo(
self,
request: noteflow_pb2.ServerInfoRequest,
context: GrpcContext,
) -> noteflow_pb2.ServerInfo:
"""Get server information."""
asr_model = ""
asr_ready = False
if self.asr_engine:
asr_ready = self.asr_engine.is_loaded
asr_model = self.asr_engine.model_size or ""
diarization_enabled = self.diarization_engine is not None
diarization_ready = self.diarization_engine is not None and (
self.diarization_engine.is_streaming_loaded
or self.diarization_engine.is_offline_loaded
)
if self.session_factory is not None:
active = await self._count_active_meetings_db()
else:
active = self.get_memory_store().active_count
return noteflow_pb2.ServerInfo(
version=self.VERSION,
asr_model=asr_model,
asr_ready=asr_ready,
supported_sample_rates=self.SUPPORTED_SAMPLE_RATES,
max_chunk_size=self.MAX_CHUNK_SIZE,
uptime_seconds=time.time() - self._start_time,
active_meetings=active,
diarization_enabled=diarization_enabled,
diarization_ready=diarization_ready,
state_version=self.STATE_VERSION,
)
class _ServicerLifecycleMixin:
async def shutdown(self) -> None:
"""Clean up servicer state before server stops."""
logger.info("Shutting down servicer...")
cancelled_job_ids = await _cancel_diarization_tasks(self)
_mark_in_memory_jobs_failed(self, cancelled_job_ids)
_close_diarization_sessions(self)
_close_audio_writers(self)
await _mark_running_jobs_failed_db(self)
await _close_webhook_service(self)
logger.info("Servicer shutdown complete")
class NoteFlowServicer(
_ServicerUowMixin,
_ServicerContextMixin,
_ServicerStreamingStateMixin,
_ServicerAudioMixin,
_ServicerInfoMixin,
_ServicerLifecycleMixin,
ServicerUowMixin,
ServicerContextMixin,
ServicerStreamingStateMixin,
ServicerAudioMixin,
ServicerInfoMixin,
ServicerLifecycleMixin,
StreamingMixin,
DiarizationMixin,
DiarizationJobMixin,

View File

@@ -1,13 +1,11 @@
"""Authentication infrastructure components."""
from noteflow.infrastructure.auth._presets import PROVIDER_PRESETS
from noteflow.infrastructure.auth.oidc_discovery import (
OidcDiscoveryClient,
OidcDiscoveryError,
)
from noteflow.infrastructure.auth.oidc_registry import (
PROVIDER_PRESETS,
OidcProviderRegistry,
)
from noteflow.infrastructure.auth.oidc_registry import OidcProviderRegistry
__all__ = [
"PROVIDER_PRESETS",

View File

@@ -0,0 +1,165 @@
"""OIDC provider preset configurations.
Pre-configured settings for popular OIDC providers like Authentik,
Authelia, Keycloak, Auth0, Okta, and Azure AD.
"""
from __future__ import annotations
from dataclasses import dataclass
from noteflow.domain.auth.oidc import (
ClaimMapping,
OidcProviderPreset,
)
from noteflow.domain.auth.oidc_constants import (
CLAIM_EMAIL,
CLAIM_EMAIL_VERIFIED,
CLAIM_GROUPS,
CLAIM_PICTURE,
CLAIM_PREFERRED_USERNAME,
FIELD_PRESET,
OIDC_SCOPE_EMAIL,
OIDC_SCOPE_GROUPS,
OIDC_SCOPE_OPENID,
OIDC_SCOPE_PROFILE,
)
@dataclass(frozen=True, slots=True)
class ProviderPresetConfig:
"""Pre-configured settings for a provider preset.
These settings represent the defaults and recommendations for each
provider type. Users can override these when creating a provider.
"""
preset: OidcProviderPreset
display_name: str
description: str
default_scopes: tuple[str, ...]
claim_mapping: ClaimMapping
documentation_url: str | None = None
notes: str | None = None
def to_dict(self) -> dict[str, object]:
"""Convert preset config to dictionary representation."""
return {
FIELD_PRESET: self.preset.value,
"display_name": self.display_name,
"description": self.description,
"default_scopes": list(self.default_scopes),
"documentation_url": self.documentation_url,
"notes": self.notes,
}
# Standard claim mapping used by most providers
_STANDARD_CLAIM_MAPPING = ClaimMapping(
subject_claim="sub",
email_claim=CLAIM_EMAIL,
email_verified_claim=CLAIM_EMAIL_VERIFIED,
name_claim="name",
preferred_username_claim=CLAIM_PREFERRED_USERNAME,
groups_claim=CLAIM_GROUPS,
picture_claim=CLAIM_PICTURE,
)
# Provider preset configurations
PROVIDER_PRESETS: dict[OidcProviderPreset, ProviderPresetConfig] = {
OidcProviderPreset.AUTHENTIK: ProviderPresetConfig(
preset=OidcProviderPreset.AUTHENTIK,
display_name="Authentik",
description="Open-source Identity Provider focused on flexibility and versatility",
default_scopes=(OIDC_SCOPE_OPENID, OIDC_SCOPE_PROFILE, OIDC_SCOPE_EMAIL, OIDC_SCOPE_GROUPS),
claim_mapping=_STANDARD_CLAIM_MAPPING,
documentation_url="https://docs.goauthentik.io/docs/providers/oauth2",
notes="Authentik supports standard OIDC claims and custom attributes via property mappings.",
),
OidcProviderPreset.AUTHELIA: ProviderPresetConfig(
preset=OidcProviderPreset.AUTHELIA,
display_name="Authelia",
description="Open-source authentication and authorization server",
default_scopes=(OIDC_SCOPE_OPENID, OIDC_SCOPE_PROFILE, OIDC_SCOPE_EMAIL, OIDC_SCOPE_GROUPS),
claim_mapping=_STANDARD_CLAIM_MAPPING,
documentation_url="https://www.authelia.com/integration/openid-connect/",
notes="Authelia requires explicit client registration in configuration.yml.",
),
OidcProviderPreset.KEYCLOAK: ProviderPresetConfig(
preset=OidcProviderPreset.KEYCLOAK,
display_name="Keycloak",
description="Open-source Identity and Access Management",
default_scopes=(OIDC_SCOPE_OPENID, OIDC_SCOPE_PROFILE, OIDC_SCOPE_EMAIL),
claim_mapping=_STANDARD_CLAIM_MAPPING,
documentation_url="https://www.keycloak.org/docs/latest/server_admin/#_oidc",
notes="For groups claim, add a 'Group Membership' mapper to the client scope.",
),
OidcProviderPreset.AUTH0: ProviderPresetConfig(
preset=OidcProviderPreset.AUTH0,
display_name="Auth0",
description="Identity platform for application builders",
default_scopes=(OIDC_SCOPE_OPENID, OIDC_SCOPE_PROFILE, OIDC_SCOPE_EMAIL),
claim_mapping=ClaimMapping(
subject_claim="sub",
email_claim=CLAIM_EMAIL,
email_verified_claim=CLAIM_EMAIL_VERIFIED,
name_claim="name",
preferred_username_claim="nickname", # Auth0 uses nickname
groups_claim="https://your-namespace/groups", # Custom claim with namespace
picture_claim=CLAIM_PICTURE,
),
documentation_url="https://auth0.com/docs/get-started/apis/scopes/openid-connect-scopes",
notes="Groups require an Auth0 Action or Rule to add custom claims.",
),
OidcProviderPreset.OKTA: ProviderPresetConfig(
preset=OidcProviderPreset.OKTA,
display_name="Okta",
description="Enterprise identity management",
default_scopes=(OIDC_SCOPE_OPENID, OIDC_SCOPE_PROFILE, OIDC_SCOPE_EMAIL, OIDC_SCOPE_GROUPS),
claim_mapping=_STANDARD_CLAIM_MAPPING,
documentation_url="https://developer.okta.com/docs/reference/api/oidc/",
notes="Ensure 'groups' scope is enabled for the application in Okta.",
),
OidcProviderPreset.AZURE_AD: ProviderPresetConfig(
preset=OidcProviderPreset.AZURE_AD,
display_name="Microsoft Entra ID (Azure AD)",
description="Microsoft's cloud-based identity service",
default_scopes=(OIDC_SCOPE_OPENID, OIDC_SCOPE_PROFILE, OIDC_SCOPE_EMAIL),
claim_mapping=_STANDARD_CLAIM_MAPPING,
documentation_url="https://learn.microsoft.com/en-us/entra/identity-platform/",
notes="Configure optional claims in App Registration for groups. Use v2.0 endpoint.",
),
OidcProviderPreset.CUSTOM: ProviderPresetConfig(
preset=OidcProviderPreset.CUSTOM,
display_name="Custom OIDC Provider",
description="Any OIDC-compliant identity provider",
default_scopes=(OIDC_SCOPE_OPENID, OIDC_SCOPE_PROFILE, OIDC_SCOPE_EMAIL),
claim_mapping=ClaimMapping(),
documentation_url=None,
notes="Configure endpoints and claims based on your provider's documentation.",
),
}
def get_preset_config(preset: OidcProviderPreset) -> ProviderPresetConfig:
"""Get the preset configuration for a provider type.
Args:
preset: Provider preset type.
Returns:
Preset configuration with defaults.
"""
config = PROVIDER_PRESETS.get(preset)
if config is None:
return PROVIDER_PRESETS[OidcProviderPreset.CUSTOM]
return config
def get_all_preset_options() -> list[dict[str, object]]:
"""Get all available provider presets with their configurations.
Returns:
List of preset information dictionaries.
"""
return [config.to_dict() for config in PROVIDER_PRESETS.values()]

View File

@@ -57,6 +57,48 @@ def _validate_required_fields(data: dict[str, object], issuer_url: str) -> None:
)
def _handle_timeout_error(
exc: httpx.TimeoutException, discovery_url: str, issuer_url: str
) -> OidcDiscoveryError:
"""Handle timeout exception during discovery fetch."""
logger.warning("OIDC discovery timeout for %s", issuer_url)
return OidcDiscoveryError(
f"Timeout fetching discovery document from {discovery_url}",
issuer_url=issuer_url,
)
def _handle_http_status_error(
exc: httpx.HTTPStatusError, issuer_url: str
) -> OidcDiscoveryError:
"""Handle HTTP status error during discovery fetch."""
logger.warning(
"OIDC discovery HTTP error for %s: %s", issuer_url, exc.response.status_code,
)
return OidcDiscoveryError(
f"HTTP {exc.response.status_code} fetching discovery document",
issuer_url=issuer_url,
)
def _handle_request_error(
exc: httpx.RequestError, issuer_url: str
) -> OidcDiscoveryError:
"""Handle request error during discovery fetch."""
logger.warning("OIDC discovery request error for %s: %s", issuer_url, exc)
return OidcDiscoveryError(
f"Request error fetching discovery document: {exc}",
issuer_url=issuer_url,
)
def _handle_json_parse_error(exc: ValueError, issuer_url: str) -> OidcDiscoveryError:
"""Handle JSON parse error during discovery fetch."""
_ = exc # unused but required for exception chaining context
logger.warning("OIDC discovery JSON parse error for %s", issuer_url)
return OidcDiscoveryError("Invalid JSON in discovery document", issuer_url=issuer_url)
def _check_issuer_match(data: dict[str, object], issuer_url: str) -> None:
"""Check that the issuer in discovery matches the expected URL.
@@ -137,41 +179,19 @@ class OidcDiscoveryClient:
"""
try:
async with httpx.AsyncClient(
timeout=self._timeout,
verify=self._verify_ssl,
timeout=self._timeout, verify=self._verify_ssl,
) as client:
response = await client.get(discovery_url)
response.raise_for_status()
return response.json()
except httpx.TimeoutException as exc:
logger.warning("OIDC discovery timeout for %s", issuer_url)
raise OidcDiscoveryError(
f"Timeout fetching discovery document from {discovery_url}",
issuer_url=issuer_url,
) from exc
raise _handle_timeout_error(exc, discovery_url, issuer_url) from exc
except httpx.HTTPStatusError as exc:
logger.warning(
"OIDC discovery HTTP error for %s: %s",
issuer_url,
exc.response.status_code,
)
raise OidcDiscoveryError(
f"HTTP {exc.response.status_code} fetching discovery document",
issuer_url=issuer_url,
) from exc
raise _handle_http_status_error(exc, issuer_url) from exc
except httpx.RequestError as exc:
logger.warning("OIDC discovery request error for %s: %s", issuer_url, exc)
raise OidcDiscoveryError(
f"Request error fetching discovery document: {exc}",
issuer_url=issuer_url,
) from exc
raise _handle_request_error(exc, issuer_url) from exc
except ValueError as exc:
logger.warning("OIDC discovery JSON parse error for %s", issuer_url)
raise OidcDiscoveryError(
"Invalid JSON in discovery document",
issuer_url=issuer_url,
) from exc
raise _handle_json_parse_error(exc, issuer_url) from exc
def _parse_discovery(
self,

View File

@@ -1,7 +1,6 @@
"""OIDC provider registry with presets for common identity providers.
"""OIDC provider registry for managing provider configurations.
This module provides pre-configured settings for popular OIDC providers
like Authentik, Authelia, Keycloak, Auth0, Okta, and Azure AD.
Handles provider creation, discovery refresh, and validation.
"""
from __future__ import annotations
@@ -11,23 +10,15 @@ from typing import TYPE_CHECKING
from uuid import UUID
from noteflow.domain.auth.oidc import (
ClaimMapping,
OidcProviderConfig,
OidcProviderCreateParams,
OidcProviderPreset,
OidcProviderRegistration,
)
from noteflow.domain.auth.oidc_constants import (
CLAIM_EMAIL,
CLAIM_EMAIL_VERIFIED,
CLAIM_GROUPS,
CLAIM_PICTURE,
CLAIM_PREFERRED_USERNAME,
FIELD_PRESET,
OIDC_SCOPE_EMAIL,
OIDC_SCOPE_GROUPS,
OIDC_SCOPE_OPENID,
OIDC_SCOPE_PROFILE,
from noteflow.infrastructure.auth._presets import (
ProviderPresetConfig,
get_all_preset_options,
get_preset_config,
)
from noteflow.infrastructure.auth.oidc_discovery import (
OidcDiscoveryClient,
@@ -40,149 +31,6 @@ if TYPE_CHECKING:
logger = get_logger(__name__)
@dataclass(frozen=True, slots=True)
class ProviderPresetConfig:
"""Pre-configured settings for a provider preset.
These settings represent the defaults and recommendations for each
provider type. Users can override these when creating a provider.
"""
preset: OidcProviderPreset
display_name: str
description: str
default_scopes: tuple[str, ...]
claim_mapping: ClaimMapping
documentation_url: str | None = None
notes: str | None = None
def to_dict(self) -> dict[str, object]:
"""Convert preset config to dictionary representation."""
return {
FIELD_PRESET: self.preset.value,
"display_name": self.display_name,
"description": self.description,
"default_scopes": list(self.default_scopes),
"documentation_url": self.documentation_url,
"notes": self.notes,
}
# Provider preset configurations
PROVIDER_PRESETS: dict[OidcProviderPreset, ProviderPresetConfig] = {
OidcProviderPreset.AUTHENTIK: ProviderPresetConfig(
preset=OidcProviderPreset.AUTHENTIK,
display_name="Authentik",
description="Open-source Identity Provider focused on flexibility and versatility",
default_scopes=(OIDC_SCOPE_OPENID, OIDC_SCOPE_PROFILE, OIDC_SCOPE_EMAIL, OIDC_SCOPE_GROUPS),
claim_mapping=ClaimMapping(
subject_claim="sub",
email_claim=CLAIM_EMAIL,
email_verified_claim=CLAIM_EMAIL_VERIFIED,
name_claim="name",
preferred_username_claim=CLAIM_PREFERRED_USERNAME,
groups_claim=CLAIM_GROUPS,
picture_claim=CLAIM_PICTURE,
),
documentation_url="https://docs.goauthentik.io/docs/providers/oauth2",
notes="Authentik supports standard OIDC claims and custom attributes via property mappings.",
),
OidcProviderPreset.AUTHELIA: ProviderPresetConfig(
preset=OidcProviderPreset.AUTHELIA,
display_name="Authelia",
description="Open-source authentication and authorization server",
default_scopes=(OIDC_SCOPE_OPENID, OIDC_SCOPE_PROFILE, OIDC_SCOPE_EMAIL, OIDC_SCOPE_GROUPS),
claim_mapping=ClaimMapping(
subject_claim="sub",
email_claim=CLAIM_EMAIL,
email_verified_claim=CLAIM_EMAIL_VERIFIED,
name_claim="name",
preferred_username_claim=CLAIM_PREFERRED_USERNAME,
groups_claim=CLAIM_GROUPS,
picture_claim=CLAIM_PICTURE,
),
documentation_url="https://www.authelia.com/integration/openid-connect/",
notes="Authelia requires explicit client registration in configuration.yml.",
),
OidcProviderPreset.KEYCLOAK: ProviderPresetConfig(
preset=OidcProviderPreset.KEYCLOAK,
display_name="Keycloak",
description="Open-source Identity and Access Management",
default_scopes=(OIDC_SCOPE_OPENID, OIDC_SCOPE_PROFILE, OIDC_SCOPE_EMAIL),
claim_mapping=ClaimMapping(
subject_claim="sub",
email_claim=CLAIM_EMAIL,
email_verified_claim=CLAIM_EMAIL_VERIFIED,
name_claim="name",
preferred_username_claim=CLAIM_PREFERRED_USERNAME,
groups_claim=CLAIM_GROUPS, # Requires mapper configuration
picture_claim=CLAIM_PICTURE,
),
documentation_url="https://www.keycloak.org/docs/latest/server_admin/#_oidc",
notes="For groups claim, add a 'Group Membership' mapper to the client scope.",
),
OidcProviderPreset.AUTH0: ProviderPresetConfig(
preset=OidcProviderPreset.AUTH0,
display_name="Auth0",
description="Identity platform for application builders",
default_scopes=(OIDC_SCOPE_OPENID, OIDC_SCOPE_PROFILE, OIDC_SCOPE_EMAIL),
claim_mapping=ClaimMapping(
subject_claim="sub",
email_claim=CLAIM_EMAIL,
email_verified_claim=CLAIM_EMAIL_VERIFIED,
name_claim="name",
preferred_username_claim="nickname", # Auth0 uses nickname
groups_claim="https://your-namespace/groups", # Custom claim with namespace
picture_claim=CLAIM_PICTURE,
),
documentation_url="https://auth0.com/docs/get-started/apis/scopes/openid-connect-scopes",
notes="Groups require an Auth0 Action or Rule to add custom claims.",
),
OidcProviderPreset.OKTA: ProviderPresetConfig(
preset=OidcProviderPreset.OKTA,
display_name="Okta",
description="Enterprise identity management",
default_scopes=(OIDC_SCOPE_OPENID, OIDC_SCOPE_PROFILE, OIDC_SCOPE_EMAIL, OIDC_SCOPE_GROUPS),
claim_mapping=ClaimMapping(
subject_claim="sub",
email_claim=CLAIM_EMAIL,
email_verified_claim=CLAIM_EMAIL_VERIFIED,
name_claim="name",
preferred_username_claim=CLAIM_PREFERRED_USERNAME,
groups_claim=CLAIM_GROUPS,
picture_claim=CLAIM_PICTURE,
),
documentation_url="https://developer.okta.com/docs/reference/api/oidc/",
notes="Ensure 'groups' scope is enabled for the application in Okta.",
),
OidcProviderPreset.AZURE_AD: ProviderPresetConfig(
preset=OidcProviderPreset.AZURE_AD,
display_name="Microsoft Entra ID (Azure AD)",
description="Microsoft's cloud-based identity service",
default_scopes=(OIDC_SCOPE_OPENID, OIDC_SCOPE_PROFILE, OIDC_SCOPE_EMAIL),
claim_mapping=ClaimMapping(
subject_claim="sub",
email_claim=CLAIM_EMAIL,
email_verified_claim=CLAIM_EMAIL_VERIFIED, # Not standard in Azure
name_claim="name",
preferred_username_claim=CLAIM_PREFERRED_USERNAME,
groups_claim=CLAIM_GROUPS, # Requires optional claim configuration
picture_claim=CLAIM_PICTURE,
),
documentation_url="https://learn.microsoft.com/en-us/entra/identity-platform/",
notes="Configure optional claims in App Registration for groups. Use v2.0 endpoint.",
),
OidcProviderPreset.CUSTOM: ProviderPresetConfig(
preset=OidcProviderPreset.CUSTOM,
display_name="Custom OIDC Provider",
description="Any OIDC-compliant identity provider",
default_scopes=(OIDC_SCOPE_OPENID, OIDC_SCOPE_PROFILE, OIDC_SCOPE_EMAIL),
claim_mapping=ClaimMapping(),
documentation_url=None,
notes="Configure endpoints and claims based on your provider's documentation.",
),
}
def _merge_params_with_preset(
params: OidcProviderCreateParams,
@@ -227,10 +75,7 @@ class OidcProviderRegistry:
Returns:
Preset configuration with defaults.
"""
config = PROVIDER_PRESETS.get(preset)
if config is None:
return PROVIDER_PRESETS[OidcProviderPreset.CUSTOM]
return config
return get_preset_config(preset)
async def create_provider(
self,
@@ -467,7 +312,15 @@ class OidcAuthService:
def get_preset_options(self) -> list[dict[str, object]]:
"""Get all available provider presets with their configurations.
Filters out the CUSTOM preset template and returns presets sorted by name
for consistent ordering in UI presentation.
Returns:
List of preset information dictionaries.
List of preset information dictionaries, sorted by name.
"""
return [config.to_dict() for config in PROVIDER_PRESETS.values()]
all_presets = get_all_preset_options()
# Filter out CUSTOM template and sort by name for consistent ordering
filtered = [p for p in all_presets if p.get("preset") != "custom"]
filtered.sort(key=lambda p: str(p.get("name", "")))
logger.debug("Returning %d OIDC provider presets", len(filtered))
return filtered

View File

@@ -0,0 +1,81 @@
"""Type definitions for Microsoft Graph Calendar API responses."""
from __future__ import annotations
from dataclasses import dataclass
from typing import TypedDict
@dataclass(frozen=True, slots=True)
class OutlookEventQuery:
"""Query parameters for fetching calendar events."""
start_time: str
end_time: str
hours_ahead: int
limit: int
class OutlookDateTime(TypedDict, total=False):
"""Microsoft Graph datetime format."""
dateTime: str
timeZone: str
class OutlookEmailAddress(TypedDict, total=False):
"""Microsoft Graph email address format."""
address: str
class OutlookAttendee(TypedDict, total=False):
"""Microsoft Graph attendee format."""
emailAddress: OutlookEmailAddress
class OutlookLocation(TypedDict, total=False):
"""Microsoft Graph location format."""
displayName: str
class OutlookOnlineMeeting(TypedDict, total=False):
"""Microsoft Graph online meeting format."""
joinUrl: str
class OutlookEvent(TypedDict, total=False):
"""Microsoft Graph calendar event format."""
id: str
subject: str
start: OutlookDateTime
end: OutlookDateTime
isAllDay: bool
attendees: list[OutlookAttendee]
seriesMasterId: str
location: OutlookLocation
bodyPreview: str
onlineMeeting: OutlookOnlineMeeting
onlineMeetingUrl: str
class OutlookEventsResponse(TypedDict, total=False):
"""Outlook API events response with pagination support.
Note: The @odata.nextLink field is accessed dynamically via dict.get()
since @ is not a valid Python identifier.
"""
value: list[OutlookEvent]
class OutlookProfile(TypedDict, total=False):
"""Microsoft Graph user profile format."""
mail: str
userPrincipalName: str
displayName: str

View File

@@ -55,8 +55,25 @@ def generate_code_verifier() -> str:
Uses PKCE_CODE_VERIFIER_BYTES (64) random bytes, producing
a base64url-encoded string of approximately 86 characters.
Per RFC 7636, the code verifier must be 43-128 characters using
unreserved URI characters [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~".
Returns:
A cryptographically random URL-safe string suitable for PKCE.
Raises:
ValueError: If generated verifier doesn't meet PKCE length requirements.
"""
return secrets.token_urlsafe(PKCE_CODE_VERIFIER_BYTES)
verifier = secrets.token_urlsafe(PKCE_CODE_VERIFIER_BYTES)
# RFC 7636 requires code_verifier to be 43-128 characters
min_length, max_length = 43, 128
if not (min_length <= len(verifier) <= max_length):
raise ValueError(
f"Generated code verifier length {len(verifier)} outside "
f"PKCE requirement [{min_length}, {max_length}]"
)
return verifier
def generate_code_challenge(verifier: str) -> str:
@@ -130,8 +147,26 @@ def generate_state_token() -> str:
Uses OAUTH_STATE_TOKEN_BYTES (32) random bytes, producing
a base64url-encoded string of approximately 43 characters.
The state parameter prevents CSRF attacks by binding the authorization
request to the user's session. The token must have sufficient entropy
to be unguessable.
Returns:
A cryptographically random URL-safe string for OAuth state.
Raises:
ValueError: If generated token has insufficient entropy (< 20 chars).
"""
return secrets.token_urlsafe(OAUTH_STATE_TOKEN_BYTES)
token = secrets.token_urlsafe(OAUTH_STATE_TOKEN_BYTES)
# Ensure minimum entropy for security (at least 20 characters)
min_entropy_length = 20
if len(token) < min_entropy_length:
raise ValueError(
f"Generated state token length {len(token)} has insufficient entropy "
f"(minimum {min_entropy_length} characters required)"
)
return token
def create_oauth_state(config: OAuthStateConfig) -> OAuthState:

View File

@@ -5,9 +5,8 @@ Implements CalendarPort for Outlook using Microsoft Graph API.
from __future__ import annotations
from dataclasses import dataclass
from datetime import UTC, datetime, timedelta
from typing import Final, TypedDict, cast
from typing import Final, cast
import httpx
@@ -24,6 +23,14 @@ from noteflow.config.constants.core import HOURS_PER_DAY
from noteflow.domain.constants.fields import ATTENDEES, LOCATION, START
from noteflow.domain.ports.calendar import CalendarEventInfo, CalendarPort
from noteflow.domain.value_objects import OAuthProvider
from noteflow.infrastructure.calendar._outlook_types import (
OutlookAttendee,
OutlookDateTime,
OutlookEvent,
OutlookEventQuery,
OutlookEventsResponse,
OutlookProfile,
)
from noteflow.infrastructure.logging import get_logger, log_timing
logger = get_logger(__name__)
@@ -35,65 +42,6 @@ MAX_ERROR_BODY_LENGTH: Final[int] = 500
GRAPH_API_MAX_PAGE_SIZE: Final[int] = 100 # Graph API maximum
@dataclass(frozen=True, slots=True)
class _OutlookEventQuery:
"""Query parameters for fetching calendar events."""
start_time: str
end_time: str
hours_ahead: int
limit: int
class _OutlookDateTime(TypedDict, total=False):
dateTime: str
timeZone: str
class _OutlookEmailAddress(TypedDict, total=False):
address: str
class _OutlookAttendee(TypedDict, total=False):
emailAddress: _OutlookEmailAddress
class _OutlookLocation(TypedDict, total=False):
displayName: str
class _OutlookOnlineMeeting(TypedDict, total=False):
joinUrl: str
class _OutlookEvent(TypedDict, total=False):
id: str
subject: str
start: _OutlookDateTime
end: _OutlookDateTime
isAllDay: bool
attendees: list[_OutlookAttendee]
seriesMasterId: str
location: _OutlookLocation
bodyPreview: str
onlineMeeting: _OutlookOnlineMeeting
onlineMeetingUrl: str
class _OutlookEventsResponse(TypedDict, total=False):
"""Outlook API events response with pagination support.
Note: The @odata.nextLink field is accessed dynamically via dict.get()
since @ is not a valid Python identifier.
"""
value: list[_OutlookEvent]
class _OutlookProfile(TypedDict, total=False):
mail: str
userPrincipalName: str
class OutlookCalendarError(Exception):
"""Outlook Calendar API error."""
@@ -162,12 +110,12 @@ class OutlookCalendarAdapter(CalendarPort):
@staticmethod
def _build_event_query(hours_ahead: int, limit: int) -> _OutlookEventQuery:
def _build_event_query(hours_ahead: int, limit: int) -> OutlookEventQuery:
"""Build query parameters for calendar events request."""
now = datetime.now(UTC)
start_time = now.strftime("%Y-%m-%dT%H:%M:%SZ")
end_time = (now + timedelta(hours=hours_ahead)).strftime("%Y-%m-%dT%H:%M:%SZ")
return _OutlookEventQuery(
return OutlookEventQuery(
start_time=start_time,
end_time=end_time,
hours_ahead=hours_ahead,
@@ -186,7 +134,7 @@ class OutlookCalendarAdapter(CalendarPort):
self,
client: httpx.AsyncClient,
headers: dict[str, str],
query: _OutlookEventQuery,
query: OutlookEventQuery,
) -> list[CalendarEventInfo]:
"""Fetch events with pagination handling."""
page_size = min(query.limit, GRAPH_API_MAX_PAGE_SIZE)
@@ -226,7 +174,7 @@ class OutlookCalendarAdapter(CalendarPort):
def _accumulate_events(
self,
items: list[_OutlookEvent],
items: list[OutlookEvent],
all_events: list[CalendarEventInfo],
limit: int,
) -> tuple[list[CalendarEventInfo], bool]:
@@ -268,13 +216,13 @@ class OutlookCalendarAdapter(CalendarPort):
@staticmethod
def _parse_events_response(
response: httpx.Response,
) -> tuple[list[_OutlookEvent], str | None] | None:
) -> tuple[list[OutlookEvent], str | None] | None:
"""Parse event payload and next link from the response."""
data_value = response.json()
if not isinstance(data_value, dict):
logger.warning("Unexpected Microsoft Graph response payload")
return None
data = cast(_OutlookEventsResponse, data_value)
data = cast(OutlookEventsResponse, data_value)
items = data.get("value", [])
next_link = data.get("@odata.nextLink") or data.get("@odata_nextLink")
next_url = str(next_link) if isinstance(next_link, str) else None
@@ -328,7 +276,7 @@ class OutlookCalendarAdapter(CalendarPort):
data_value = response.json()
if not isinstance(data_value, dict):
raise OutlookCalendarError("Invalid user profile response")
data = cast(_OutlookProfile, data_value)
data = cast(OutlookProfile, data_value)
email = data.get("mail") or data.get("userPrincipalName")
if not email:
@@ -347,7 +295,7 @@ class OutlookCalendarAdapter(CalendarPort):
get_user_email = user_email
get_user_info = user_info
def _parse_outlook_event(self, item: _OutlookEvent) -> CalendarEventInfo:
def _parse_outlook_event(self, item: OutlookEvent) -> CalendarEventInfo:
"""Parse Microsoft Graph event into CalendarEventInfo."""
event_id = str(item.get("id", ""))
title = str(item.get("subject", DEFAULT_MEETING_TITLE))
@@ -395,7 +343,7 @@ class OutlookCalendarAdapter(CalendarPort):
raw=dict(item),
)
def _parse_outlook_datetime(self, dt_data: _OutlookDateTime) -> datetime:
def _parse_outlook_datetime(self, dt_data: OutlookDateTime) -> datetime:
"""Parse datetime from Microsoft Graph format."""
dt_str = dt_data.get("dateTime")
timezone = dt_data.get("timeZone", "UTC")
@@ -414,7 +362,7 @@ class OutlookCalendarAdapter(CalendarPort):
logger.warning("Failed to parse datetime: %s (tz: %s)", dt_str, timezone)
return datetime.now(UTC)
def _parse_attendees(self, attendees_data: list[_OutlookAttendee]) -> tuple[str, ...]:
def _parse_attendees(self, attendees_data: list[OutlookAttendee]) -> tuple[str, ...]:
"""Parse attendees from Microsoft Graph format."""
emails: list[str] = []
for attendee in attendees_data:
@@ -424,7 +372,7 @@ class OutlookCalendarAdapter(CalendarPort):
return tuple(emails)
def _extract_meeting_url(self, item: _OutlookEvent) -> str | None:
def _extract_meeting_url(self, item: OutlookEvent) -> str | None:
"""Extract online meeting URL from event data."""
if online_url := item.get("onlineMeetingUrl"):
return online_url

Some files were not shown because too many files have changed in this diff Show More