@getrift/rift 0.0.0 → 0.1.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.dev.md +110 -0
- package/README.md +130 -0
- package/dist/src/auth/keychain.d.ts +25 -0
- package/dist/src/auth/keychain.d.ts.map +1 -0
- package/dist/src/auth/keychain.js +113 -0
- package/dist/src/auth/keychain.js.map +1 -0
- package/dist/src/auth/middleware.d.ts +20 -0
- package/dist/src/auth/middleware.d.ts.map +1 -0
- package/dist/src/auth/middleware.js +49 -0
- package/dist/src/auth/middleware.js.map +1 -0
- package/dist/src/auth/rate-limit.d.ts +16 -0
- package/dist/src/auth/rate-limit.d.ts.map +1 -0
- package/dist/src/auth/rate-limit.js +38 -0
- package/dist/src/auth/rate-limit.js.map +1 -0
- package/dist/src/auth/rotation.d.ts +67 -0
- package/dist/src/auth/rotation.d.ts.map +1 -0
- package/dist/src/auth/rotation.js +190 -0
- package/dist/src/auth/rotation.js.map +1 -0
- package/dist/src/backfill/project-context-batch-constructor.d.ts +127 -0
- package/dist/src/backfill/project-context-batch-constructor.d.ts.map +1 -0
- package/dist/src/backfill/project-context-batch-constructor.js +210 -0
- package/dist/src/backfill/project-context-batch-constructor.js.map +1 -0
- package/dist/src/capture/auto-capture.d.ts +162 -0
- package/dist/src/capture/auto-capture.d.ts.map +1 -0
- package/dist/src/capture/auto-capture.js +601 -0
- package/dist/src/capture/auto-capture.js.map +1 -0
- package/dist/src/capture/batch-budget.d.ts +90 -0
- package/dist/src/capture/batch-budget.d.ts.map +1 -0
- package/dist/src/capture/batch-budget.js +148 -0
- package/dist/src/capture/batch-budget.js.map +1 -0
- package/dist/src/capture/codex-cli-triage-provider.d.ts +17 -0
- package/dist/src/capture/codex-cli-triage-provider.d.ts.map +1 -0
- package/dist/src/capture/codex-cli-triage-provider.js +109 -0
- package/dist/src/capture/codex-cli-triage-provider.js.map +1 -0
- package/dist/src/capture/observability.d.ts +42 -0
- package/dist/src/capture/observability.d.ts.map +1 -0
- package/dist/src/capture/observability.js +87 -0
- package/dist/src/capture/observability.js.map +1 -0
- package/dist/src/capture/openai-triage-provider.d.ts +92 -0
- package/dist/src/capture/openai-triage-provider.d.ts.map +1 -0
- package/dist/src/capture/openai-triage-provider.js +267 -0
- package/dist/src/capture/openai-triage-provider.js.map +1 -0
- package/dist/src/capture/review-queue-index.d.ts +51 -0
- package/dist/src/capture/review-queue-index.d.ts.map +1 -0
- package/dist/src/capture/review-queue-index.js +204 -0
- package/dist/src/capture/review-queue-index.js.map +1 -0
- package/dist/src/capture/review-queue.d.ts +43 -0
- package/dist/src/capture/review-queue.d.ts.map +1 -0
- package/dist/src/capture/review-queue.js +116 -0
- package/dist/src/capture/review-queue.js.map +1 -0
- package/dist/src/capture/sources.d.ts +7 -0
- package/dist/src/capture/sources.d.ts.map +1 -0
- package/dist/src/capture/sources.js +3 -0
- package/dist/src/capture/sources.js.map +1 -0
- package/dist/src/capture/triage-lane.d.ts +39 -0
- package/dist/src/capture/triage-lane.d.ts.map +1 -0
- package/dist/src/capture/triage-lane.js +217 -0
- package/dist/src/capture/triage-lane.js.map +1 -0
- package/dist/src/capture/triage-provider.d.ts +75 -0
- package/dist/src/capture/triage-provider.d.ts.map +1 -0
- package/dist/src/capture/triage-provider.js +120 -0
- package/dist/src/capture/triage-provider.js.map +1 -0
- package/dist/src/capture/triage.d.ts +30 -0
- package/dist/src/capture/triage.d.ts.map +1 -0
- package/dist/src/capture/triage.js +48 -0
- package/dist/src/capture/triage.js.map +1 -0
- package/dist/src/cli/commands/backfill.d.ts +3 -0
- package/dist/src/cli/commands/backfill.d.ts.map +1 -0
- package/dist/src/cli/commands/backfill.js +1376 -0
- package/dist/src/cli/commands/backfill.js.map +1 -0
- package/dist/src/cli/commands/bulk-ingest.d.ts +3 -0
- package/dist/src/cli/commands/bulk-ingest.d.ts.map +1 -0
- package/dist/src/cli/commands/bulk-ingest.js +126 -0
- package/dist/src/cli/commands/bulk-ingest.js.map +1 -0
- package/dist/src/cli/commands/capture.d.ts +12 -0
- package/dist/src/cli/commands/capture.d.ts.map +1 -0
- package/dist/src/cli/commands/capture.js +123 -0
- package/dist/src/cli/commands/capture.js.map +1 -0
- package/dist/src/cli/commands/compact.d.ts +3 -0
- package/dist/src/cli/commands/compact.d.ts.map +1 -0
- package/dist/src/cli/commands/compact.js +70 -0
- package/dist/src/cli/commands/compact.js.map +1 -0
- package/dist/src/cli/commands/feedback.d.ts +22 -0
- package/dist/src/cli/commands/feedback.d.ts.map +1 -0
- package/dist/src/cli/commands/feedback.js +125 -0
- package/dist/src/cli/commands/feedback.js.map +1 -0
- package/dist/src/cli/commands/import.d.ts +19 -0
- package/dist/src/cli/commands/import.d.ts.map +1 -0
- package/dist/src/cli/commands/import.js +258 -0
- package/dist/src/cli/commands/import.js.map +1 -0
- package/dist/src/cli/commands/ingest.d.ts +3 -0
- package/dist/src/cli/commands/ingest.d.ts.map +1 -0
- package/dist/src/cli/commands/ingest.js +80 -0
- package/dist/src/cli/commands/ingest.js.map +1 -0
- package/dist/src/cli/commands/mcp-install.d.ts +25 -0
- package/dist/src/cli/commands/mcp-install.d.ts.map +1 -0
- package/dist/src/cli/commands/mcp-install.js +134 -0
- package/dist/src/cli/commands/mcp-install.js.map +1 -0
- package/dist/src/cli/commands/onboard.d.ts +98 -0
- package/dist/src/cli/commands/onboard.d.ts.map +1 -0
- package/dist/src/cli/commands/onboard.js +742 -0
- package/dist/src/cli/commands/onboard.js.map +1 -0
- package/dist/src/cli/commands/rebuild.d.ts +12 -0
- package/dist/src/cli/commands/rebuild.d.ts.map +1 -0
- package/dist/src/cli/commands/rebuild.js +164 -0
- package/dist/src/cli/commands/rebuild.js.map +1 -0
- package/dist/src/cli/commands/reconcile.d.ts +3 -0
- package/dist/src/cli/commands/reconcile.d.ts.map +1 -0
- package/dist/src/cli/commands/reconcile.js +56 -0
- package/dist/src/cli/commands/reconcile.js.map +1 -0
- package/dist/src/cli/commands/reindex.d.ts +3 -0
- package/dist/src/cli/commands/reindex.d.ts.map +1 -0
- package/dist/src/cli/commands/reindex.js +66 -0
- package/dist/src/cli/commands/reindex.js.map +1 -0
- package/dist/src/cli/commands/review.d.ts +13 -0
- package/dist/src/cli/commands/review.d.ts.map +1 -0
- package/dist/src/cli/commands/review.js +383 -0
- package/dist/src/cli/commands/review.js.map +1 -0
- package/dist/src/cli/commands/save.d.ts +3 -0
- package/dist/src/cli/commands/save.d.ts.map +1 -0
- package/dist/src/cli/commands/save.js +111 -0
- package/dist/src/cli/commands/save.js.map +1 -0
- package/dist/src/cli/commands/search.d.ts +35 -0
- package/dist/src/cli/commands/search.d.ts.map +1 -0
- package/dist/src/cli/commands/search.js +88 -0
- package/dist/src/cli/commands/search.js.map +1 -0
- package/dist/src/cli/commands/stats.d.ts +3 -0
- package/dist/src/cli/commands/stats.d.ts.map +1 -0
- package/dist/src/cli/commands/stats.js +42 -0
- package/dist/src/cli/commands/stats.js.map +1 -0
- package/dist/src/cli/commands/status.d.ts +15 -0
- package/dist/src/cli/commands/status.d.ts.map +1 -0
- package/dist/src/cli/commands/status.js +89 -0
- package/dist/src/cli/commands/status.js.map +1 -0
- package/dist/src/cli/commands/token-issue.d.ts +3 -0
- package/dist/src/cli/commands/token-issue.d.ts.map +1 -0
- package/dist/src/cli/commands/token-issue.js +25 -0
- package/dist/src/cli/commands/token-issue.js.map +1 -0
- package/dist/src/cli/commands/triage.d.ts +3 -0
- package/dist/src/cli/commands/triage.d.ts.map +1 -0
- package/dist/src/cli/commands/triage.js +125 -0
- package/dist/src/cli/commands/triage.js.map +1 -0
- package/dist/src/cli/commands/uninstall.d.ts +3 -0
- package/dist/src/cli/commands/uninstall.d.ts.map +1 -0
- package/dist/src/cli/commands/uninstall.js +238 -0
- package/dist/src/cli/commands/uninstall.js.map +1 -0
- package/dist/src/cli/feedback/feedback-config.d.ts +21 -0
- package/dist/src/cli/feedback/feedback-config.d.ts.map +1 -0
- package/dist/src/cli/feedback/feedback-config.js +43 -0
- package/dist/src/cli/feedback/feedback-config.js.map +1 -0
- package/dist/src/cli/feedback/feedback-history.d.ts +4 -0
- package/dist/src/cli/feedback/feedback-history.d.ts.map +1 -0
- package/dist/src/cli/feedback/feedback-history.js +115 -0
- package/dist/src/cli/feedback/feedback-history.js.map +1 -0
- package/dist/src/cli/feedback/feedback-payload.d.ts +53 -0
- package/dist/src/cli/feedback/feedback-payload.d.ts.map +1 -0
- package/dist/src/cli/feedback/feedback-payload.js +10 -0
- package/dist/src/cli/feedback/feedback-payload.js.map +1 -0
- package/dist/src/cli/feedback/feedback-relay.d.ts +15 -0
- package/dist/src/cli/feedback/feedback-relay.d.ts.map +1 -0
- package/dist/src/cli/feedback/feedback-relay.js +47 -0
- package/dist/src/cli/feedback/feedback-relay.js.map +1 -0
- package/dist/src/cli/feedback/feedback-status.d.ts +11 -0
- package/dist/src/cli/feedback/feedback-status.d.ts.map +1 -0
- package/dist/src/cli/feedback/feedback-status.js +122 -0
- package/dist/src/cli/feedback/feedback-status.js.map +1 -0
- package/dist/src/cli/http-client.d.ts +36 -0
- package/dist/src/cli/http-client.d.ts.map +1 -0
- package/dist/src/cli/http-client.js +153 -0
- package/dist/src/cli/http-client.js.map +1 -0
- package/dist/src/cli/index.d.ts +4 -0
- package/dist/src/cli/index.d.ts.map +1 -0
- package/dist/src/cli/index.js +66 -0
- package/dist/src/cli/index.js.map +1 -0
- package/dist/src/cli/job-poller.d.ts +13 -0
- package/dist/src/cli/job-poller.d.ts.map +1 -0
- package/dist/src/cli/job-poller.js +29 -0
- package/dist/src/cli/job-poller.js.map +1 -0
- package/dist/src/cli/mcp-config-writers/codex-toml.d.ts +10 -0
- package/dist/src/cli/mcp-config-writers/codex-toml.d.ts.map +1 -0
- package/dist/src/cli/mcp-config-writers/codex-toml.js +410 -0
- package/dist/src/cli/mcp-config-writers/codex-toml.js.map +1 -0
- package/dist/src/cli/mcp-config-writers/errors.d.ts +17 -0
- package/dist/src/cli/mcp-config-writers/errors.d.ts.map +1 -0
- package/dist/src/cli/mcp-config-writers/errors.js +13 -0
- package/dist/src/cli/mcp-config-writers/errors.js.map +1 -0
- package/dist/src/cli/mcp-config-writers/index.d.ts +18 -0
- package/dist/src/cli/mcp-config-writers/index.d.ts.map +1 -0
- package/dist/src/cli/mcp-config-writers/index.js +49 -0
- package/dist/src/cli/mcp-config-writers/index.js.map +1 -0
- package/dist/src/cli/mcp-config-writers/json-config.d.ts +12 -0
- package/dist/src/cli/mcp-config-writers/json-config.d.ts.map +1 -0
- package/dist/src/cli/mcp-config-writers/json-config.js +177 -0
- package/dist/src/cli/mcp-config-writers/json-config.js.map +1 -0
- package/dist/src/cli/mcp-config-writers/redact.d.ts +28 -0
- package/dist/src/cli/mcp-config-writers/redact.d.ts.map +1 -0
- package/dist/src/cli/mcp-config-writers/redact.js +48 -0
- package/dist/src/cli/mcp-config-writers/redact.js.map +1 -0
- package/dist/src/cli/mcp-config-writers/types.d.ts +32 -0
- package/dist/src/cli/mcp-config-writers/types.d.ts.map +1 -0
- package/dist/src/cli/mcp-config-writers/types.js +5 -0
- package/dist/src/cli/mcp-config-writers/types.js.map +1 -0
- package/dist/src/cli/output.d.ts +8 -0
- package/dist/src/cli/output.d.ts.map +1 -0
- package/dist/src/cli/output.js +34 -0
- package/dist/src/cli/output.js.map +1 -0
- package/dist/src/cli/status/friend-header.d.ts +33 -0
- package/dist/src/cli/status/friend-header.d.ts.map +1 -0
- package/dist/src/cli/status/friend-header.js +108 -0
- package/dist/src/cli/status/friend-header.js.map +1 -0
- package/dist/src/cli/status/local-signals.d.ts +14 -0
- package/dist/src/cli/status/local-signals.d.ts.map +1 -0
- package/dist/src/cli/status/local-signals.js +73 -0
- package/dist/src/cli/status/local-signals.js.map +1 -0
- package/dist/src/cli/token.d.ts +37 -0
- package/dist/src/cli/token.d.ts.map +1 -0
- package/dist/src/cli/token.js +105 -0
- package/dist/src/cli/token.js.map +1 -0
- package/dist/src/cli/uninstall/mcp-uninstall.d.ts +33 -0
- package/dist/src/cli/uninstall/mcp-uninstall.d.ts.map +1 -0
- package/dist/src/cli/uninstall/mcp-uninstall.js +181 -0
- package/dist/src/cli/uninstall/mcp-uninstall.js.map +1 -0
- package/dist/src/config/loader.d.ts +9 -0
- package/dist/src/config/loader.d.ts.map +1 -0
- package/dist/src/config/loader.js +73 -0
- package/dist/src/config/loader.js.map +1 -0
- package/dist/src/config/schema.d.ts +635 -0
- package/dist/src/config/schema.d.ts.map +1 -0
- package/dist/src/config/schema.js +208 -0
- package/dist/src/config/schema.js.map +1 -0
- package/dist/src/ingestion/bulk-ingest.d.ts +11 -0
- package/dist/src/ingestion/bulk-ingest.d.ts.map +1 -0
- package/dist/src/ingestion/bulk-ingest.js +11 -0
- package/dist/src/ingestion/bulk-ingest.js.map +1 -0
- package/dist/src/ingestion/extractor.d.ts +16 -0
- package/dist/src/ingestion/extractor.d.ts.map +1 -0
- package/dist/src/ingestion/extractor.js +85 -0
- package/dist/src/ingestion/extractor.js.map +1 -0
- package/dist/src/ingestion/extractors/docx.d.ts +3 -0
- package/dist/src/ingestion/extractors/docx.d.ts.map +1 -0
- package/dist/src/ingestion/extractors/docx.js +20 -0
- package/dist/src/ingestion/extractors/docx.js.map +1 -0
- package/dist/src/ingestion/extractors/pdf.d.ts +3 -0
- package/dist/src/ingestion/extractors/pdf.d.ts.map +1 -0
- package/dist/src/ingestion/extractors/pdf.js +32 -0
- package/dist/src/ingestion/extractors/pdf.js.map +1 -0
- package/dist/src/ingestion/historical-campaign.d.ts +340 -0
- package/dist/src/ingestion/historical-campaign.d.ts.map +1 -0
- package/dist/src/ingestion/historical-campaign.js +1010 -0
- package/dist/src/ingestion/historical-campaign.js.map +1 -0
- package/dist/src/ingestion/ignored-paths.d.ts +20 -0
- package/dist/src/ingestion/ignored-paths.d.ts.map +1 -0
- package/dist/src/ingestion/ignored-paths.js +45 -0
- package/dist/src/ingestion/ignored-paths.js.map +1 -0
- package/dist/src/ingestion/inbox-watcher.d.ts +12 -0
- package/dist/src/ingestion/inbox-watcher.d.ts.map +1 -0
- package/dist/src/ingestion/inbox-watcher.js +99 -0
- package/dist/src/ingestion/inbox-watcher.js.map +1 -0
- package/dist/src/ingestion/indexer.d.ts +32 -0
- package/dist/src/ingestion/indexer.d.ts.map +1 -0
- package/dist/src/ingestion/indexer.js +68 -0
- package/dist/src/ingestion/indexer.js.map +1 -0
- package/dist/src/ingestion/metadata-extraction.d.ts +53 -0
- package/dist/src/ingestion/metadata-extraction.d.ts.map +1 -0
- package/dist/src/ingestion/metadata-extraction.js +132 -0
- package/dist/src/ingestion/metadata-extraction.js.map +1 -0
- package/dist/src/ingestion/parsers/chatgpt-web.d.ts +29 -0
- package/dist/src/ingestion/parsers/chatgpt-web.d.ts.map +1 -0
- package/dist/src/ingestion/parsers/chatgpt-web.js +100 -0
- package/dist/src/ingestion/parsers/chatgpt-web.js.map +1 -0
- package/dist/src/ingestion/parsers/claude-code-jsonl.d.ts +16 -0
- package/dist/src/ingestion/parsers/claude-code-jsonl.d.ts.map +1 -0
- package/dist/src/ingestion/parsers/claude-code-jsonl.js +123 -0
- package/dist/src/ingestion/parsers/claude-code-jsonl.js.map +1 -0
- package/dist/src/ingestion/parsers/claude-web.d.ts +24 -0
- package/dist/src/ingestion/parsers/claude-web.d.ts.map +1 -0
- package/dist/src/ingestion/parsers/claude-web.js +78 -0
- package/dist/src/ingestion/parsers/claude-web.js.map +1 -0
- package/dist/src/ingestion/parsers/codex-jsonl.d.ts +18 -0
- package/dist/src/ingestion/parsers/codex-jsonl.d.ts.map +1 -0
- package/dist/src/ingestion/parsers/codex-jsonl.js +125 -0
- package/dist/src/ingestion/parsers/codex-jsonl.js.map +1 -0
- package/dist/src/ingestion/parsers/gemini-web.d.ts +16 -0
- package/dist/src/ingestion/parsers/gemini-web.d.ts.map +1 -0
- package/dist/src/ingestion/parsers/gemini-web.js +170 -0
- package/dist/src/ingestion/parsers/gemini-web.js.map +1 -0
- package/dist/src/ingestion/parsers/grok-web.d.ts +40 -0
- package/dist/src/ingestion/parsers/grok-web.d.ts.map +1 -0
- package/dist/src/ingestion/parsers/grok-web.js +67 -0
- package/dist/src/ingestion/parsers/grok-web.js.map +1 -0
- package/dist/src/ingestion/parsers/types.d.ts +34 -0
- package/dist/src/ingestion/parsers/types.d.ts.map +1 -0
- package/dist/src/ingestion/parsers/types.js +26 -0
- package/dist/src/ingestion/parsers/types.js.map +1 -0
- package/dist/src/ingestion/scanner.d.ts +48 -0
- package/dist/src/ingestion/scanner.d.ts.map +1 -0
- package/dist/src/ingestion/scanner.js +131 -0
- package/dist/src/ingestion/scanner.js.map +1 -0
- package/dist/src/ingestion/staging.d.ts +109 -0
- package/dist/src/ingestion/staging.d.ts.map +1 -0
- package/dist/src/ingestion/staging.js +411 -0
- package/dist/src/ingestion/staging.js.map +1 -0
- package/dist/src/ingestion/watcher.d.ts +65 -0
- package/dist/src/ingestion/watcher.d.ts.map +1 -0
- package/dist/src/ingestion/watcher.js +182 -0
- package/dist/src/ingestion/watcher.js.map +1 -0
- package/dist/src/jobs/codex-override-handler.d.ts +3 -0
- package/dist/src/jobs/codex-override-handler.d.ts.map +1 -0
- package/dist/src/jobs/codex-override-handler.js +16 -0
- package/dist/src/jobs/codex-override-handler.js.map +1 -0
- package/dist/src/jobs/handlers/compact.d.ts +30 -0
- package/dist/src/jobs/handlers/compact.d.ts.map +1 -0
- package/dist/src/jobs/handlers/compact.js +329 -0
- package/dist/src/jobs/handlers/compact.js.map +1 -0
- package/dist/src/jobs/handlers/ingest.d.ts +13 -0
- package/dist/src/jobs/handlers/ingest.d.ts.map +1 -0
- package/dist/src/jobs/handlers/ingest.js +255 -0
- package/dist/src/jobs/handlers/ingest.js.map +1 -0
- package/dist/src/jobs/handlers/reconcile.d.ts +29 -0
- package/dist/src/jobs/handlers/reconcile.d.ts.map +1 -0
- package/dist/src/jobs/handlers/reconcile.js +476 -0
- package/dist/src/jobs/handlers/reconcile.js.map +1 -0
- package/dist/src/jobs/handlers/reindex.d.ts +38 -0
- package/dist/src/jobs/handlers/reindex.d.ts.map +1 -0
- package/dist/src/jobs/handlers/reindex.js +52 -0
- package/dist/src/jobs/handlers/reindex.js.map +1 -0
- package/dist/src/jobs/handlers/save.d.ts +10 -0
- package/dist/src/jobs/handlers/save.d.ts.map +1 -0
- package/dist/src/jobs/handlers/save.js +206 -0
- package/dist/src/jobs/handlers/save.js.map +1 -0
- package/dist/src/jobs/handlers/triage.d.ts +47 -0
- package/dist/src/jobs/handlers/triage.d.ts.map +1 -0
- package/dist/src/jobs/handlers/triage.js +95 -0
- package/dist/src/jobs/handlers/triage.js.map +1 -0
- package/dist/src/jobs/queue.d.ts +107 -0
- package/dist/src/jobs/queue.d.ts.map +1 -0
- package/dist/src/jobs/queue.js +319 -0
- package/dist/src/jobs/queue.js.map +1 -0
- package/dist/src/jobs/types.d.ts +39 -0
- package/dist/src/jobs/types.d.ts.map +1 -0
- package/dist/src/jobs/types.js +29 -0
- package/dist/src/jobs/types.js.map +1 -0
- package/dist/src/jobs/worker-entry.d.ts +10 -0
- package/dist/src/jobs/worker-entry.d.ts.map +1 -0
- package/dist/src/jobs/worker-entry.js +210 -0
- package/dist/src/jobs/worker-entry.js.map +1 -0
- package/dist/src/jobs/worker-process.d.ts +50 -0
- package/dist/src/jobs/worker-process.d.ts.map +1 -0
- package/dist/src/jobs/worker-process.js +186 -0
- package/dist/src/jobs/worker-process.js.map +1 -0
- package/dist/src/jobs/worker.d.ts +11 -0
- package/dist/src/jobs/worker.d.ts.map +1 -0
- package/dist/src/jobs/worker.js +14 -0
- package/dist/src/jobs/worker.js.map +1 -0
- package/dist/src/main.d.ts +2 -0
- package/dist/src/main.d.ts.map +1 -0
- package/dist/src/main.js +425 -0
- package/dist/src/main.js.map +1 -0
- package/dist/src/mcp/errors.d.ts +8 -0
- package/dist/src/mcp/errors.d.ts.map +1 -0
- package/dist/src/mcp/errors.js +50 -0
- package/dist/src/mcp/errors.js.map +1 -0
- package/dist/src/mcp/server.d.ts +10 -0
- package/dist/src/mcp/server.d.ts.map +1 -0
- package/dist/src/mcp/server.js +94 -0
- package/dist/src/mcp/server.js.map +1 -0
- package/dist/src/mcp/tools/context-pack.d.ts +35 -0
- package/dist/src/mcp/tools/context-pack.d.ts.map +1 -0
- package/dist/src/mcp/tools/context-pack.js +97 -0
- package/dist/src/mcp/tools/context-pack.js.map +1 -0
- package/dist/src/mcp/tools/conversations-search.d.ts +38 -0
- package/dist/src/mcp/tools/conversations-search.d.ts.map +1 -0
- package/dist/src/mcp/tools/conversations-search.js +73 -0
- package/dist/src/mcp/tools/conversations-search.js.map +1 -0
- package/dist/src/mcp/tools/save.d.ts +32 -0
- package/dist/src/mcp/tools/save.d.ts.map +1 -0
- package/dist/src/mcp/tools/save.js +60 -0
- package/dist/src/mcp/tools/save.js.map +1 -0
- package/dist/src/mcp/tools/search.d.ts +33 -0
- package/dist/src/mcp/tools/search.d.ts.map +1 -0
- package/dist/src/mcp/tools/search.js +58 -0
- package/dist/src/mcp/tools/search.js.map +1 -0
- package/dist/src/mcp/tools/status.d.ts +17 -0
- package/dist/src/mcp/tools/status.d.ts.map +1 -0
- package/dist/src/mcp/tools/status.js +12 -0
- package/dist/src/mcp/tools/status.js.map +1 -0
- package/dist/src/observability/coverage.d.ts +100 -0
- package/dist/src/observability/coverage.d.ts.map +1 -0
- package/dist/src/observability/coverage.js +180 -0
- package/dist/src/observability/coverage.js.map +1 -0
- package/dist/src/observability/rift-context.d.ts +47 -0
- package/dist/src/observability/rift-context.d.ts.map +1 -0
- package/dist/src/observability/rift-context.js +118 -0
- package/dist/src/observability/rift-context.js.map +1 -0
- package/dist/src/observability/staleness.d.ts +43 -0
- package/dist/src/observability/staleness.d.ts.map +1 -0
- package/dist/src/observability/staleness.js +74 -0
- package/dist/src/observability/staleness.js.map +1 -0
- package/dist/src/observability/tool-usage-stats.d.ts +23 -0
- package/dist/src/observability/tool-usage-stats.d.ts.map +1 -0
- package/dist/src/observability/tool-usage-stats.js +83 -0
- package/dist/src/observability/tool-usage-stats.js.map +1 -0
- package/dist/src/observability/tool-usage.d.ts +68 -0
- package/dist/src/observability/tool-usage.d.ts.map +1 -0
- package/dist/src/observability/tool-usage.js +207 -0
- package/dist/src/observability/tool-usage.js.map +1 -0
- package/dist/src/onboarding/daemon-control.d.ts +33 -0
- package/dist/src/onboarding/daemon-control.d.ts.map +1 -0
- package/dist/src/onboarding/daemon-control.js +92 -0
- package/dist/src/onboarding/daemon-control.js.map +1 -0
- package/dist/src/onboarding/env-file.d.ts +18 -0
- package/dist/src/onboarding/env-file.d.ts.map +1 -0
- package/dist/src/onboarding/env-file.js +89 -0
- package/dist/src/onboarding/env-file.js.map +1 -0
- package/dist/src/onboarding/voyage-validate.d.ts +16 -0
- package/dist/src/onboarding/voyage-validate.d.ts.map +1 -0
- package/dist/src/onboarding/voyage-validate.js +85 -0
- package/dist/src/onboarding/voyage-validate.js.map +1 -0
- package/dist/src/providers/anthropic-digest.d.ts +23 -0
- package/dist/src/providers/anthropic-digest.d.ts.map +1 -0
- package/dist/src/providers/anthropic-digest.js +91 -0
- package/dist/src/providers/anthropic-digest.js.map +1 -0
- package/dist/src/providers/codex-cli-digest.d.ts +12 -0
- package/dist/src/providers/codex-cli-digest.d.ts.map +1 -0
- package/dist/src/providers/codex-cli-digest.js +70 -0
- package/dist/src/providers/codex-cli-digest.js.map +1 -0
- package/dist/src/providers/codex-cli-metadata-extraction.d.ts +14 -0
- package/dist/src/providers/codex-cli-metadata-extraction.d.ts.map +1 -0
- package/dist/src/providers/codex-cli-metadata-extraction.js +101 -0
- package/dist/src/providers/codex-cli-metadata-extraction.js.map +1 -0
- package/dist/src/providers/codex-cli-runner.d.ts +14 -0
- package/dist/src/providers/codex-cli-runner.d.ts.map +1 -0
- package/dist/src/providers/codex-cli-runner.js +272 -0
- package/dist/src/providers/codex-cli-runner.js.map +1 -0
- package/dist/src/providers/conversation-generation.d.ts +10 -0
- package/dist/src/providers/conversation-generation.d.ts.map +1 -0
- package/dist/src/providers/conversation-generation.js +54 -0
- package/dist/src/providers/conversation-generation.js.map +1 -0
- package/dist/src/providers/ollama-embed.d.ts +22 -0
- package/dist/src/providers/ollama-embed.d.ts.map +1 -0
- package/dist/src/providers/ollama-embed.js +133 -0
- package/dist/src/providers/ollama-embed.js.map +1 -0
- package/dist/src/providers/ollama.d.ts +42 -0
- package/dist/src/providers/ollama.d.ts.map +1 -0
- package/dist/src/providers/ollama.js +169 -0
- package/dist/src/providers/ollama.js.map +1 -0
- package/dist/src/providers/openai-metadata-extraction.d.ts +73 -0
- package/dist/src/providers/openai-metadata-extraction.d.ts.map +1 -0
- package/dist/src/providers/openai-metadata-extraction.js +161 -0
- package/dist/src/providers/openai-metadata-extraction.js.map +1 -0
- package/dist/src/providers/operator-overrides.d.ts +24 -0
- package/dist/src/providers/operator-overrides.d.ts.map +1 -0
- package/dist/src/providers/operator-overrides.js +84 -0
- package/dist/src/providers/operator-overrides.js.map +1 -0
- package/dist/src/providers/stub.d.ts +17 -0
- package/dist/src/providers/stub.d.ts.map +1 -0
- package/dist/src/providers/stub.js +72 -0
- package/dist/src/providers/stub.js.map +1 -0
- package/dist/src/providers/types.d.ts +82 -0
- package/dist/src/providers/types.d.ts.map +1 -0
- package/dist/src/providers/types.js +52 -0
- package/dist/src/providers/types.js.map +1 -0
- package/dist/src/providers/voyage.d.ts +23 -0
- package/dist/src/providers/voyage.d.ts.map +1 -0
- package/dist/src/providers/voyage.js +135 -0
- package/dist/src/providers/voyage.js.map +1 -0
- package/dist/src/retrieval/compact.d.ts +89 -0
- package/dist/src/retrieval/compact.d.ts.map +1 -0
- package/dist/src/retrieval/compact.js +348 -0
- package/dist/src/retrieval/compact.js.map +1 -0
- package/dist/src/retrieval/context-pack.d.ts +123 -0
- package/dist/src/retrieval/context-pack.d.ts.map +1 -0
- package/dist/src/retrieval/context-pack.js +553 -0
- package/dist/src/retrieval/context-pack.js.map +1 -0
- package/dist/src/retrieval/cwd.d.ts +25 -0
- package/dist/src/retrieval/cwd.d.ts.map +1 -0
- package/dist/src/retrieval/cwd.js +48 -0
- package/dist/src/retrieval/cwd.js.map +1 -0
- package/dist/src/retrieval/degraded.d.ts +20 -0
- package/dist/src/retrieval/degraded.d.ts.map +1 -0
- package/dist/src/retrieval/degraded.js +43 -0
- package/dist/src/retrieval/degraded.js.map +1 -0
- package/dist/src/retrieval/hybrid.d.ts +38 -0
- package/dist/src/retrieval/hybrid.d.ts.map +1 -0
- package/dist/src/retrieval/hybrid.js +82 -0
- package/dist/src/retrieval/hybrid.js.map +1 -0
- package/dist/src/retrieval/lexical.d.ts +28 -0
- package/dist/src/retrieval/lexical.d.ts.map +1 -0
- package/dist/src/retrieval/lexical.js +301 -0
- package/dist/src/retrieval/lexical.js.map +1 -0
- package/dist/src/retrieval/post-filter.d.ts +32 -0
- package/dist/src/retrieval/post-filter.d.ts.map +1 -0
- package/dist/src/retrieval/post-filter.js +57 -0
- package/dist/src/retrieval/post-filter.js.map +1 -0
- package/dist/src/retrieval/reranker.d.ts +72 -0
- package/dist/src/retrieval/reranker.d.ts.map +1 -0
- package/dist/src/retrieval/reranker.js +129 -0
- package/dist/src/retrieval/reranker.js.map +1 -0
- package/dist/src/retrieval/vector.d.ts +47 -0
- package/dist/src/retrieval/vector.d.ts.map +1 -0
- package/dist/src/retrieval/vector.js +112 -0
- package/dist/src/retrieval/vector.js.map +1 -0
- package/dist/src/runtime/legacy-migration.d.ts +27 -0
- package/dist/src/runtime/legacy-migration.d.ts.map +1 -0
- package/dist/src/runtime/legacy-migration.js +140 -0
- package/dist/src/runtime/legacy-migration.js.map +1 -0
- package/dist/src/runtime/legacy-name-guard.d.ts +35 -0
- package/dist/src/runtime/legacy-name-guard.d.ts.map +1 -0
- package/dist/src/runtime/legacy-name-guard.js +58 -0
- package/dist/src/runtime/legacy-name-guard.js.map +1 -0
- package/dist/src/runtime/rift-env.d.ts +14 -0
- package/dist/src/runtime/rift-env.d.ts.map +1 -0
- package/dist/src/runtime/rift-env.js +79 -0
- package/dist/src/runtime/rift-env.js.map +1 -0
- package/dist/src/runtime/watcher-startup.d.ts +2 -0
- package/dist/src/runtime/watcher-startup.d.ts.map +1 -0
- package/dist/src/runtime/watcher-startup.js +4 -0
- package/dist/src/runtime/watcher-startup.js.map +1 -0
- package/dist/src/security/archive.d.ts +23 -0
- package/dist/src/security/archive.d.ts.map +1 -0
- package/dist/src/security/archive.js +163 -0
- package/dist/src/security/archive.js.map +1 -0
- package/dist/src/security/paths.d.ts +21 -0
- package/dist/src/security/paths.d.ts.map +1 -0
- package/dist/src/security/paths.js +67 -0
- package/dist/src/security/paths.js.map +1 -0
- package/dist/src/server/app.d.ts +29 -0
- package/dist/src/server/app.d.ts.map +1 -0
- package/dist/src/server/app.js +226 -0
- package/dist/src/server/app.js.map +1 -0
- package/dist/src/server/build-info.d.ts +8 -0
- package/dist/src/server/build-info.d.ts.map +1 -0
- package/dist/src/server/build-info.js +61 -0
- package/dist/src/server/build-info.js.map +1 -0
- package/dist/src/server/lifecycle.d.ts +30 -0
- package/dist/src/server/lifecycle.d.ts.map +1 -0
- package/dist/src/server/lifecycle.js +59 -0
- package/dist/src/server/lifecycle.js.map +1 -0
- package/dist/src/server/middleware/multipart.d.ts +51 -0
- package/dist/src/server/middleware/multipart.d.ts.map +1 -0
- package/dist/src/server/middleware/multipart.js +86 -0
- package/dist/src/server/middleware/multipart.js.map +1 -0
- package/dist/src/server/routes/compact.d.ts +37 -0
- package/dist/src/server/routes/compact.d.ts.map +1 -0
- package/dist/src/server/routes/compact.js +77 -0
- package/dist/src/server/routes/compact.js.map +1 -0
- package/dist/src/server/routes/context.d.ts +5 -0
- package/dist/src/server/routes/context.d.ts.map +1 -0
- package/dist/src/server/routes/context.js +50 -0
- package/dist/src/server/routes/context.js.map +1 -0
- package/dist/src/server/routes/conversations-search.d.ts +4 -0
- package/dist/src/server/routes/conversations-search.d.ts.map +1 -0
- package/dist/src/server/routes/conversations-search.js +243 -0
- package/dist/src/server/routes/conversations-search.js.map +1 -0
- package/dist/src/server/routes/friend-status.d.ts +72 -0
- package/dist/src/server/routes/friend-status.d.ts.map +1 -0
- package/dist/src/server/routes/friend-status.js +71 -0
- package/dist/src/server/routes/friend-status.js.map +1 -0
- package/dist/src/server/routes/ingest.d.ts +15 -0
- package/dist/src/server/routes/ingest.d.ts.map +1 -0
- package/dist/src/server/routes/ingest.js +139 -0
- package/dist/src/server/routes/ingest.js.map +1 -0
- package/dist/src/server/routes/jobs.d.ts +10 -0
- package/dist/src/server/routes/jobs.d.ts.map +1 -0
- package/dist/src/server/routes/jobs.js +29 -0
- package/dist/src/server/routes/jobs.js.map +1 -0
- package/dist/src/server/routes/mcp-usage.d.ts +13 -0
- package/dist/src/server/routes/mcp-usage.d.ts.map +1 -0
- package/dist/src/server/routes/mcp-usage.js +17 -0
- package/dist/src/server/routes/mcp-usage.js.map +1 -0
- package/dist/src/server/routes/reconcile.d.ts +4 -0
- package/dist/src/server/routes/reconcile.d.ts.map +1 -0
- package/dist/src/server/routes/reconcile.js +43 -0
- package/dist/src/server/routes/reconcile.js.map +1 -0
- package/dist/src/server/routes/reindex.d.ts +4 -0
- package/dist/src/server/routes/reindex.d.ts.map +1 -0
- package/dist/src/server/routes/reindex.js +74 -0
- package/dist/src/server/routes/reindex.js.map +1 -0
- package/dist/src/server/routes/save.d.ts +40 -0
- package/dist/src/server/routes/save.d.ts.map +1 -0
- package/dist/src/server/routes/save.js +112 -0
- package/dist/src/server/routes/save.js.map +1 -0
- package/dist/src/server/routes/search.d.ts +5 -0
- package/dist/src/server/routes/search.d.ts.map +1 -0
- package/dist/src/server/routes/search.js +400 -0
- package/dist/src/server/routes/search.js.map +1 -0
- package/dist/src/server/routes/stats.d.ts +10 -0
- package/dist/src/server/routes/stats.d.ts.map +1 -0
- package/dist/src/server/routes/stats.js +15 -0
- package/dist/src/server/routes/stats.js.map +1 -0
- package/dist/src/server/routes/status.d.ts +20 -0
- package/dist/src/server/routes/status.d.ts.map +1 -0
- package/dist/src/server/routes/status.js +31 -0
- package/dist/src/server/routes/status.js.map +1 -0
- package/dist/src/server/routes/triage.d.ts +4 -0
- package/dist/src/server/routes/triage.d.ts.map +1 -0
- package/dist/src/server/routes/triage.js +94 -0
- package/dist/src/server/routes/triage.js.map +1 -0
- package/dist/src/server/save-quality.d.ts +21 -0
- package/dist/src/server/save-quality.d.ts.map +1 -0
- package/dist/src/server/save-quality.js +51 -0
- package/dist/src/server/save-quality.js.map +1 -0
- package/dist/src/storage/atomic.d.ts +8 -0
- package/dist/src/storage/atomic.d.ts.map +1 -0
- package/dist/src/storage/atomic.js +22 -0
- package/dist/src/storage/atomic.js.map +1 -0
- package/dist/src/storage/db.d.ts +15 -0
- package/dist/src/storage/db.d.ts.map +1 -0
- package/dist/src/storage/db.js +43 -0
- package/dist/src/storage/db.js.map +1 -0
- package/dist/src/storage/integrity.d.ts +11 -0
- package/dist/src/storage/integrity.d.ts.map +1 -0
- package/dist/src/storage/integrity.js +66 -0
- package/dist/src/storage/integrity.js.map +1 -0
- package/dist/src/storage/rebuild.d.ts +37 -0
- package/dist/src/storage/rebuild.d.ts.map +1 -0
- package/dist/src/storage/rebuild.js +353 -0
- package/dist/src/storage/rebuild.js.map +1 -0
- package/dist/src/storage/shadow-swap.d.ts +20 -0
- package/dist/src/storage/shadow-swap.d.ts.map +1 -0
- package/dist/src/storage/shadow-swap.js +163 -0
- package/dist/src/storage/shadow-swap.js.map +1 -0
- package/dist/src/storage/tables.d.ts +77 -0
- package/dist/src/storage/tables.d.ts.map +1 -0
- package/dist/src/storage/tables.js +196 -0
- package/dist/src/storage/tables.js.map +1 -0
- package/package.json +45 -14
- package/index.js +0 -3
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Save job handler — Slice 8.
|
|
3
|
+
*
|
|
4
|
+
* Processes a POST /save payload:
|
|
5
|
+
* 1. Write raw payload to data/raw/conversations/{source}/{timestamp}_{id}.json
|
|
6
|
+
* 2. Generate embedding via EmbeddingProvider
|
|
7
|
+
* 3. Insert row into conversations_hot
|
|
8
|
+
*
|
|
9
|
+
* On failure (after raw write): quarantine to data/quarantine/{source}_{timestamp}_{hash}.json
|
|
10
|
+
* Raw file is written BEFORE table insert (crash safety).
|
|
11
|
+
*
|
|
12
|
+
* Replay safety:
|
|
13
|
+
* - Row ID is the root of the retry chain (walks `retry_of` to the
|
|
14
|
+
* first ancestor), so multi-hop retries all converge on one ID.
|
|
15
|
+
* - Before inserting, checks if the row already exists. If it does
|
|
16
|
+
* (prior run succeeded), the handler returns early — no mutation.
|
|
17
|
+
* - Raw file is written once per stable ID; replays detect the existing
|
|
18
|
+
* file, skip the write, and use the raw file's payload as the
|
|
19
|
+
* authoritative content. This prevents drift between the canonical
|
|
20
|
+
* raw artifact and the indexed row.
|
|
21
|
+
*/
|
|
22
|
+
import crypto from "node:crypto";
|
|
23
|
+
import fs from "node:fs";
|
|
24
|
+
import path from "node:path";
|
|
25
|
+
import { getTable } from "../../storage/tables.js";
|
|
26
|
+
import { atomicWrite } from "../../storage/atomic.js";
|
|
27
|
+
/**
|
|
28
|
+
* Walk the `retry_of` chain to the root job.
|
|
29
|
+
*
|
|
30
|
+
* Queue retries point to the immediate failed parent, not the
|
|
31
|
+
* original. A -> B (retry_of=A) -> C (retry_of=B). This function
|
|
32
|
+
* returns A in all three cases, so all retries share one stable ID
|
|
33
|
+
* and one canonical payload.
|
|
34
|
+
*/
|
|
35
|
+
function resolveChainRoot(job, queue) {
|
|
36
|
+
let current = job;
|
|
37
|
+
let depth = 0;
|
|
38
|
+
while (current.retry_of && depth < 50) {
|
|
39
|
+
const parent = queue.get(current.retry_of);
|
|
40
|
+
if (!parent)
|
|
41
|
+
break; // Parent not in queue (e.g. pruned) — stop here.
|
|
42
|
+
current = parent;
|
|
43
|
+
depth++;
|
|
44
|
+
}
|
|
45
|
+
return current;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Find the raw file for `rowId` under `rawDir`, if it exists.
|
|
49
|
+
* Files are named `{timestamp}_{rowId}.json`, so we match the suffix.
|
|
50
|
+
* Returns the full path, or undefined if not found.
|
|
51
|
+
*/
|
|
52
|
+
function findRawFile(rawDir, rowId) {
|
|
53
|
+
if (!fs.existsSync(rawDir))
|
|
54
|
+
return undefined;
|
|
55
|
+
const suffix = `_${rowId}.json`;
|
|
56
|
+
const match = fs.readdirSync(rawDir).find((f) => f.endsWith(suffix));
|
|
57
|
+
return match ? path.join(rawDir, match) : undefined;
|
|
58
|
+
}
|
|
59
|
+
export function createSaveHandler(deps) {
|
|
60
|
+
return async (job) => {
|
|
61
|
+
const jobPayload = job.payload;
|
|
62
|
+
if (!jobPayload || !jobPayload.source || !jobPayload.summary) {
|
|
63
|
+
throw new Error("Invalid save job payload: missing source or summary");
|
|
64
|
+
}
|
|
65
|
+
// Resolve the chain root to get a stable ID and the original
|
|
66
|
+
// payload's source — the raw directory is always keyed to the
|
|
67
|
+
// first job's source, not the retry's.
|
|
68
|
+
const rootJob = resolveChainRoot(job, deps.queue);
|
|
69
|
+
const rootPayload = rootJob.payload ?? jobPayload;
|
|
70
|
+
const rowId = rootJob.id;
|
|
71
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
72
|
+
// --- 1. Write raw payload to disk (before table insert) ---
|
|
73
|
+
// Always use the root payload's source for the directory path so
|
|
74
|
+
// retries with a changed source still find the canonical artifact.
|
|
75
|
+
const rawDir = path.join(deps.dataDir, "raw", "conversations", rootPayload.source);
|
|
76
|
+
let payload;
|
|
77
|
+
const existingRawPath = findRawFile(rawDir, rowId);
|
|
78
|
+
// Track the path if we write a NEW raw file (not a replay).
|
|
79
|
+
// Used in the catch block to clean up on failed replacement saves.
|
|
80
|
+
let newRawPath;
|
|
81
|
+
if (existingRawPath) {
|
|
82
|
+
// Replay: read the canonical raw file so the indexed row always
|
|
83
|
+
// agrees with the raw artifact, even if the retry carried a
|
|
84
|
+
// different payload (including a different source).
|
|
85
|
+
payload = JSON.parse(fs.readFileSync(existingRawPath, "utf-8"));
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
// First run: persist the raw artifact using the original payload.
|
|
89
|
+
payload = rootPayload;
|
|
90
|
+
const rawFileName = `${timestamp}_${rowId}.json`;
|
|
91
|
+
newRawPath = path.join(rawDir, rawFileName);
|
|
92
|
+
await atomicWrite(newRawPath, JSON.stringify(payload, null, 2));
|
|
93
|
+
}
|
|
94
|
+
// --- 2. Generate embedding + 3. Insert into conversations_hot ---
|
|
95
|
+
// Both steps are wrapped so ANY failure after raw write is quarantined.
|
|
96
|
+
try {
|
|
97
|
+
const table = getTable("conversations_hot");
|
|
98
|
+
// Replay guard: if the row already exists from a prior successful
|
|
99
|
+
// run, return early. No delete, so no risk of data loss.
|
|
100
|
+
const existing = await table
|
|
101
|
+
.query()
|
|
102
|
+
.where(`id = '${rowId}'`)
|
|
103
|
+
.toArray();
|
|
104
|
+
if (existing.length > 0) {
|
|
105
|
+
return; // Already indexed — nothing to do.
|
|
106
|
+
}
|
|
107
|
+
// Generate embedding FIRST — before any deletions so the old row
|
|
108
|
+
// is preserved if embedding fails (data-safety invariant).
|
|
109
|
+
const textForEmbedding = payload.content ?? payload.summary;
|
|
110
|
+
const embedding = await deps.embeddingProvider.embed(textForEmbedding);
|
|
111
|
+
const row = {
|
|
112
|
+
id: rowId,
|
|
113
|
+
content: payload.content ?? payload.summary,
|
|
114
|
+
summary: payload.summary,
|
|
115
|
+
embedding,
|
|
116
|
+
source: payload.source,
|
|
117
|
+
domain: payload.domain ?? "tech",
|
|
118
|
+
intent: "build", // Default — no LLM extraction in this slice
|
|
119
|
+
quality: "medium", // Default — no LLM extraction in this slice
|
|
120
|
+
topics: JSON.stringify(payload.topics ?? []),
|
|
121
|
+
decisions: JSON.stringify(payload.decisions ?? []),
|
|
122
|
+
key_outputs: JSON.stringify(payload.key_outputs ?? []),
|
|
123
|
+
indexed_at: new Date().toISOString(),
|
|
124
|
+
idempotency_key: payload.idempotency_key ?? "",
|
|
125
|
+
};
|
|
126
|
+
// Insert the new row FIRST. Old-version cleanup happens after the
|
|
127
|
+
// insert succeeds, so a failed insert never destroys the old version.
|
|
128
|
+
await table.add([row]);
|
|
129
|
+
// Clean up old version — best-effort AFTER new row is safely stored.
|
|
130
|
+
// Failure here means a temporary duplicate (old + new coexist),
|
|
131
|
+
// which is recoverable; the alternative (deleting old before insert
|
|
132
|
+
// succeeds) risks losing both versions on insert failure.
|
|
133
|
+
if (payload.replace_idempotency_key) {
|
|
134
|
+
try {
|
|
135
|
+
const coldTable = getTable("conversations_cold");
|
|
136
|
+
const hotOldRows = await table
|
|
137
|
+
.query()
|
|
138
|
+
.where(`idempotency_key = '${payload.replace_idempotency_key}'`)
|
|
139
|
+
.toArray();
|
|
140
|
+
const coldOldRows = await coldTable
|
|
141
|
+
.query()
|
|
142
|
+
.where(`idempotency_key = '${payload.replace_idempotency_key}'`)
|
|
143
|
+
.toArray();
|
|
144
|
+
const oldRow = hotOldRows[0] ?? coldOldRows[0];
|
|
145
|
+
if (oldRow) {
|
|
146
|
+
const oldRawDir = path.join(deps.dataDir, "raw", "conversations", oldRow.source);
|
|
147
|
+
const oldRawPath = findRawFile(oldRawDir, oldRow.id);
|
|
148
|
+
if (oldRawPath) {
|
|
149
|
+
try {
|
|
150
|
+
fs.unlinkSync(oldRawPath);
|
|
151
|
+
}
|
|
152
|
+
catch { /* best-effort */ }
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
if (hotOldRows.length > 0) {
|
|
156
|
+
await table.delete(`idempotency_key = '${payload.replace_idempotency_key}'`);
|
|
157
|
+
}
|
|
158
|
+
if (coldOldRows.length > 0) {
|
|
159
|
+
await coldTable.delete(`idempotency_key = '${payload.replace_idempotency_key}'`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
catch (cleanupErr) {
|
|
163
|
+
// Log but don't throw — new version is safely saved.
|
|
164
|
+
// Temporary duplicate is not data loss; reconcile-level
|
|
165
|
+
// dedup can address it if needed.
|
|
166
|
+
process.stderr.write(`save: warning: failed to clean up replaced version (key=${payload.replace_idempotency_key}): ${cleanupErr instanceof Error ? cleanupErr.message : String(cleanupErr)}\n`);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
catch (err) {
|
|
171
|
+
// If this was a replacement save and we wrote a new raw file,
|
|
172
|
+
// clean it up so reconcile/rebuild won't resurrect the failed
|
|
173
|
+
// version alongside the still-valid old version. For non-
|
|
174
|
+
// replacement first-time saves the raw file is the intended
|
|
175
|
+
// safety net — reconcile recovers from it.
|
|
176
|
+
if (newRawPath && payload.replace_idempotency_key) {
|
|
177
|
+
try {
|
|
178
|
+
fs.unlinkSync(newRawPath);
|
|
179
|
+
}
|
|
180
|
+
catch { /* best-effort */ }
|
|
181
|
+
}
|
|
182
|
+
await quarantine(deps.dataDir, payload, err);
|
|
183
|
+
throw err; // Re-throw so the job is marked failed
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Write a quarantine file for a failed save.
|
|
189
|
+
* Path: data/quarantine/{source}_{timestamp}_{hash}.json
|
|
190
|
+
*/
|
|
191
|
+
async function quarantine(dataDir, payload, error) {
|
|
192
|
+
const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
193
|
+
const hash = crypto
|
|
194
|
+
.createHash("sha256")
|
|
195
|
+
.update(JSON.stringify(payload))
|
|
196
|
+
.digest("hex")
|
|
197
|
+
.slice(0, 12);
|
|
198
|
+
const quarantinePath = path.join(dataDir, "quarantine", `${payload.source}_${timestamp}_${hash}.json`);
|
|
199
|
+
const quarantineData = {
|
|
200
|
+
payload,
|
|
201
|
+
error: error instanceof Error ? error.message : String(error),
|
|
202
|
+
quarantined_at: new Date().toISOString(),
|
|
203
|
+
};
|
|
204
|
+
await atomicWrite(quarantinePath, JSON.stringify(quarantineData, null, 2));
|
|
205
|
+
}
|
|
206
|
+
//# sourceMappingURL=save.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"save.js","sourceRoot":"","sources":["../../../../src/jobs/handlers/save.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { JobHandler } from "../types.js";
|
|
2
|
+
import { type TriageResult } from "../../capture/triage-provider.js";
|
|
3
|
+
import type { OpenAIConfig } from "../../config/schema.js";
|
|
4
|
+
import { type HistoricalTriageMeteringMode, type OperatorOverrideProvider } from "../../providers/operator-overrides.js";
|
|
5
|
+
import type { CostReportingTriageProvider } from "../../capture/batch-budget.js";
|
|
6
|
+
export interface TriageJobItem {
|
|
7
|
+
id: string;
|
|
8
|
+
content: string;
|
|
9
|
+
source?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface TriageJobPayload {
|
|
12
|
+
items: TriageJobItem[];
|
|
13
|
+
/**
|
|
14
|
+
* Retained for route/backfill compatibility. Codex CLI is currently the
|
|
15
|
+
* only live triage provider, so provider_override is accepted but does not
|
|
16
|
+
* change provider selection.
|
|
17
|
+
*/
|
|
18
|
+
provider_override?: OperatorOverrideProvider;
|
|
19
|
+
}
|
|
20
|
+
export interface TriageJobItemResult {
|
|
21
|
+
id: string;
|
|
22
|
+
triage?: TriageResult;
|
|
23
|
+
error?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface TriageJobOutput {
|
|
26
|
+
job_id: string;
|
|
27
|
+
completed_at: string;
|
|
28
|
+
total: number;
|
|
29
|
+
succeeded: number;
|
|
30
|
+
failed: number;
|
|
31
|
+
cost_cap_exceeded: boolean;
|
|
32
|
+
metering_mode: HistoricalTriageMeteringMode;
|
|
33
|
+
spend_note?: string;
|
|
34
|
+
spent_usd: number;
|
|
35
|
+
cost_cap_usd: number;
|
|
36
|
+
items: TriageJobItemResult[];
|
|
37
|
+
}
|
|
38
|
+
export interface TriageHandlerDeps {
|
|
39
|
+
dataDir: string;
|
|
40
|
+
openai: OpenAIConfig;
|
|
41
|
+
/** Override the API-key resolver (tests). Defaults to macOS Keychain. */
|
|
42
|
+
apiKey?: () => Promise<string>;
|
|
43
|
+
/** Override the provider factory (tests). */
|
|
44
|
+
providerFactory?: (deps: TriageHandlerDeps, payload: TriageJobPayload) => CostReportingTriageProvider;
|
|
45
|
+
}
|
|
46
|
+
export declare function createTriageHandler(deps: TriageHandlerDeps): JobHandler;
|
|
47
|
+
//# sourceMappingURL=triage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"triage.d.ts","sourceRoot":"","sources":["../../../../src/jobs/handlers/triage.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAO,UAAU,EAAE,MAAM,aAAa,CAAC;AAOnD,OAAO,EAEL,KAAK,YAAY,EAClB,MAAM,kCAAkC,CAAC;AAE1C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAGL,KAAK,4BAA4B,EACjC,KAAK,wBAAwB,EAC9B,MAAM,uCAAuC,CAAC;AAC/C,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAEjF,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,wBAAwB,CAAC;CAC9C;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,EAAE,OAAO,CAAC;IAC3B,aAAa,EAAE,4BAA4B,CAAC;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,mBAAmB,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,YAAY,CAAC;IACrB,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/B,6CAA6C;IAC7C,eAAe,CAAC,EAAE,CAChB,IAAI,EAAE,iBAAiB,EACvB,OAAO,EAAE,gBAAgB,KACtB,2BAA2B,CAAC;CAClC;AAYD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,iBAAiB,GAAG,UAAU,CAkFvE"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Triage job handler — Slice 5.
|
|
3
|
+
*
|
|
4
|
+
* Triage is a first-class job type so batches can be queued, retried,
|
|
5
|
+
* and observed independently of ingest. The handler runs every item in
|
|
6
|
+
* the payload through a single guarded TriageProvider so a per-batch
|
|
7
|
+
* cost cap and parallelism limit are enforced at the job boundary.
|
|
8
|
+
*
|
|
9
|
+
* Output: a JSON file at `data/triage-results/{jobId}.json` containing
|
|
10
|
+
* one entry per input item with the triage decision + provenance
|
|
11
|
+
* (decision, confidence, rationale, model, provider, version). Callers
|
|
12
|
+
* (e.g. follow-up routing) read this file. We deliberately don't fan
|
|
13
|
+
* out save/review-queue side effects from inside this handler — Slice 5
|
|
14
|
+
* is about the runtime, not a redesign of the routing pipeline.
|
|
15
|
+
*
|
|
16
|
+
* BatchCostExceededError aborts the job: the failure is surfaced via
|
|
17
|
+
* the job's error field, which is operator-visible.
|
|
18
|
+
*/
|
|
19
|
+
import path from "node:path";
|
|
20
|
+
import { atomicWrite } from "../../storage/atomic.js";
|
|
21
|
+
import { BatchBudget, Semaphore, withBatchGuards, } from "../../capture/batch-budget.js";
|
|
22
|
+
import { BatchCostExceededError, } from "../../capture/triage-provider.js";
|
|
23
|
+
import { CodexCliTriageProvider } from "../../capture/codex-cli-triage-provider.js";
|
|
24
|
+
import { resolveOperatorOverrideProvider, triageMeteringModeForProvider, } from "../../providers/operator-overrides.js";
|
|
25
|
+
function newDefaultProvider(_deps, _payload) {
|
|
26
|
+
// OpenAI remains available only via explicit test/providerFactory injection;
|
|
27
|
+
// the production default is intentionally Codex CLI so live capture uses the
|
|
28
|
+
// operator's existing CLI auth instead of a separate Keychain secret.
|
|
29
|
+
return new CodexCliTriageProvider();
|
|
30
|
+
}
|
|
31
|
+
export function createTriageHandler(deps) {
|
|
32
|
+
return async (job) => {
|
|
33
|
+
const payload = (job.payload ?? {});
|
|
34
|
+
const items = Array.isArray(payload.items) ? payload.items : [];
|
|
35
|
+
const providerOverride = resolveOperatorOverrideProvider(payload.provider_override);
|
|
36
|
+
if (items.length === 0) {
|
|
37
|
+
throw new Error("Triage job payload missing items");
|
|
38
|
+
}
|
|
39
|
+
const effectivePayload = {
|
|
40
|
+
items,
|
|
41
|
+
...(providerOverride ? { provider_override: providerOverride } : {}),
|
|
42
|
+
};
|
|
43
|
+
const provider = (deps.providerFactory ?? newDefaultProvider)(deps, effectivePayload);
|
|
44
|
+
const meteringMode = triageMeteringModeForProvider(providerOverride ?? (deps.providerFactory ? undefined : "codex-cli"));
|
|
45
|
+
const budget = new BatchBudget(deps.openai.max_cost_per_batch_usd);
|
|
46
|
+
const semaphore = new Semaphore(deps.openai.max_parallel_requests);
|
|
47
|
+
const guarded = withBatchGuards(provider, budget, semaphore);
|
|
48
|
+
const results = [];
|
|
49
|
+
let costCapExceeded = false;
|
|
50
|
+
// Run all items in parallel — the semaphore enforces the in-flight cap.
|
|
51
|
+
await Promise.all(items.map(async (item) => {
|
|
52
|
+
try {
|
|
53
|
+
const triage = await guarded.triage({
|
|
54
|
+
content: item.content,
|
|
55
|
+
...(item.source ? { source: item.source } : {}),
|
|
56
|
+
});
|
|
57
|
+
results.push({ id: item.id, triage });
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
if (err instanceof BatchCostExceededError) {
|
|
61
|
+
costCapExceeded = true;
|
|
62
|
+
}
|
|
63
|
+
results.push({
|
|
64
|
+
id: item.id,
|
|
65
|
+
error: err instanceof Error ? err.message : String(err),
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
}));
|
|
69
|
+
const output = {
|
|
70
|
+
job_id: job.id,
|
|
71
|
+
completed_at: new Date().toISOString(),
|
|
72
|
+
total: items.length,
|
|
73
|
+
succeeded: results.filter((r) => r.triage !== undefined).length,
|
|
74
|
+
failed: results.filter((r) => r.error !== undefined).length,
|
|
75
|
+
cost_cap_exceeded: costCapExceeded,
|
|
76
|
+
metering_mode: meteringMode,
|
|
77
|
+
...(meteringMode === "unmetered_codex_cli"
|
|
78
|
+
? {
|
|
79
|
+
spend_note: "Codex CLI historical backfill override is unmetered by OpenAI USD.",
|
|
80
|
+
}
|
|
81
|
+
: {}),
|
|
82
|
+
spent_usd: meteringMode === "openai_usd" ? budget.spent : 0,
|
|
83
|
+
cost_cap_usd: meteringMode === "openai_usd" ? budget.capUsd : 0,
|
|
84
|
+
items: results,
|
|
85
|
+
};
|
|
86
|
+
const outPath = path.join(deps.dataDir, "triage-results", `${job.id}.json`);
|
|
87
|
+
await atomicWrite(outPath, JSON.stringify(output, null, 2));
|
|
88
|
+
if (costCapExceeded) {
|
|
89
|
+
throw new BatchCostExceededError(`Triage job ${job.id} aborted: batch cost cap of $${budget.capUsd.toFixed(2)} exceeded ` +
|
|
90
|
+
`(spent $${budget.spent.toFixed(4)}, ${output.succeeded}/${output.total} completed before cap). ` +
|
|
91
|
+
`Partial results written to ${outPath}.`, budget.spent, budget.capUsd);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=triage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"triage.js","sourceRoot":"","sources":["../../../../src/jobs/handlers/triage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import type { Job, JobType, CreateJobResult, JobHandler } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* In-process job queue with:
|
|
4
|
+
* - Persistence to `queue.json` (atomic write: temp + rename)
|
|
5
|
+
* - State machine: queued -> running -> completed | failed, plus cancelled, interrupted
|
|
6
|
+
* - Idempotency checked before mutual exclusion (PRD 4.1)
|
|
7
|
+
* - Mutual exclusion for {compact, reindex, reconcile}
|
|
8
|
+
* - Crash recovery: running -> interrupted -> re-queued on startup
|
|
9
|
+
*/
|
|
10
|
+
export declare class JobQueue {
|
|
11
|
+
private queuePath;
|
|
12
|
+
private jobs;
|
|
13
|
+
private handlers;
|
|
14
|
+
private processing;
|
|
15
|
+
private held;
|
|
16
|
+
constructor(queuePath: string);
|
|
17
|
+
/**
|
|
18
|
+
* Hold processing — registerHandler and create won't auto-start queued
|
|
19
|
+
* work until releaseHold() is called. Used at startup to prevent
|
|
20
|
+
* recovered jobs from executing before the integrity check completes.
|
|
21
|
+
*/
|
|
22
|
+
hold(): void;
|
|
23
|
+
/** Release hold and kick processing for any waiting jobs. */
|
|
24
|
+
releaseHold(): void;
|
|
25
|
+
/** Register a handler for a job type. Kicks processing for any queued work. */
|
|
26
|
+
registerHandler(type: JobType, handler: JobHandler): void;
|
|
27
|
+
/** Check if a handler is registered for a job type. */
|
|
28
|
+
hasHandler(type: JobType): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Load persisted queue from disk. Mark any `running` jobs as
|
|
31
|
+
* `interrupted` and re-queue them — timers/progress don't survive restart.
|
|
32
|
+
*
|
|
33
|
+
* Only jobs that were `running` at crash time get re-queued. Jobs that
|
|
34
|
+
* were already `interrupted` (from a previous recovery) are left as-is
|
|
35
|
+
* so repeated loads don't multiply work.
|
|
36
|
+
*/
|
|
37
|
+
load(): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Create a job. Returns `{ job, duplicate }`.
|
|
40
|
+
*
|
|
41
|
+
* Idempotency is checked first (PRD 4.1):
|
|
42
|
+
* - If a job with the same `idempotency_key` exists in
|
|
43
|
+
* `queued | running | completed` -> return it with `duplicate: true`.
|
|
44
|
+
* - If it exists in `failed` -> create a new retry job with `retry_of`.
|
|
45
|
+
*
|
|
46
|
+
* Mutual exclusion is checked second:
|
|
47
|
+
* - If the job type is in the exclusive set and another exclusive job
|
|
48
|
+
* is `queued | running`, return null (caller should 409).
|
|
49
|
+
*/
|
|
50
|
+
create(type: JobType, opts?: {
|
|
51
|
+
idempotency_key?: string;
|
|
52
|
+
payload?: unknown;
|
|
53
|
+
}): Promise<CreateJobResult | {
|
|
54
|
+
conflict: true;
|
|
55
|
+
}>;
|
|
56
|
+
/** Get a job by ID, or undefined. */
|
|
57
|
+
get(id: string): Job | undefined;
|
|
58
|
+
/**
|
|
59
|
+
* Check whether an idempotency key matches an existing active job.
|
|
60
|
+
* Returns the job if found in queued/running/completed state, undefined otherwise.
|
|
61
|
+
* Does NOT create or mutate anything — safe for pre-flight checks.
|
|
62
|
+
*/
|
|
63
|
+
findDuplicate(idempotencyKey: string): Job | undefined;
|
|
64
|
+
/**
|
|
65
|
+
* Cancel a job.
|
|
66
|
+
* - `queued` or `interrupted` -> `cancelled`, returns the job.
|
|
67
|
+
* - `running` -> returns `{ conflict: true }`.
|
|
68
|
+
* - Others -> returns undefined (not found or not cancellable).
|
|
69
|
+
*/
|
|
70
|
+
cancel(id: string): Promise<Job | {
|
|
71
|
+
conflict: true;
|
|
72
|
+
} | undefined>;
|
|
73
|
+
/** Atomic write: temp file + rename. */
|
|
74
|
+
private persist;
|
|
75
|
+
/**
|
|
76
|
+
* Find the active job for a given idempotency key.
|
|
77
|
+
* Skip superseded jobs (those with `retried_by` set) so we always
|
|
78
|
+
* find the leaf of the retry chain, not the old parent.
|
|
79
|
+
*/
|
|
80
|
+
private findByIdempotencyKey;
|
|
81
|
+
/**
|
|
82
|
+
* Create a job that bypasses the mutual exclusion check and is
|
|
83
|
+
* inserted at the front of the queue (runs before other queued work).
|
|
84
|
+
*
|
|
85
|
+
* Used exclusively for startup corruption repair: the mandatory
|
|
86
|
+
* rebuild must run before any other queued work touches storage,
|
|
87
|
+
* regardless of what else is in the queue. Other exclusive jobs
|
|
88
|
+
* naturally wait (one-at-a-time processing) and run after the
|
|
89
|
+
* rebuild against healthy storage.
|
|
90
|
+
*/
|
|
91
|
+
createUrgent(type: JobType, opts?: {
|
|
92
|
+
payload?: unknown;
|
|
93
|
+
}): Promise<CreateJobResult>;
|
|
94
|
+
/** Whether any exclusive job is queued or running. */
|
|
95
|
+
hasActiveExclusiveJob(): boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Return the exclusive job that is currently running, or null.
|
|
98
|
+
* Only returns jobs with status "running" — queued exclusive jobs
|
|
99
|
+
* have not entered their coordinated maintenance phase.
|
|
100
|
+
*/
|
|
101
|
+
getRunningExclusiveJob(): Job | null;
|
|
102
|
+
private createRetryJob;
|
|
103
|
+
/** Process the next queued job if no job is currently running. */
|
|
104
|
+
private processNext;
|
|
105
|
+
private findNextQueued;
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=queue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../../src/jobs/queue.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,GAAG,EAAE,OAAO,EAAa,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAGvF;;;;;;;GAOG;AACH,qBAAa,QAAQ;IAMP,OAAO,CAAC,SAAS;IAL7B,OAAO,CAAC,IAAI,CAA0B;IACtC,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,IAAI,CAAS;gBAED,SAAS,EAAE,MAAM;IAErC;;;;OAIG;IACH,IAAI,IAAI,IAAI;IAIZ,6DAA6D;IAC7D,WAAW,IAAI,IAAI;IAKnB,+EAA+E;IAC/E,eAAe,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,GAAG,IAAI;IAKzD,uDAAuD;IACvD,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO;IAIlC;;;;;;;OAOG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA8C3B;;;;;;;;;;;OAWG;IACG,MAAM,CACV,IAAI,EAAE,OAAO,EACb,IAAI,CAAC,EAAE;QAAE,eAAe,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GACrD,OAAO,CAAC,eAAe,GAAG;QAAE,QAAQ,EAAE,IAAI,CAAA;KAAE,CAAC;IA0ChD,qCAAqC;IACrC,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS;IAIhC;;;;OAIG;IACH,aAAa,CAAC,cAAc,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS;IAatD;;;;;OAKG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,GAAG;QAAE,QAAQ,EAAE,IAAI,CAAA;KAAE,GAAG,SAAS,CAAC;IAkBvE,wCAAwC;YAC1B,OAAO;IAOrB;;;;OAIG;IACH,OAAO,CAAC,oBAAoB;IAO5B;;;;;;;;;OASG;IACG,YAAY,CAChB,IAAI,EAAE,OAAO,EACb,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GAC3B,OAAO,CAAC,eAAe,CAAC;IAwB3B,sDAAsD;IACtD,qBAAqB,IAAI,OAAO;IAYhC;;;;OAIG;IACH,sBAAsB,IAAI,GAAG,GAAG,IAAI;YAStB,cAAc;IA6B5B,kEAAkE;IAClE,OAAO,CAAC,WAAW;IAgCnB,OAAO,CAAC,cAAc;CAMvB"}
|