@aligndottech/cli 0.48.0 → 0.50.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.md +10 -8
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +35 -26
- package/dist/cli.js.map +1 -1
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +7 -2
- package/dist/commands/agents.js.map +1 -1
- package/dist/commands/ai.d.ts +11 -0
- package/dist/commands/ai.d.ts.map +1 -0
- package/dist/commands/ai.js +121 -0
- package/dist/commands/ai.js.map +1 -0
- package/dist/commands/check.d.ts.map +1 -1
- package/dist/commands/check.js +18 -2
- package/dist/commands/check.js.map +1 -1
- package/dist/commands/connect.d.ts +5 -0
- package/dist/commands/connect.d.ts.map +1 -1
- package/dist/commands/connect.js +24 -0
- package/dist/commands/connect.js.map +1 -1
- package/dist/commands/default-action.js +2 -2
- package/dist/commands/default-action.js.map +1 -1
- package/dist/commands/import/confluence.d.ts.map +1 -1
- package/dist/commands/import/confluence.js +24 -5
- package/dist/commands/import/confluence.js.map +1 -1
- package/dist/commands/import/docs.js +2 -2
- package/dist/commands/import/git.d.ts.map +1 -1
- package/dist/commands/import/git.js +15 -5
- package/dist/commands/import/git.js.map +1 -1
- package/dist/commands/import/github.d.ts.map +1 -1
- package/dist/commands/import/github.js +34 -7
- package/dist/commands/import/github.js.map +1 -1
- package/dist/commands/import/gitlab.d.ts.map +1 -1
- package/dist/commands/import/gitlab.js +10 -5
- package/dist/commands/import/gitlab.js.map +1 -1
- package/dist/commands/import/jira.d.ts.map +1 -1
- package/dist/commands/import/jira.js +10 -5
- package/dist/commands/import/jira.js.map +1 -1
- package/dist/commands/import/linear.d.ts.map +1 -1
- package/dist/commands/import/linear.js +10 -5
- package/dist/commands/import/linear.js.map +1 -1
- package/dist/commands/import/notion.d.ts.map +1 -1
- package/dist/commands/import/notion.js +10 -5
- package/dist/commands/import/notion.js.map +1 -1
- package/dist/commands/import/sessions.js +2 -2
- package/dist/commands/import/slack.d.ts.map +1 -1
- package/dist/commands/import/slack.js +12 -7
- package/dist/commands/import/slack.js.map +1 -1
- package/dist/commands/import/teams.d.ts.map +1 -1
- package/dist/commands/import/teams.js +10 -5
- package/dist/commands/import/teams.js.map +1 -1
- package/dist/commands/import/zoom.d.ts.map +1 -1
- package/dist/commands/import/zoom.js +10 -5
- package/dist/commands/import/zoom.js.map +1 -1
- package/dist/commands/import.d.ts.map +1 -1
- package/dist/commands/import.js +43 -1
- package/dist/commands/import.js.map +1 -1
- package/dist/commands/local.d.ts.map +1 -1
- package/dist/commands/local.js +76 -4
- package/dist/commands/local.js.map +1 -1
- package/dist/commands/mark.d.ts +37 -0
- package/dist/commands/mark.d.ts.map +1 -0
- package/dist/commands/mark.js +105 -0
- package/dist/commands/mark.js.map +1 -0
- package/dist/commands/mcp.d.ts +141 -2
- package/dist/commands/mcp.d.ts.map +1 -1
- package/dist/commands/mcp.js +72 -14
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/registry.d.ts.map +1 -1
- package/dist/commands/registry.js +12 -2
- package/dist/commands/registry.js.map +1 -1
- package/dist/commands/setup.d.ts +39 -0
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +118 -241
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/share.d.ts +7 -0
- package/dist/commands/share.d.ts.map +1 -0
- package/dist/commands/share.js +60 -0
- package/dist/commands/share.js.map +1 -0
- package/dist/commands/sync.d.ts +55 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +278 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/telemetry.d.ts +3 -3
- package/dist/commands/telemetry.js +6 -6
- package/dist/commands/telemetry.js.map +1 -1
- package/dist/commands/why.d.ts.map +1 -1
- package/dist/commands/why.js +27 -1
- package/dist/commands/why.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/ask-key-offer.d.ts +38 -0
- package/dist/lib/ask-key-offer.d.ts.map +1 -0
- package/dist/lib/ask-key-offer.js +130 -0
- package/dist/lib/ask-key-offer.js.map +1 -0
- package/dist/lib/backfill-state.d.ts +116 -0
- package/dist/lib/backfill-state.d.ts.map +1 -0
- package/dist/lib/backfill-state.js +342 -0
- package/dist/lib/backfill-state.js.map +1 -0
- package/dist/lib/backup-copy.d.ts +17 -0
- package/dist/lib/backup-copy.d.ts.map +1 -0
- package/dist/lib/backup-copy.js +13 -0
- package/dist/lib/backup-copy.js.map +1 -0
- package/dist/lib/capture-report.d.ts +22 -18
- package/dist/lib/capture-report.d.ts.map +1 -1
- package/dist/lib/capture-report.js +64 -2
- package/dist/lib/capture-report.js.map +1 -1
- package/dist/lib/config.d.ts +56 -24
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +176 -45
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/confirm-timeout.d.ts +8 -0
- package/dist/lib/confirm-timeout.d.ts.map +1 -0
- package/dist/lib/confirm-timeout.js +18 -0
- package/dist/lib/confirm-timeout.js.map +1 -0
- package/dist/lib/curation/check-marks.d.ts +48 -0
- package/dist/lib/curation/check-marks.d.ts.map +1 -0
- package/dist/lib/curation/check-marks.js +81 -0
- package/dist/lib/curation/check-marks.js.map +1 -0
- package/dist/lib/curation/guardrail.d.ts +39 -0
- package/dist/lib/curation/guardrail.d.ts.map +1 -0
- package/dist/lib/curation/guardrail.js +93 -0
- package/dist/lib/curation/guardrail.js.map +1 -0
- package/dist/lib/curation/judge.d.ts +3 -0
- package/dist/lib/curation/judge.d.ts.map +1 -0
- package/dist/lib/curation/judge.js +9 -0
- package/dist/lib/curation/judge.js.map +1 -0
- package/dist/lib/curation/judgements-db.d.ts +96 -0
- package/dist/lib/curation/judgements-db.d.ts.map +1 -0
- package/dist/lib/curation/judgements-db.js +200 -0
- package/dist/lib/curation/judgements-db.js.map +1 -0
- package/dist/lib/curation/last-check.d.ts +32 -0
- package/dist/lib/curation/last-check.d.ts.map +1 -0
- package/dist/lib/curation/last-check.js +81 -0
- package/dist/lib/curation/last-check.js.map +1 -0
- package/dist/lib/curation/mark.d.ts +76 -0
- package/dist/lib/curation/mark.d.ts.map +1 -0
- package/dist/lib/curation/mark.js +359 -0
- package/dist/lib/curation/mark.js.map +1 -0
- package/dist/lib/curation/text.d.ts +6 -0
- package/dist/lib/curation/text.d.ts.map +1 -0
- package/dist/lib/curation/text.js +35 -0
- package/dist/lib/curation/text.js.map +1 -0
- package/dist/lib/fetchers/capture.d.ts +49 -2
- package/dist/lib/fetchers/capture.d.ts.map +1 -1
- package/dist/lib/fetchers/capture.js +7 -1
- package/dist/lib/fetchers/capture.js.map +1 -1
- package/dist/lib/fetchers/confluence.d.ts +2 -2
- package/dist/lib/fetchers/confluence.d.ts.map +1 -1
- package/dist/lib/fetchers/confluence.js.map +1 -1
- package/dist/lib/fetchers/git.d.ts +1 -0
- package/dist/lib/fetchers/git.d.ts.map +1 -1
- package/dist/lib/fetchers/git.js +3 -1
- package/dist/lib/fetchers/git.js.map +1 -1
- package/dist/lib/fetchers/github.d.ts +44 -5
- package/dist/lib/fetchers/github.d.ts.map +1 -1
- package/dist/lib/fetchers/github.js +122 -5
- package/dist/lib/fetchers/github.js.map +1 -1
- package/dist/lib/fetchers/gitlab.d.ts +2 -2
- package/dist/lib/fetchers/gitlab.d.ts.map +1 -1
- package/dist/lib/fetchers/gitlab.js.map +1 -1
- package/dist/lib/fetchers/jira.d.ts +2 -2
- package/dist/lib/fetchers/jira.d.ts.map +1 -1
- package/dist/lib/fetchers/jira.js.map +1 -1
- package/dist/lib/fetchers/linear.d.ts +2 -2
- package/dist/lib/fetchers/linear.d.ts.map +1 -1
- package/dist/lib/fetchers/linear.js.map +1 -1
- package/dist/lib/fetchers/notion.d.ts +2 -2
- package/dist/lib/fetchers/notion.d.ts.map +1 -1
- package/dist/lib/fetchers/notion.js.map +1 -1
- package/dist/lib/fetchers/slack.d.ts +2 -3
- package/dist/lib/fetchers/slack.d.ts.map +1 -1
- package/dist/lib/fetchers/slack.js.map +1 -1
- package/dist/lib/fetchers/teams.d.ts +2 -2
- package/dist/lib/fetchers/teams.d.ts.map +1 -1
- package/dist/lib/fetchers/teams.js.map +1 -1
- package/dist/lib/fetchers/zoom.d.ts +2 -2
- package/dist/lib/fetchers/zoom.d.ts.map +1 -1
- package/dist/lib/fetchers/zoom.js.map +1 -1
- package/dist/lib/gateway-client.d.ts +34 -0
- package/dist/lib/gateway-client.d.ts.map +1 -1
- package/dist/lib/gateway-client.js +19 -1
- package/dist/lib/gateway-client.js.map +1 -1
- package/dist/lib/github-text.d.ts +3 -0
- package/dist/lib/github-text.d.ts.map +1 -0
- package/dist/lib/github-text.js +18 -0
- package/dist/lib/github-text.js.map +1 -0
- package/dist/lib/hook-context.d.ts +10 -0
- package/dist/lib/hook-context.d.ts.map +1 -1
- package/dist/lib/hook-context.js +14 -0
- package/dist/lib/hook-context.js.map +1 -1
- package/dist/lib/import-defaults.d.ts +39 -23
- package/dist/lib/import-defaults.d.ts.map +1 -1
- package/dist/lib/import-defaults.js +28 -26
- package/dist/lib/import-defaults.js.map +1 -1
- package/dist/lib/launch/adapters/aider.d.ts +17 -0
- package/dist/lib/launch/adapters/aider.d.ts.map +1 -0
- package/dist/lib/launch/adapters/aider.js +30 -0
- package/dist/lib/launch/adapters/aider.js.map +1 -0
- package/dist/lib/launch/adapters/amp.d.ts +18 -0
- package/dist/lib/launch/adapters/amp.d.ts.map +1 -0
- package/dist/lib/launch/adapters/amp.js +29 -0
- package/dist/lib/launch/adapters/amp.js.map +1 -0
- package/dist/lib/launch/adapters/auggie.d.ts +18 -0
- package/dist/lib/launch/adapters/auggie.d.ts.map +1 -0
- package/dist/lib/launch/adapters/auggie.js +34 -0
- package/dist/lib/launch/adapters/auggie.js.map +1 -0
- package/dist/lib/launch/adapters/cline.d.ts +10 -0
- package/dist/lib/launch/adapters/cline.d.ts.map +1 -0
- package/dist/lib/launch/adapters/cline.js +41 -0
- package/dist/lib/launch/adapters/cline.js.map +1 -0
- package/dist/lib/launch/adapters/continue.d.ts +22 -0
- package/dist/lib/launch/adapters/continue.d.ts.map +1 -0
- package/dist/lib/launch/adapters/continue.js +46 -0
- package/dist/lib/launch/adapters/continue.js.map +1 -0
- package/dist/lib/launch/adapters/droid.d.ts +19 -0
- package/dist/lib/launch/adapters/droid.d.ts.map +1 -0
- package/dist/lib/launch/adapters/droid.js +38 -0
- package/dist/lib/launch/adapters/droid.js.map +1 -0
- package/dist/lib/launch/adapters/gemini-cli.d.ts +13 -14
- package/dist/lib/launch/adapters/gemini-cli.d.ts.map +1 -1
- package/dist/lib/launch/adapters/gemini-cli.js +38 -53
- package/dist/lib/launch/adapters/gemini-cli.js.map +1 -1
- package/dist/lib/launch/adapters/goose.d.ts +20 -0
- package/dist/lib/launch/adapters/goose.d.ts.map +1 -0
- package/dist/lib/launch/adapters/goose.js +47 -0
- package/dist/lib/launch/adapters/goose.js.map +1 -0
- package/dist/lib/launch/adapters/grok-build.d.ts +16 -0
- package/dist/lib/launch/adapters/grok-build.d.ts.map +1 -0
- package/dist/lib/launch/adapters/grok-build.js +25 -0
- package/dist/lib/launch/adapters/grok-build.js.map +1 -0
- package/dist/lib/launch/adapters/kiro.d.ts +17 -0
- package/dist/lib/launch/adapters/kiro.d.ts.map +1 -0
- package/dist/lib/launch/adapters/kiro.js +25 -0
- package/dist/lib/launch/adapters/kiro.js.map +1 -0
- package/dist/lib/launch/adapters/notes.d.ts +7 -0
- package/dist/lib/launch/adapters/notes.d.ts.map +1 -0
- package/dist/lib/launch/adapters/notes.js +5 -0
- package/dist/lib/launch/adapters/notes.js.map +1 -0
- package/dist/lib/launch/adapters/qwen.d.ts +25 -0
- package/dist/lib/launch/adapters/qwen.d.ts.map +1 -0
- package/dist/lib/launch/adapters/qwen.js +67 -0
- package/dist/lib/launch/adapters/qwen.js.map +1 -0
- package/dist/lib/launch/agents.d.ts +6 -1
- package/dist/lib/launch/agents.d.ts.map +1 -1
- package/dist/lib/launch/agents.js +12 -4
- package/dist/lib/launch/agents.js.map +1 -1
- package/dist/lib/launch/amp-state.d.ts +21 -0
- package/dist/lib/launch/amp-state.d.ts.map +1 -0
- package/dist/lib/launch/amp-state.js +61 -0
- package/dist/lib/launch/amp-state.js.map +1 -0
- package/dist/lib/launch/auggie-state.d.ts +25 -0
- package/dist/lib/launch/auggie-state.d.ts.map +1 -0
- package/dist/lib/launch/auggie-state.js +74 -0
- package/dist/lib/launch/auggie-state.js.map +1 -0
- package/dist/lib/launch/cline-state.d.ts +32 -0
- package/dist/lib/launch/cline-state.d.ts.map +1 -0
- package/dist/lib/launch/cline-state.js +108 -0
- package/dist/lib/launch/cline-state.js.map +1 -0
- package/dist/lib/launch/config-writes.d.ts +11 -1
- package/dist/lib/launch/config-writes.d.ts.map +1 -1
- package/dist/lib/launch/config-writes.js +66 -8
- package/dist/lib/launch/config-writes.js.map +1 -1
- package/dist/lib/launch/continue-state.d.ts +41 -0
- package/dist/lib/launch/continue-state.d.ts.map +1 -0
- package/dist/lib/launch/continue-state.js +142 -0
- package/dist/lib/launch/continue-state.js.map +1 -0
- package/dist/lib/launch/detect.d.ts.map +1 -1
- package/dist/lib/launch/detect.js +5 -2
- package/dist/lib/launch/detect.js.map +1 -1
- package/dist/lib/launch/droid-state.d.ts +24 -0
- package/dist/lib/launch/droid-state.d.ts.map +1 -0
- package/dist/lib/launch/droid-state.js +74 -0
- package/dist/lib/launch/droid-state.js.map +1 -0
- package/dist/lib/launch/gemini-state.d.ts +26 -20
- package/dist/lib/launch/gemini-state.d.ts.map +1 -1
- package/dist/lib/launch/gemini-state.js +95 -37
- package/dist/lib/launch/gemini-state.js.map +1 -1
- package/dist/lib/launch/gemini-system-file.d.ts +17 -0
- package/dist/lib/launch/gemini-system-file.d.ts.map +1 -0
- package/dist/lib/launch/gemini-system-file.js +55 -0
- package/dist/lib/launch/gemini-system-file.js.map +1 -0
- package/dist/lib/launch/gemini-trust.d.ts +3 -1
- package/dist/lib/launch/gemini-trust.d.ts.map +1 -1
- package/dist/lib/launch/gemini-trust.js +10 -3
- package/dist/lib/launch/gemini-trust.js.map +1 -1
- package/dist/lib/launch/goose-state.d.ts +53 -0
- package/dist/lib/launch/goose-state.d.ts.map +1 -0
- package/dist/lib/launch/goose-state.js +137 -0
- package/dist/lib/launch/goose-state.js.map +1 -0
- package/dist/lib/launch/grok-state.d.ts +42 -0
- package/dist/lib/launch/grok-state.d.ts.map +1 -0
- package/dist/lib/launch/grok-state.js +128 -0
- package/dist/lib/launch/grok-state.js.map +1 -0
- package/dist/lib/launch/kiro-state.d.ts +22 -0
- package/dist/lib/launch/kiro-state.d.ts.map +1 -0
- package/dist/lib/launch/kiro-state.js +59 -0
- package/dist/lib/launch/kiro-state.js.map +1 -0
- package/dist/lib/launch/launch-files.d.ts.map +1 -1
- package/dist/lib/launch/launch-files.js +3 -2
- package/dist/lib/launch/launch-files.js.map +1 -1
- package/dist/lib/launch/launch.d.ts +51 -2
- package/dist/lib/launch/launch.d.ts.map +1 -1
- package/dist/lib/launch/launch.js +70 -6
- package/dist/lib/launch/launch.js.map +1 -1
- package/dist/lib/launch/layer-files.d.ts +12 -0
- package/dist/lib/launch/layer-files.d.ts.map +1 -0
- package/dist/lib/launch/layer-files.js +43 -0
- package/dist/lib/launch/layer-files.js.map +1 -0
- package/dist/lib/launch/mcp-child-env.d.ts +30 -0
- package/dist/lib/launch/mcp-child-env.d.ts.map +1 -0
- package/dist/lib/launch/mcp-child-env.js +151 -0
- package/dist/lib/launch/mcp-child-env.js.map +1 -0
- package/dist/lib/launch/pick-agent.d.ts.map +1 -1
- package/dist/lib/launch/pick-agent.js +7 -6
- package/dist/lib/launch/pick-agent.js.map +1 -1
- package/dist/lib/launch/picker-options.d.ts.map +1 -1
- package/dist/lib/launch/picker-options.js +7 -2
- package/dist/lib/launch/picker-options.js.map +1 -1
- package/dist/lib/launch/qwen-state.d.ts +30 -0
- package/dist/lib/launch/qwen-state.d.ts.map +1 -0
- package/dist/lib/launch/qwen-state.js +57 -0
- package/dist/lib/launch/qwen-state.js.map +1 -0
- package/dist/lib/launch/qwen-trust.d.ts +24 -0
- package/dist/lib/launch/qwen-trust.d.ts.map +1 -0
- package/dist/lib/launch/qwen-trust.js +100 -0
- package/dist/lib/launch/qwen-trust.js.map +1 -0
- package/dist/lib/launch/registry/agents/aider.d.ts +3 -0
- package/dist/lib/launch/registry/agents/aider.d.ts.map +1 -0
- package/dist/lib/launch/registry/agents/aider.js +13 -0
- package/dist/lib/launch/registry/agents/aider.js.map +1 -0
- package/dist/lib/launch/registry/agents/amp.d.ts +3 -0
- package/dist/lib/launch/registry/agents/amp.d.ts.map +1 -0
- package/dist/lib/launch/registry/agents/amp.js +14 -0
- package/dist/lib/launch/registry/agents/amp.js.map +1 -0
- package/dist/lib/launch/registry/agents/auggie.d.ts +3 -0
- package/dist/lib/launch/registry/agents/auggie.d.ts.map +1 -0
- package/dist/lib/launch/registry/agents/auggie.js +11 -0
- package/dist/lib/launch/registry/agents/auggie.js.map +1 -0
- package/dist/lib/launch/registry/agents/cline.d.ts +3 -0
- package/dist/lib/launch/registry/agents/cline.d.ts.map +1 -0
- package/dist/lib/launch/registry/agents/cline.js +19 -0
- package/dist/lib/launch/registry/agents/cline.js.map +1 -0
- package/dist/lib/launch/registry/agents/continue.d.ts +3 -0
- package/dist/lib/launch/registry/agents/continue.d.ts.map +1 -0
- package/dist/lib/launch/registry/agents/continue.js +20 -0
- package/dist/lib/launch/registry/agents/continue.js.map +1 -0
- package/dist/lib/launch/registry/agents/droid.d.ts +3 -0
- package/dist/lib/launch/registry/agents/droid.d.ts.map +1 -0
- package/dist/lib/launch/registry/agents/droid.js +13 -0
- package/dist/lib/launch/registry/agents/droid.js.map +1 -0
- package/dist/lib/launch/registry/agents/gemini-cli.js +2 -2
- package/dist/lib/launch/registry/agents/gemini-cli.js.map +1 -1
- package/dist/lib/launch/registry/agents/goose.d.ts +3 -0
- package/dist/lib/launch/registry/agents/goose.d.ts.map +1 -0
- package/dist/lib/launch/registry/agents/goose.js +20 -0
- package/dist/lib/launch/registry/agents/goose.js.map +1 -0
- package/dist/lib/launch/registry/agents/grok-build.d.ts +3 -0
- package/dist/lib/launch/registry/agents/grok-build.d.ts.map +1 -0
- package/dist/lib/launch/registry/agents/grok-build.js +14 -0
- package/dist/lib/launch/registry/agents/grok-build.js.map +1 -0
- package/dist/lib/launch/registry/agents/kiro.d.ts +3 -0
- package/dist/lib/launch/registry/agents/kiro.d.ts.map +1 -0
- package/dist/lib/launch/registry/agents/kiro.js +11 -0
- package/dist/lib/launch/registry/agents/kiro.js.map +1 -0
- package/dist/lib/launch/registry/agents/qwen.d.ts +3 -0
- package/dist/lib/launch/registry/agents/qwen.d.ts.map +1 -0
- package/dist/lib/launch/registry/agents/qwen.js +11 -0
- package/dist/lib/launch/registry/agents/qwen.js.map +1 -0
- package/dist/lib/launch/registry/index.d.ts +4 -1
- package/dist/lib/launch/registry/index.d.ts.map +1 -1
- package/dist/lib/launch/registry/index.js +15 -2
- package/dist/lib/launch/registry/index.js.map +1 -1
- package/dist/lib/launch/registry/types.d.ts +17 -1
- package/dist/lib/launch/registry/types.d.ts.map +1 -1
- package/dist/lib/launch/run-agent.d.ts +11 -0
- package/dist/lib/launch/run-agent.d.ts.map +1 -1
- package/dist/lib/launch/run-agent.js +22 -1
- package/dist/lib/launch/run-agent.js.map +1 -1
- package/dist/lib/launch/strict-entry.d.ts +22 -2
- package/dist/lib/launch/strict-entry.d.ts.map +1 -1
- package/dist/lib/launch/strict-entry.js +82 -2
- package/dist/lib/launch/strict-entry.js.map +1 -1
- package/dist/lib/launch/yaml-scan.d.ts +59 -0
- package/dist/lib/launch/yaml-scan.d.ts.map +1 -0
- package/dist/lib/launch/yaml-scan.js +275 -0
- package/dist/lib/launch/yaml-scan.js.map +1 -0
- package/dist/lib/llm-providers.d.ts +66 -0
- package/dist/lib/llm-providers.d.ts.map +1 -0
- package/dist/lib/llm-providers.js +150 -0
- package/dist/lib/llm-providers.js.map +1 -0
- package/dist/lib/local-db-epoch.d.ts +4 -0
- package/dist/lib/local-db-epoch.d.ts.map +1 -0
- package/dist/lib/local-db-epoch.js +19 -0
- package/dist/lib/local-db-epoch.js.map +1 -0
- package/dist/lib/local-db-migrate.d.ts +85 -0
- package/dist/lib/local-db-migrate.d.ts.map +1 -0
- package/dist/lib/local-db-migrate.js +484 -0
- package/dist/lib/local-db-migrate.js.map +1 -0
- package/dist/lib/local-db-v10.d.ts +28 -0
- package/dist/lib/local-db-v10.d.ts.map +1 -0
- package/dist/lib/local-db-v10.js +49 -0
- package/dist/lib/local-db-v10.js.map +1 -0
- package/dist/lib/local-db-v11.d.ts +24 -0
- package/dist/lib/local-db-v11.d.ts.map +1 -0
- package/dist/lib/local-db-v11.js +25 -0
- package/dist/lib/local-db-v11.js.map +1 -0
- package/dist/lib/local-db-v7.d.ts +30 -0
- package/dist/lib/local-db-v7.d.ts.map +1 -0
- package/dist/lib/local-db-v7.js +285 -0
- package/dist/lib/local-db-v7.js.map +1 -0
- package/dist/lib/local-db-v8.d.ts +22 -0
- package/dist/lib/local-db-v8.d.ts.map +1 -0
- package/dist/lib/local-db-v8.js +33 -0
- package/dist/lib/local-db-v8.js.map +1 -0
- package/dist/lib/local-db-v9.d.ts +10 -0
- package/dist/lib/local-db-v9.d.ts.map +1 -0
- package/dist/lib/local-db-v9.js +8 -0
- package/dist/lib/local-db-v9.js.map +1 -0
- package/dist/lib/local-db.d.ts +61 -11
- package/dist/lib/local-db.d.ts.map +1 -1
- package/dist/lib/local-db.js +186 -371
- package/dist/lib/local-db.js.map +1 -1
- package/dist/lib/local-embeddings.d.ts.map +1 -1
- package/dist/lib/local-embeddings.js +2 -2
- package/dist/lib/local-embeddings.js.map +1 -1
- package/dist/lib/local-gateway-client.d.ts +30 -87
- package/dist/lib/local-gateway-client.d.ts.map +1 -1
- package/dist/lib/local-gateway-client.js +182 -171
- package/dist/lib/local-gateway-client.js.map +1 -1
- package/dist/lib/local-ingest.d.ts +129 -0
- package/dist/lib/local-ingest.d.ts.map +1 -0
- package/dist/lib/local-ingest.js +81 -0
- package/dist/lib/local-ingest.js.map +1 -0
- package/dist/lib/local-link-pass.d.ts +15 -0
- package/dist/lib/local-link-pass.d.ts.map +1 -0
- package/dist/lib/local-link-pass.js +61 -0
- package/dist/lib/local-link-pass.js.map +1 -0
- package/dist/lib/local-llm.d.ts +63 -12
- package/dist/lib/local-llm.d.ts.map +1 -1
- package/dist/lib/local-llm.js +229 -104
- package/dist/lib/local-llm.js.map +1 -1
- package/dist/lib/local-mode.d.ts +4 -1
- package/dist/lib/local-mode.d.ts.map +1 -1
- package/dist/lib/local-mode.js +16 -1
- package/dist/lib/local-mode.js.map +1 -1
- package/dist/lib/local-provenance.d.ts +14 -0
- package/dist/lib/local-provenance.d.ts.map +1 -0
- package/dist/lib/local-provenance.js +14 -0
- package/dist/lib/local-provenance.js.map +1 -0
- package/dist/lib/local-thresholds.d.ts +70 -0
- package/dist/lib/local-thresholds.d.ts.map +1 -0
- package/dist/lib/local-thresholds.js +79 -0
- package/dist/lib/local-thresholds.js.map +1 -0
- package/dist/lib/mcp/mark-tool.d.ts +27 -0
- package/dist/lib/mcp/mark-tool.d.ts.map +1 -0
- package/dist/lib/mcp/mark-tool.js +103 -0
- package/dist/lib/mcp/mark-tool.js.map +1 -0
- package/dist/lib/mcp/share-tool.d.ts +46 -0
- package/dist/lib/mcp/share-tool.d.ts.map +1 -0
- package/dist/lib/mcp/share-tool.js +68 -0
- package/dist/lib/mcp/share-tool.js.map +1 -0
- package/dist/lib/mcp/tool-rules.d.ts +30 -0
- package/dist/lib/mcp/tool-rules.d.ts.map +1 -0
- package/dist/lib/mcp/tool-rules.js +84 -0
- package/dist/lib/mcp/tool-rules.js.map +1 -0
- package/dist/lib/mcp-backfill.d.ts +89 -0
- package/dist/lib/mcp-backfill.d.ts.map +1 -0
- package/dist/lib/mcp-backfill.js +194 -0
- package/dist/lib/mcp-backfill.js.map +1 -0
- package/dist/lib/mcp-scope.d.ts +90 -0
- package/dist/lib/mcp-scope.d.ts.map +1 -0
- package/dist/lib/mcp-scope.js +125 -0
- package/dist/lib/mcp-scope.js.map +1 -0
- package/dist/lib/mcp-sync.d.ts +64 -0
- package/dist/lib/mcp-sync.d.ts.map +1 -0
- package/dist/lib/mcp-sync.js +183 -0
- package/dist/lib/mcp-sync.js.map +1 -0
- package/dist/lib/personal-import.d.ts +7 -0
- package/dist/lib/personal-import.d.ts.map +1 -1
- package/dist/lib/personal-import.js +13 -1
- package/dist/lib/personal-import.js.map +1 -1
- package/dist/lib/safe-config-write.d.ts +12 -1
- package/dist/lib/safe-config-write.d.ts.map +1 -1
- package/dist/lib/safe-config-write.js +162 -9
- package/dist/lib/safe-config-write.js.map +1 -1
- package/dist/lib/scope-choices.d.ts +51 -0
- package/dist/lib/scope-choices.d.ts.map +1 -0
- package/dist/lib/scope-choices.js +193 -0
- package/dist/lib/scope-choices.js.map +1 -0
- package/dist/lib/scope-connect.d.ts +82 -0
- package/dist/lib/scope-connect.d.ts.map +1 -0
- package/dist/lib/scope-connect.js +258 -0
- package/dist/lib/scope-connect.js.map +1 -0
- package/dist/lib/scope-defaults.d.ts +3 -0
- package/dist/lib/scope-defaults.d.ts.map +1 -0
- package/dist/lib/scope-defaults.js +42 -0
- package/dist/lib/scope-defaults.js.map +1 -0
- package/dist/lib/scope-real.d.ts +223 -0
- package/dist/lib/scope-real.d.ts.map +1 -0
- package/dist/lib/scope-real.js +58 -0
- package/dist/lib/scope-real.js.map +1 -0
- package/dist/lib/scope-values.d.ts +76 -0
- package/dist/lib/scope-values.d.ts.map +1 -0
- package/dist/lib/scope-values.js +169 -0
- package/dist/lib/scope-values.js.map +1 -0
- package/dist/lib/scope.d.ts +161 -0
- package/dist/lib/scope.d.ts.map +1 -0
- package/dist/lib/scope.js +323 -0
- package/dist/lib/scope.js.map +1 -0
- package/dist/lib/share/command.d.ts +32 -0
- package/dist/lib/share/command.d.ts.map +1 -0
- package/dist/lib/share/command.js +136 -0
- package/dist/lib/share/command.js.map +1 -0
- package/dist/lib/share/ledger.d.ts +59 -0
- package/dist/lib/share/ledger.d.ts.map +1 -0
- package/dist/lib/share/ledger.js +135 -0
- package/dist/lib/share/ledger.js.map +1 -0
- package/dist/lib/share/payload.d.ts +92 -0
- package/dist/lib/share/payload.d.ts.map +1 -0
- package/dist/lib/share/payload.js +138 -0
- package/dist/lib/share/payload.js.map +1 -0
- package/dist/lib/share/pending.d.ts +48 -0
- package/dist/lib/share/pending.d.ts.map +1 -0
- package/dist/lib/share/pending.js +130 -0
- package/dist/lib/share/pending.js.map +1 -0
- package/dist/lib/share/preview.d.ts +18 -0
- package/dist/lib/share/preview.d.ts.map +1 -0
- package/dist/lib/share/preview.js +72 -0
- package/dist/lib/share/preview.js.map +1 -0
- package/dist/lib/share/run.d.ts +115 -0
- package/dist/lib/share/run.d.ts.map +1 -0
- package/dist/lib/share/run.js +261 -0
- package/dist/lib/share/run.js.map +1 -0
- package/dist/lib/share/salt.d.ts +2 -0
- package/dist/lib/share/salt.d.ts.map +1 -0
- package/dist/lib/share/salt.js +44 -0
- package/dist/lib/share/salt.js.map +1 -0
- package/dist/lib/share/secret-patterns.json +100 -0
- package/dist/lib/share/secret-scan.d.ts +19 -0
- package/dist/lib/share/secret-scan.d.ts.map +1 -0
- package/dist/lib/share/secret-scan.js +75 -0
- package/dist/lib/share/secret-scan.js.map +1 -0
- package/dist/lib/share/tty.d.ts +4 -0
- package/dist/lib/share/tty.d.ts.map +1 -0
- package/dist/lib/share/tty.js +57 -0
- package/dist/lib/share/tty.js.map +1 -0
- package/dist/lib/share/visible.d.ts +4 -0
- package/dist/lib/share/visible.d.ts.map +1 -0
- package/dist/lib/share/visible.js +30 -0
- package/dist/lib/share/visible.js.map +1 -0
- package/dist/lib/share/wire.d.ts +98 -0
- package/dist/lib/share/wire.d.ts.map +1 -0
- package/dist/lib/share/wire.js +43 -0
- package/dist/lib/share/wire.js.map +1 -0
- package/dist/lib/similarity/embedding-matrix.d.ts +64 -0
- package/dist/lib/similarity/embedding-matrix.d.ts.map +1 -0
- package/dist/lib/similarity/embedding-matrix.js +119 -0
- package/dist/lib/similarity/embedding-matrix.js.map +1 -0
- package/dist/lib/since-flag.d.ts +11 -0
- package/dist/lib/since-flag.d.ts.map +1 -0
- package/dist/lib/since-flag.js +24 -0
- package/dist/lib/since-flag.js.map +1 -0
- package/dist/lib/since.d.ts +59 -0
- package/dist/lib/since.d.ts.map +1 -0
- package/dist/lib/since.js +86 -0
- package/dist/lib/since.js.map +1 -0
- package/dist/lib/source-key.d.ts +13 -0
- package/dist/lib/source-key.d.ts.map +1 -0
- package/dist/lib/source-key.js +60 -0
- package/dist/lib/source-key.js.map +1 -0
- package/dist/lib/source-sync-state.d.ts +12 -0
- package/dist/lib/source-sync-state.d.ts.map +1 -0
- package/dist/lib/source-sync-state.js +43 -0
- package/dist/lib/source-sync-state.js.map +1 -0
- package/dist/lib/startup-backfill-track.d.ts +2 -0
- package/dist/lib/startup-backfill-track.d.ts.map +1 -0
- package/dist/lib/startup-backfill-track.js +6 -0
- package/dist/lib/startup-backfill-track.js.map +1 -0
- package/dist/lib/startup-env.d.ts +8 -0
- package/dist/lib/startup-env.d.ts.map +1 -0
- package/dist/lib/startup-env.js +8 -0
- package/dist/lib/startup-env.js.map +1 -0
- package/dist/lib/startup-xdg.d.ts +2 -0
- package/dist/lib/startup-xdg.d.ts.map +1 -0
- package/dist/lib/startup-xdg.js +9 -0
- package/dist/lib/startup-xdg.js.map +1 -0
- package/dist/lib/sync/after-connect.d.ts +2 -0
- package/dist/lib/sync/after-connect.d.ts.map +1 -0
- package/dist/lib/sync/after-connect.js +18 -0
- package/dist/lib/sync/after-connect.js.map +1 -0
- package/dist/lib/sync/bg-claim.d.ts +14 -0
- package/dist/lib/sync/bg-claim.d.ts.map +1 -0
- package/dist/lib/sync/bg-claim.js +97 -0
- package/dist/lib/sync/bg-claim.js.map +1 -0
- package/dist/lib/sync/blocked.d.ts +8 -0
- package/dist/lib/sync/blocked.d.ts.map +1 -0
- package/dist/lib/sync/blocked.js +44 -0
- package/dist/lib/sync/blocked.js.map +1 -0
- package/dist/lib/sync/classify.d.ts +34 -0
- package/dist/lib/sync/classify.d.ts.map +1 -0
- package/dist/lib/sync/classify.js +91 -0
- package/dist/lib/sync/classify.js.map +1 -0
- package/dist/lib/sync/drain.d.ts +16 -0
- package/dist/lib/sync/drain.d.ts.map +1 -0
- package/dist/lib/sync/drain.js +33 -0
- package/dist/lib/sync/drain.js.map +1 -0
- package/dist/lib/sync/forget.d.ts +12 -0
- package/dist/lib/sync/forget.d.ts.map +1 -0
- package/dist/lib/sync/forget.js +32 -0
- package/dist/lib/sync/forget.js.map +1 -0
- package/dist/lib/sync/launch-hook.d.ts +42 -0
- package/dist/lib/sync/launch-hook.d.ts.map +1 -0
- package/dist/lib/sync/launch-hook.js +117 -0
- package/dist/lib/sync/launch-hook.js.map +1 -0
- package/dist/lib/sync/lock.d.ts +35 -0
- package/dist/lib/sync/lock.d.ts.map +1 -0
- package/dist/lib/sync/lock.js +175 -0
- package/dist/lib/sync/lock.js.map +1 -0
- package/dist/lib/sync/purge.d.ts +38 -0
- package/dist/lib/sync/purge.d.ts.map +1 -0
- package/dist/lib/sync/purge.js +61 -0
- package/dist/lib/sync/purge.js.map +1 -0
- package/dist/lib/sync/real-env.d.ts +208 -0
- package/dist/lib/sync/real-env.d.ts.map +1 -0
- package/dist/lib/sync/real-env.js +47 -0
- package/dist/lib/sync/real-env.js.map +1 -0
- package/dist/lib/sync/relink.d.ts +14 -0
- package/dist/lib/sync/relink.d.ts.map +1 -0
- package/dist/lib/sync/relink.js +36 -0
- package/dist/lib/sync/relink.js.map +1 -0
- package/dist/lib/sync/report.d.ts +3 -0
- package/dist/lib/sync/report.d.ts.map +1 -0
- package/dist/lib/sync/report.js +54 -0
- package/dist/lib/sync/report.js.map +1 -0
- package/dist/lib/sync/run-all.d.ts +23 -0
- package/dist/lib/sync/run-all.d.ts.map +1 -0
- package/dist/lib/sync/run-all.js +30 -0
- package/dist/lib/sync/run-all.js.map +1 -0
- package/dist/lib/sync/run-source.d.ts +73 -0
- package/dist/lib/sync/run-source.d.ts.map +1 -0
- package/dist/lib/sync/run-source.js +262 -0
- package/dist/lib/sync/run-source.js.map +1 -0
- package/dist/lib/sync/safe-read.d.ts +4 -0
- package/dist/lib/sync/safe-read.d.ts.map +1 -0
- package/dist/lib/sync/safe-read.js +40 -0
- package/dist/lib/sync/safe-read.js.map +1 -0
- package/dist/lib/sync/should-background-sync.d.ts +31 -0
- package/dist/lib/sync/should-background-sync.d.ts.map +1 -0
- package/dist/lib/sync/should-background-sync.js +69 -0
- package/dist/lib/sync/should-background-sync.js.map +1 -0
- package/dist/lib/sync/source-ids.d.ts +10 -0
- package/dist/lib/sync/source-ids.d.ts.map +1 -0
- package/dist/lib/sync/source-ids.js +9 -0
- package/dist/lib/sync/source-ids.js.map +1 -0
- package/dist/lib/sync/sources.d.ts +33 -0
- package/dist/lib/sync/sources.d.ts.map +1 -0
- package/dist/lib/sync/sources.js +37 -0
- package/dist/lib/sync/sources.js.map +1 -0
- package/dist/lib/sync/spawn-background.d.ts +27 -0
- package/dist/lib/sync/spawn-background.d.ts.map +1 -0
- package/dist/lib/sync/spawn-background.js +66 -0
- package/dist/lib/sync/spawn-background.js.map +1 -0
- package/dist/lib/sync/status.d.ts +57 -0
- package/dist/lib/sync/status.d.ts.map +1 -0
- package/dist/lib/sync/status.js +166 -0
- package/dist/lib/sync/status.js.map +1 -0
- package/dist/lib/sync/summary-read.d.ts +19 -0
- package/dist/lib/sync/summary-read.d.ts.map +1 -0
- package/dist/lib/sync/summary-read.js +39 -0
- package/dist/lib/sync/summary-read.js.map +1 -0
- package/dist/lib/sync/summary.d.ts +10 -0
- package/dist/lib/sync/summary.d.ts.map +1 -0
- package/dist/lib/sync/summary.js +80 -0
- package/dist/lib/sync/summary.js.map +1 -0
- package/dist/lib/sync/sync-state.d.ts +128 -0
- package/dist/lib/sync/sync-state.d.ts.map +1 -0
- package/dist/lib/sync/sync-state.js +253 -0
- package/dist/lib/sync/sync-state.js.map +1 -0
- package/dist/lib/sync/telemetry.d.ts +20 -0
- package/dist/lib/sync/telemetry.d.ts.map +1 -0
- package/dist/lib/sync/telemetry.js +31 -0
- package/dist/lib/sync/telemetry.js.map +1 -0
- package/dist/lib/sync/threads.d.ts +48 -0
- package/dist/lib/sync/threads.d.ts.map +1 -0
- package/dist/lib/sync/threads.js +82 -0
- package/dist/lib/sync/threads.js.map +1 -0
- package/dist/lib/sync/window.d.ts +72 -0
- package/dist/lib/sync/window.d.ts.map +1 -0
- package/dist/lib/sync/window.js +112 -0
- package/dist/lib/sync/window.js.map +1 -0
- package/dist/lib/team-cta.d.ts +11 -0
- package/dist/lib/team-cta.d.ts.map +1 -0
- package/dist/lib/team-cta.js +16 -0
- package/dist/lib/team-cta.js.map +1 -0
- package/dist/lib/telemetry-ci.d.ts +2 -0
- package/dist/lib/telemetry-ci.d.ts.map +1 -0
- package/dist/lib/telemetry-ci.js +21 -0
- package/dist/lib/telemetry-ci.js.map +1 -0
- package/dist/lib/telemetry-consent.d.ts +44 -23
- package/dist/lib/telemetry-consent.d.ts.map +1 -1
- package/dist/lib/telemetry-consent.js +74 -35
- package/dist/lib/telemetry-consent.js.map +1 -1
- package/dist/lib/telemetry-env.d.ts +1 -1
- package/dist/lib/usage-telemetry.d.ts +87 -22
- package/dist/lib/usage-telemetry.d.ts.map +1 -1
- package/dist/lib/usage-telemetry.js +263 -74
- package/dist/lib/usage-telemetry.js.map +1 -1
- package/dist/lib/xdg.d.ts +27 -0
- package/dist/lib/xdg.d.ts.map +1 -0
- package/dist/lib/xdg.js +56 -0
- package/dist/lib/xdg.js.map +1 -0
- package/package.json +3 -2
- package/dist/commands/push.d.ts +0 -25
- package/dist/commands/push.d.ts.map +0 -1
- package/dist/commands/push.js +0 -98
- package/dist/commands/push.js.map +0 -1
package/dist/lib/local-db.js
CHANGED
|
@@ -2,65 +2,12 @@ import { DatabaseSync } from 'node:sqlite';
|
|
|
2
2
|
import { randomUUID } from 'node:crypto';
|
|
3
3
|
import { mkdirSync } from 'node:fs';
|
|
4
4
|
import { dirname } from 'node:path';
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
source_url TEXT,
|
|
12
|
-
platform TEXT NOT NULL DEFAULT 'cli',
|
|
13
|
-
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
14
|
-
repo TEXT,
|
|
15
|
-
decided_at TEXT,
|
|
16
|
-
decider_kind TEXT,
|
|
17
|
-
confirmed_by TEXT,
|
|
18
|
-
confirmed_at TEXT,
|
|
19
|
-
ratified_by TEXT,
|
|
20
|
-
ratified_at TEXT
|
|
21
|
-
);
|
|
22
|
-
|
|
23
|
-
CREATE TABLE IF NOT EXISTS decision_audit (
|
|
24
|
-
id TEXT PRIMARY KEY,
|
|
25
|
-
decision_id TEXT NOT NULL,
|
|
26
|
-
action TEXT NOT NULL,
|
|
27
|
-
actor TEXT,
|
|
28
|
-
detail TEXT,
|
|
29
|
-
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
30
|
-
);
|
|
31
|
-
|
|
32
|
-
CREATE TABLE IF NOT EXISTS decision_embeddings (
|
|
33
|
-
decision_id TEXT PRIMARY KEY REFERENCES decisions(id) ON DELETE CASCADE,
|
|
34
|
-
embedding BLOB NOT NULL,
|
|
35
|
-
model TEXT
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
CREATE TABLE IF NOT EXISTS decision_links (
|
|
39
|
-
id TEXT PRIMARY KEY,
|
|
40
|
-
source_id TEXT NOT NULL REFERENCES decisions(id) ON DELETE CASCADE,
|
|
41
|
-
target_id TEXT NOT NULL REFERENCES decisions(id) ON DELETE CASCADE,
|
|
42
|
-
relation TEXT NOT NULL,
|
|
43
|
-
confidence REAL NOT NULL DEFAULT 1.0,
|
|
44
|
-
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
45
|
-
);
|
|
46
|
-
|
|
47
|
-
CREATE TABLE IF NOT EXISTS decision_refs (
|
|
48
|
-
decision_id TEXT NOT NULL REFERENCES decisions(id) ON DELETE CASCADE,
|
|
49
|
-
ref TEXT NOT NULL,
|
|
50
|
-
platform TEXT NOT NULL,
|
|
51
|
-
PRIMARY KEY (decision_id, ref)
|
|
52
|
-
);
|
|
53
|
-
`;
|
|
54
|
-
/**
|
|
55
|
-
* Schema version this build expects. Bump when adding a step to `migrate`.
|
|
56
|
-
*
|
|
57
|
-
* Exported so a test can assert the migration WROTE the version it claims, without hardcoding
|
|
58
|
-
* the number - a test pinning a literal 1 had to be edited by this change rather than passing
|
|
59
|
-
* or failing on its own merits. A parity test also derives the highest `version <` branch in
|
|
60
|
-
* `migrate` from the source and compares it here, because forgetting the bump leaves the new
|
|
61
|
-
* branch running destructively on every open with nothing to stop it.
|
|
62
|
-
*/
|
|
63
|
-
export const SCHEMA_VERSION = 6;
|
|
5
|
+
import { deleteDecisionWithDependents, migrate, SCHEMA, SLACK_TOMBSTONE_TITLE } from './local-db-migrate.js';
|
|
6
|
+
import { bumpRowSetEpoch, rowSetEpoch } from './local-db-epoch.js';
|
|
7
|
+
import { foldKeylessTwin } from './local-db-v7.js';
|
|
8
|
+
import { discussionStart } from './github-text.js';
|
|
9
|
+
import { connectorItemKey, KEYED_PLATFORMS } from './source-key.js';
|
|
10
|
+
export { SCHEMA_VERSION } from './local-db-migrate.js';
|
|
64
11
|
/**
|
|
65
12
|
* ALI-829: a source timestamp as this database stores it - ISO-8601 Z - or null.
|
|
66
13
|
*
|
|
@@ -92,10 +39,6 @@ export function normaliseDecidedAt(value) {
|
|
|
92
39
|
return null;
|
|
93
40
|
return new Date(ms).toISOString();
|
|
94
41
|
}
|
|
95
|
-
/** The title connector-core 0.5.0 gave every Slack thread whose root was deleted. The 0.6.0
|
|
96
|
-
* fetcher titles such a thread from its first human message, or drops it; either way this
|
|
97
|
-
* row is a duplicate-to-be under the (source_url, title) key, or noise. */
|
|
98
|
-
const SLACK_TOMBSTONE_TITLE = 'This message was deleted.';
|
|
99
42
|
/**
|
|
100
43
|
* A `source_url` is only an identity if it points at ONE thing. Some fetchers substitute a
|
|
101
44
|
* constant when the per-item link is missing, and connector-core ships one:
|
|
@@ -136,308 +79,13 @@ export function identifyingSourceUrl(raw) {
|
|
|
136
79
|
}
|
|
137
80
|
return value;
|
|
138
81
|
}
|
|
139
|
-
/** The five ALI-831 columns, named exactly as the shared contract spells them. One list,
|
|
140
|
-
* read by the migration; SCHEMA above spells them a second time because a fresh CREATE
|
|
141
|
-
* TABLE cannot read a constant, and the provenance test pins both against each other. */
|
|
142
|
-
const PROVENANCE_COLUMNS = ['decider_kind', 'confirmed_by', 'confirmed_at', 'ratified_by', 'ratified_at'];
|
|
143
|
-
/**
|
|
144
|
-
* ALI-787: the only embedding model this graph has ever written before the `model` column
|
|
145
|
-
* existed. Verified, not assumed - `git log --all -p` on local-embeddings.ts and
|
|
146
|
-
* local-embeddings-wasm.ts shows exactly one HF model id was ever hardcoded there, across
|
|
147
|
-
* every commit. So backfilling every pre-column row with this is a true historical fact,
|
|
148
|
-
* unlike `decided_at` (step 4 below), which genuinely cannot be derived from an existing row.
|
|
149
|
-
*
|
|
150
|
-
* A deliberate LITERAL, not an import of local-embeddings.ts's EMBEDDING_MODEL_ID: this
|
|
151
|
-
* constant names what was true when the column was added, and must stay that value even
|
|
152
|
-
* after a future model swap changes EMBEDDING_MODEL_ID. Migrations are a historical record.
|
|
153
|
-
*/
|
|
154
|
-
const LEGACY_EMBEDDING_MODEL = 'Xenova/all-MiniLM-L6-v2';
|
|
155
|
-
/**
|
|
156
|
-
* One-time data migrations, tracked in SQLite's built-in `user_version`.
|
|
157
|
-
*
|
|
158
|
-
* 1. ALI-503: relabel the cosine-similarity links that were written as `conflicts_with`.
|
|
159
|
-
* Every such row at version 0 is provably an artefact, because `insertLink` had exactly
|
|
160
|
-
* one caller and it hardcoded that relation for any pair over 0.65 cosine. No classifier
|
|
161
|
-
* verdict was ever persisted, so there is no earned row to damage.
|
|
162
|
-
*
|
|
163
|
-
* 2. A decision's `source_url` identifies it, and nothing enforced that: `insertDecision` minted
|
|
164
|
-
* a fresh UUID per call, so re-importing the same commit added a second copy. The documented
|
|
165
|
-
* first run does exactly that - `setup --local` seeds from git, then its own outro tells you
|
|
166
|
-
* to run `align connect git` - so a graph goes from 2 decisions to 4 by following the tips.
|
|
167
|
-
* Collapse the existing duplicates, then make them unrepresentable with a unique index.
|
|
168
|
-
*
|
|
169
|
-
* 3. ALI-798: add the `repo` column (missing on any graph that predates it) and backfill it
|
|
170
|
-
* for every existing row from `source_url`, via the same `repoFromSourceUrl` the importer
|
|
171
|
-
* now stamps new rows with - one reader of the URL shape, used for both. A row whose
|
|
172
|
-
* source is not code (Jira, Slack, a bare capture) stays NULL, which is "unattributed",
|
|
173
|
-
* not "wrong": `--repo` scoping always includes unattributed rows alongside the named
|
|
174
|
-
* repo (see local-gateway-client.ts), so nothing existing becomes invisible.
|
|
175
|
-
*
|
|
176
|
-
* 4. ALI-829: add `decided_at` - when the decision was MADE, from the source's own
|
|
177
|
-
* timestamp, as distinct from `created_at`, the minute this CLI imported it. Every one
|
|
178
|
-
* of the 684 rows in the 2026-09-02 measurement carried the ingest minute and nothing
|
|
179
|
-
* else, so "what changed since March" was unanswerable offline. No backfill, unlike
|
|
180
|
-
* `repo`: a repo is derivable from a stored source_url, and a decision date is not
|
|
181
|
-
* derivable from anything already in the row. A re-import fills it in; inventing one
|
|
182
|
-
* from created_at would write the exact wrong fact this column exists to correct.
|
|
183
|
-
*
|
|
184
|
-
* Same bump, second step: drop the Slack rows titled by a deleted root. The 0.6.0
|
|
185
|
-
* fetcher titles a thread from its first human message, and the dedup key is
|
|
186
|
-
* (source_url, title), so each of those rows would otherwise be re-inserted BESIDE its
|
|
187
|
-
* tombstone twin on the next import (35 of 39 on the 2026-09-02 graph). The next import
|
|
188
|
-
* recreates the real ones with real titles; the ones that were only bot output on a
|
|
189
|
-
* deleted root do not come back, which is the point. Foreign keys are off in this
|
|
190
|
-
* database (see step 2), so the dependent rows are deleted explicitly - including any
|
|
191
|
-
* link a human adjudicated on such a row. That is a real loss, accepted: the row's
|
|
192
|
-
* identity is changing under it, and the re-import classifies the retitled thread
|
|
193
|
-
* afresh. Scoped to platform = 'slack': a git commit or a captured note that happens to
|
|
194
|
-
* carry the same words is not a tombstone and is left alone.
|
|
195
|
-
*
|
|
196
|
-
* 5. ALI-831: add the decider/ratified columns (`decider_kind`, `confirmed_by`,
|
|
197
|
-
* `confirmed_at`, `ratified_by`, `ratified_at`) so an agent-made decision can enter as a
|
|
198
|
-
* CLAIM a human later stands behind, and the `decision_audit` table the human act is
|
|
199
|
-
* recorded in. No backfill, on purpose: a row captured before the column reads as
|
|
200
|
-
* 'unknown', and stamping 'human' on it from its platform would be the retroactive
|
|
201
|
-
* guess align-stack's migration 113 refuses. The columns are added here rather than only
|
|
202
|
-
* in SCHEMA because CREATE TABLE IF NOT EXISTS never alters an existing table.
|
|
203
|
-
*
|
|
204
|
-
* The version guard is load-bearing rather than tidiness. The same UPDATE run on every open
|
|
205
|
-
* is indistinguishable from this one today, and starts silently eating genuine conflicts the
|
|
206
|
-
* moment anything writes one.
|
|
207
|
-
*/
|
|
208
|
-
/**
|
|
209
|
-
* Remove a decision and everything hanging off it. Foreign keys are off in this database
|
|
210
|
-
* (see migrate, step 2), so the dependents are named explicitly rather than cascaded. One
|
|
211
|
-
* writer for the v4 tombstone sweep and the ingest-time twin removal (ALI-829).
|
|
212
|
-
*/
|
|
213
|
-
function deleteDecisionWithDependents(db, id) {
|
|
214
|
-
db.prepare('DELETE FROM decision_links WHERE source_id = ? OR target_id = ?').run(id, id);
|
|
215
|
-
db.prepare('DELETE FROM decision_refs WHERE decision_id = ?').run(id);
|
|
216
|
-
db.prepare('DELETE FROM decision_embeddings WHERE decision_id = ?').run(id);
|
|
217
|
-
db.prepare('DELETE FROM decision_audit WHERE decision_id = ?').run(id);
|
|
218
|
-
db.prepare('DELETE FROM decisions WHERE id = ?').run(id);
|
|
219
|
-
}
|
|
220
|
-
function migrate(db) {
|
|
221
|
-
const version = db.prepare('PRAGMA user_version').get().user_version;
|
|
222
|
-
if (version < 1) {
|
|
223
|
-
db.exec(`UPDATE decision_links SET relation = 'relates' WHERE relation = 'conflicts_with'`);
|
|
224
|
-
}
|
|
225
|
-
if (version < 2) {
|
|
226
|
-
// IMMEDIATE, not the default DEFERRED: this transaction reads (the survivor scan) before it
|
|
227
|
-
// writes, and under WAL another writer arriving in between makes the first write fail with
|
|
228
|
-
// SQLITE_BUSY_SNAPSHOT, which busy_timeout does not retry. Every local command opens the DB
|
|
229
|
-
// and the advisory hook fires on every agent edit, so a concurrent open is the normal case.
|
|
230
|
-
db.exec('BEGIN IMMEDIATE');
|
|
231
|
-
try {
|
|
232
|
-
// The survivor is the row inserted FIRST. `rowid` rather than `id` breaks a created_at
|
|
233
|
-
// tie: created_at has one-second granularity so rows written in one import tie routinely,
|
|
234
|
-
// and ordering by a random UUID would keep an arbitrary one while this comment claimed to
|
|
235
|
-
// keep the long-standing id. rowid is insertion order (the table is not WITHOUT ROWID).
|
|
236
|
-
//
|
|
237
|
-
// Keyed on (source_url, title), not source_url alone. Some fetchers emit a CONSTANT
|
|
238
|
-
// source_url when the per-item link is missing - connector-core's Teams fallback is
|
|
239
|
-
// literally 'https://teams.microsoft.com' - and collapsing on the URL alone deleted every
|
|
240
|
-
// such message but one. Two rows sharing a URL AND a title are duplicates by any reading;
|
|
241
|
-
// two sharing only the URL are not.
|
|
242
|
-
db.exec(`
|
|
243
|
-
CREATE TEMP TABLE dedup_survivor AS
|
|
244
|
-
SELECT source_url, title, id FROM (
|
|
245
|
-
SELECT source_url, title, id,
|
|
246
|
-
ROW_NUMBER() OVER (PARTITION BY source_url, title ORDER BY created_at, rowid) AS rn
|
|
247
|
-
FROM decisions WHERE source_url IS NOT NULL
|
|
248
|
-
) WHERE rn = 1;
|
|
249
|
-
|
|
250
|
-
CREATE TEMP TABLE dedup_dropped AS
|
|
251
|
-
SELECT d.id AS id, s.id AS survivor_id
|
|
252
|
-
FROM decisions d JOIN dedup_survivor s
|
|
253
|
-
ON d.source_url = s.source_url AND d.title = s.title
|
|
254
|
-
WHERE d.id <> s.id;
|
|
255
|
-
`);
|
|
256
|
-
// Repoint edges rather than dropping them: an edge naming a duplicate is a real edge that
|
|
257
|
-
// happened to name the copy. Dropping it would lose a relationship the user earned.
|
|
258
|
-
db.exec(`
|
|
259
|
-
UPDATE decision_links SET source_id = (
|
|
260
|
-
SELECT survivor_id FROM dedup_dropped WHERE id = decision_links.source_id
|
|
261
|
-
) WHERE source_id IN (SELECT id FROM dedup_dropped);
|
|
262
|
-
UPDATE decision_links SET target_id = (
|
|
263
|
-
SELECT survivor_id FROM dedup_dropped WHERE id = decision_links.target_id
|
|
264
|
-
) WHERE target_id IN (SELECT id FROM dedup_dropped);
|
|
265
|
-
`);
|
|
266
|
-
// Both cleanups are scoped to the pairs repointing actually touched. An earlier version
|
|
267
|
-
// deduplicated decision_links table-wide, which deleted user-earned edges that had nothing
|
|
268
|
-
// to do with duplication - and kept the lowest UUID rather than the highest confidence.
|
|
269
|
-
db.exec(`
|
|
270
|
-
DELETE FROM decision_links
|
|
271
|
-
WHERE source_id = target_id
|
|
272
|
-
AND (source_id IN (SELECT survivor_id FROM dedup_dropped)
|
|
273
|
-
OR target_id IN (SELECT survivor_id FROM dedup_dropped));
|
|
274
|
-
`);
|
|
275
|
-
// Explicitly, not by CASCADE: SQLite leaves foreign_keys OFF unless asked, so the
|
|
276
|
-
// ON DELETE CASCADE in the schema does not fire and these would be orphaned.
|
|
277
|
-
db.exec(`DELETE FROM decision_embeddings WHERE decision_id IN (SELECT id FROM dedup_dropped)`);
|
|
278
|
-
db.exec(`DELETE FROM decisions WHERE id IN (SELECT id FROM dedup_dropped)`);
|
|
279
|
-
db.exec(`DROP TABLE dedup_dropped; DROP TABLE dedup_survivor;`);
|
|
280
|
-
// Created here rather than in SCHEMA on purpose: SCHEMA runs before this function, so on
|
|
281
|
-
// any already-duplicated graph the index would fail to build before the collapse could
|
|
282
|
-
// run. A fresh database passes through the same path with nothing to collapse.
|
|
283
|
-
//
|
|
284
|
-
// A distinct name from any previous attempt, because IF NOT EXISTS matches on the NAME
|
|
285
|
-
// only: an index of the same name with different columns would be silently kept, and
|
|
286
|
-
// every later insert would then fail with "ON CONFLICT clause does not match".
|
|
287
|
-
db.exec(`CREATE UNIQUE INDEX IF NOT EXISTS decisions_source_title_unique ON decisions(source_url, title)`);
|
|
288
|
-
// Same story for edges: insertLink's `OR IGNORE` was decorative without a unique index, so
|
|
289
|
-
// a re-import stacked an identical relates row every time. Collapse, then constrain.
|
|
290
|
-
//
|
|
291
|
-
// This one IS table-wide, unavoidably: the index cannot be created while any duplicate
|
|
292
|
-
// triple remains anywhere. Every row it removes duplicates another by definition - same
|
|
293
|
-
// source, same target, same relation. It keeps the HIGHEST confidence rather than the
|
|
294
|
-
// lowest uuid, so the survivor is the best score rather than an arbitrary one.
|
|
295
|
-
db.exec(`
|
|
296
|
-
DELETE FROM decision_links WHERE id NOT IN (
|
|
297
|
-
SELECT id FROM (
|
|
298
|
-
SELECT id, ROW_NUMBER() OVER (
|
|
299
|
-
PARTITION BY source_id, target_id, relation ORDER BY confidence DESC, rowid
|
|
300
|
-
) AS rn FROM decision_links
|
|
301
|
-
) WHERE rn = 1
|
|
302
|
-
);
|
|
303
|
-
`);
|
|
304
|
-
db.exec(`CREATE UNIQUE INDEX IF NOT EXISTS decision_links_triple_unique ON decision_links(source_id, target_id, relation)`);
|
|
305
|
-
// Stamped INSIDE the transaction. Outside it, a process killed between COMMIT and the
|
|
306
|
-
// pragma replays the version-1 relabel on the next open, which turns an adjudicated
|
|
307
|
-
// conflicts_with edge into relates - the exact silent loss the docstring above warns of.
|
|
308
|
-
//
|
|
309
|
-
// Stamps this step's OWN number (2), not SCHEMA_VERSION: a later step (3, below) runs
|
|
310
|
-
// after this one commits, and if a crash lands between the two, `user_version` must
|
|
311
|
-
// still read 2 so the version-3 step is not skipped on the next open.
|
|
312
|
-
db.exec('PRAGMA user_version = 2');
|
|
313
|
-
db.exec('COMMIT');
|
|
314
|
-
}
|
|
315
|
-
catch (err) {
|
|
316
|
-
// Guarded: SQLITE_FULL, IOERR, BUSY, NOMEM and INTERRUPT auto-roll-back, and an
|
|
317
|
-
// unconditional ROLLBACK then throws "no transaction is active" and buries the real
|
|
318
|
-
// cause - so a user whose disk filled mid-migration would be told the wrong thing.
|
|
319
|
-
if (db.isTransaction)
|
|
320
|
-
db.exec('ROLLBACK');
|
|
321
|
-
throw err;
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
if (version < 3) {
|
|
325
|
-
// The column may already exist: a brand-new database's CREATE TABLE (SCHEMA, above)
|
|
326
|
-
// declares `repo` directly, so on a fresh install this ALTER would fail with "duplicate
|
|
327
|
-
// column name" if run unconditionally. A legacy database predates the column entirely.
|
|
328
|
-
const hasRepoColumn = db.prepare('PRAGMA table_info(decisions)').all()
|
|
329
|
-
.some((c) => c.name === 'repo');
|
|
330
|
-
if (!hasRepoColumn) {
|
|
331
|
-
db.exec('ALTER TABLE decisions ADD COLUMN repo TEXT');
|
|
332
|
-
}
|
|
333
|
-
// Backfill every row with no repo yet. JS-side because SQLite has no regex function to
|
|
334
|
-
// apply `repoFromSourceUrl`'s pattern in SQL - and it must be the SAME function the
|
|
335
|
-
// importer stamps new rows with, or a backfilled row and a freshly-imported one for the
|
|
336
|
-
// same URL could disagree about which repo they belong to.
|
|
337
|
-
const rows = db.prepare('SELECT id, source_url FROM decisions WHERE repo IS NULL')
|
|
338
|
-
.all();
|
|
339
|
-
if (rows.length) {
|
|
340
|
-
db.exec('BEGIN IMMEDIATE');
|
|
341
|
-
try {
|
|
342
|
-
const update = db.prepare('UPDATE decisions SET repo = ? WHERE id = ?');
|
|
343
|
-
for (const row of rows) {
|
|
344
|
-
const repo = repoFromSourceUrl(row.source_url);
|
|
345
|
-
// Only WRITE when a repo was found: leaving a non-code row NULL is the correct
|
|
346
|
-
// outcome (unattributed, not "wrong"), and writing NULL over NULL is a no-op
|
|
347
|
-
// this loop can just skip.
|
|
348
|
-
if (repo)
|
|
349
|
-
update.run(repo, row.id);
|
|
350
|
-
}
|
|
351
|
-
db.exec('PRAGMA user_version = 3');
|
|
352
|
-
db.exec('COMMIT');
|
|
353
|
-
}
|
|
354
|
-
catch (err) {
|
|
355
|
-
if (db.isTransaction)
|
|
356
|
-
db.exec('ROLLBACK');
|
|
357
|
-
throw err;
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
else {
|
|
361
|
-
db.exec('PRAGMA user_version = 3');
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
if (version < 4) {
|
|
365
|
-
db.exec('BEGIN IMMEDIATE');
|
|
366
|
-
try {
|
|
367
|
-
// Same shape as the `repo` step: a fresh database's CREATE TABLE already declares the
|
|
368
|
-
// column, and a legacy one predates it, so the ALTER is conditional. Checked INSIDE
|
|
369
|
-
// the write lock, unlike step 3: two processes opening a v3 file at once (the
|
|
370
|
-
// advisory hook is the normal concurrent case) could otherwise both read "no column"
|
|
371
|
-
// and the second would die on "duplicate column name". SQLite DDL is transactional.
|
|
372
|
-
const hasDecidedAt = db.prepare('PRAGMA table_info(decisions)').all()
|
|
373
|
-
.some((c) => c.name === 'decided_at');
|
|
374
|
-
if (!hasDecidedAt) {
|
|
375
|
-
db.exec('ALTER TABLE decisions ADD COLUMN decided_at TEXT');
|
|
376
|
-
}
|
|
377
|
-
const tombstones = db.prepare(`SELECT id FROM decisions WHERE platform = 'slack' AND title = ?`).all(SLACK_TOMBSTONE_TITLE);
|
|
378
|
-
for (const { id } of tombstones)
|
|
379
|
-
deleteDecisionWithDependents(db, id);
|
|
380
|
-
// Stamped inside the transaction, for the reason step 2 gives.
|
|
381
|
-
db.exec('PRAGMA user_version = 4');
|
|
382
|
-
db.exec('COMMIT');
|
|
383
|
-
}
|
|
384
|
-
catch (err) {
|
|
385
|
-
if (db.isTransaction)
|
|
386
|
-
db.exec('ROLLBACK');
|
|
387
|
-
throw err;
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
if (version < 5) {
|
|
391
|
-
// Inside the write lock, for the reason step 4 gives: two concurrent opens of a v4
|
|
392
|
-
// file must not both read "no column" and race the ALTER.
|
|
393
|
-
db.exec('BEGIN IMMEDIATE');
|
|
394
|
-
try {
|
|
395
|
-
const existing = new Set(db.prepare('PRAGMA table_info(decisions)').all().map((c) => c.name));
|
|
396
|
-
for (const column of PROVENANCE_COLUMNS) {
|
|
397
|
-
if (!existing.has(column))
|
|
398
|
-
db.exec(`ALTER TABLE decisions ADD COLUMN ${column} TEXT`);
|
|
399
|
-
}
|
|
400
|
-
db.exec('PRAGMA user_version = 5');
|
|
401
|
-
db.exec('COMMIT');
|
|
402
|
-
}
|
|
403
|
-
catch (err) {
|
|
404
|
-
if (db.isTransaction)
|
|
405
|
-
db.exec('ROLLBACK');
|
|
406
|
-
throw err;
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
if (version < 6) {
|
|
410
|
-
// Inside the write lock, for the reason step 4/5 give: two concurrent opens of a v5
|
|
411
|
-
// file must not both read "no column" and race the ALTER.
|
|
412
|
-
db.exec('BEGIN IMMEDIATE');
|
|
413
|
-
try {
|
|
414
|
-
const hasModel = db.prepare('PRAGMA table_info(decision_embeddings)').all()
|
|
415
|
-
.some((c) => c.name === 'model');
|
|
416
|
-
if (!hasModel) {
|
|
417
|
-
db.exec('ALTER TABLE decision_embeddings ADD COLUMN model TEXT');
|
|
418
|
-
}
|
|
419
|
-
// Every row that predates the column was written by LEGACY_EMBEDDING_MODEL - see its
|
|
420
|
-
// doc comment for how that is verified rather than assumed. Only rows with no tag yet
|
|
421
|
-
// are touched, so re-running this on an already-migrated database is a no-op.
|
|
422
|
-
db.prepare('UPDATE decision_embeddings SET model = ? WHERE model IS NULL').run(LEGACY_EMBEDDING_MODEL);
|
|
423
|
-
db.exec('PRAGMA user_version = 6');
|
|
424
|
-
db.exec('COMMIT');
|
|
425
|
-
}
|
|
426
|
-
catch (err) {
|
|
427
|
-
if (db.isTransaction)
|
|
428
|
-
db.exec('ROLLBACK');
|
|
429
|
-
throw err;
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
if (version < SCHEMA_VERSION) {
|
|
433
|
-
db.exec(`PRAGMA user_version = ${SCHEMA_VERSION}`);
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
82
|
/** Every column a DecisionRow carries, aliased to its camelCase name. One writer, read by
|
|
437
83
|
* both row readers, so a new column cannot be added to one SELECT and missed by the other. */
|
|
438
84
|
const DECISION_COLUMNS = 'id, title, summary, source_url as sourceUrl, platform, created_at as createdAt, repo, decided_at as decidedAt, ' +
|
|
439
85
|
'decider_kind as deciderKind, confirmed_by as confirmedBy, confirmed_at as confirmedAt, ' +
|
|
440
86
|
'ratified_by as ratifiedBy, ratified_at as ratifiedAt';
|
|
87
|
+
/** A person's ratification or confirmation covers the text they read (review finding 4). */
|
|
88
|
+
const ATTESTED = 'decisions.ratified_at IS NOT NULL OR decisions.confirmed_at IS NOT NULL';
|
|
441
89
|
export function createLocalDb(dbPath) {
|
|
442
90
|
// SQLite creates the DB file but not its parent directory, so on a clean machine
|
|
443
91
|
// (~/.config/align-cli absent) `align setup --local` crashed with "unable to open
|
|
@@ -448,17 +96,29 @@ export function createLocalDb(dbPath) {
|
|
|
448
96
|
mkdirSync(dirname(dbPath), { recursive: true });
|
|
449
97
|
}
|
|
450
98
|
const db = new DatabaseSync(dbPath);
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
99
|
+
// 30s: the longest measured v7 migration (100k rows, 33k merges) takes about 5s, so a waiting
|
|
100
|
+
// opener outlasts it with margin. First, before anything that needs a lock: every local command and the advisory hook open
|
|
101
|
+
// this file, so a concurrent opener is normal, and without a timeout it fails at once with
|
|
102
|
+
// "database is locked" instead of waiting for the migration in progress.
|
|
103
|
+
db.exec('PRAGMA busy_timeout = 30000');
|
|
104
|
+
try {
|
|
105
|
+
db.exec('PRAGMA journal_mode = WAL');
|
|
106
|
+
db.exec(SCHEMA);
|
|
107
|
+
migrate(db);
|
|
108
|
+
}
|
|
109
|
+
catch (err) {
|
|
110
|
+
db.close();
|
|
111
|
+
throw err;
|
|
112
|
+
}
|
|
454
113
|
// Shared by insertLink and resolveRefs (ALI-796), so there is one writer of the
|
|
455
114
|
// decision_links insert rather than two copies of the same ON CONFLICT clause.
|
|
456
115
|
function insertLinkRow(link) {
|
|
457
116
|
db.prepare(`INSERT INTO decision_links (id, source_id, target_id, relation, confidence) VALUES (?, ?, ?, ?, ?)
|
|
458
117
|
ON CONFLICT(source_id, target_id, relation)
|
|
459
|
-
DO UPDATE SET confidence = MAX(confidence, excluded.confidence)`).run(randomUUID(), link.sourceId, link.targetId, link.relation, link.confidence);
|
|
118
|
+
DO UPDATE SET confidence = MAX(confidence, excluded.confidence)`).run(link.id ?? randomUUID(), link.sourceId, link.targetId, link.relation, link.confidence);
|
|
460
119
|
}
|
|
461
|
-
|
|
120
|
+
let dataVersionStmt;
|
|
121
|
+
const api = {
|
|
462
122
|
/**
|
|
463
123
|
* Insert, or refresh the decision that already carries this `source_url`, returning the id
|
|
464
124
|
* that now holds it.
|
|
@@ -484,15 +144,39 @@ export function createLocalDb(dbPath) {
|
|
|
484
144
|
* change which repo it points at between imports.
|
|
485
145
|
*/
|
|
486
146
|
insertDecision(row) {
|
|
487
|
-
|
|
147
|
+
// L2: a one-item-per-URL connector item upserts on its source_key, and that branch takes
|
|
148
|
+
// the new title, so an edited PR title updates the row instead of adding a twin. Every
|
|
149
|
+
// other row (sessions, captures, docs) keeps the (source_url, title) identity.
|
|
150
|
+
//
|
|
151
|
+
// Both branches clear enriched_at: the row's text may have changed, so its links are not
|
|
152
|
+
// known to be current until ingestOne's link pass marks it again (Decision 30).
|
|
153
|
+
const sourceUrl = identifyingSourceUrl(row.sourceUrl);
|
|
154
|
+
const key = (row.keyed ? connectorItemKey(row.platform, sourceUrl) : undefined) ?? null;
|
|
155
|
+
api.foldPendingTwin(sourceUrl, row.title, row.platform, row.keyed);
|
|
156
|
+
const inserted = db.prepare(`INSERT INTO decisions (id, title, summary, source_url, platform, repo, decided_at, decider_kind, source_key, detail_pending) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
157
|
+
ON CONFLICT(source_key) WHERE source_key IS NOT NULL DO UPDATE SET
|
|
158
|
+
title = CASE WHEN ${ATTESTED} THEN decisions.title ELSE excluded.title END,
|
|
159
|
+
summary = CASE WHEN ${ATTESTED} THEN decisions.summary ELSE excluded.summary END,
|
|
160
|
+
platform = excluded.platform,
|
|
161
|
+
repo = COALESCE(excluded.repo, decisions.repo),
|
|
162
|
+
decided_at = COALESCE(excluded.decided_at, decisions.decided_at),
|
|
163
|
+
-- An attested row keeps its text, so it keeps the flag that describes that text (review 8).
|
|
164
|
+
-- A thin arrival whose body IS the stored body (ingestOne passed the stored text on
|
|
165
|
+
-- because the stored one is richer) must not turn a complete row pending again.
|
|
166
|
+
detail_pending = CASE
|
|
167
|
+
WHEN ${ATTESTED} THEN decisions.detail_pending
|
|
168
|
+
WHEN excluded.detail_pending = 1 AND decisions.detail_pending = 0 AND excluded.summary = decisions.summary THEN 0
|
|
169
|
+
ELSE excluded.detail_pending END,
|
|
170
|
+
enriched_at = CASE WHEN ${ATTESTED} THEN decisions.enriched_at ELSE NULL END
|
|
488
171
|
ON CONFLICT(source_url, title) DO UPDATE SET
|
|
489
172
|
summary = excluded.summary, platform = excluded.platform,
|
|
490
173
|
repo = COALESCE(excluded.repo, decisions.repo),
|
|
491
|
-
decided_at = COALESCE(excluded.decided_at, decisions.decided_at)
|
|
492
|
-
|
|
174
|
+
decided_at = COALESCE(excluded.decided_at, decisions.decided_at),
|
|
175
|
+
enriched_at = NULL
|
|
176
|
+
RETURNING id`).get(randomUUID(), row.title, row.summary, sourceUrl, row.platform, row.repo ?? null,
|
|
493
177
|
// `||`, not `??`: COALESCE('', old) is '', so an empty string would blank a stored
|
|
494
178
|
// date. Callers normalise, but this is the one place the column is written.
|
|
495
|
-
row.decidedAt || null, row.deciderKind ?? null);
|
|
179
|
+
row.decidedAt || null, row.deciderKind ?? null, key, row.detailPending ? 1 : 0);
|
|
496
180
|
return inserted.id;
|
|
497
181
|
},
|
|
498
182
|
/**
|
|
@@ -519,13 +203,95 @@ export function createLocalDb(dbPath) {
|
|
|
519
203
|
* A null `sourceUrl` is always null here: SQLite treats each NULL in a unique index as
|
|
520
204
|
* distinct, so those rows never conflict and every one of them really is new.
|
|
521
205
|
*/
|
|
522
|
-
findIdBySource(sourceUrl, title) {
|
|
206
|
+
findIdBySource(sourceUrl, title, platform, keyed) {
|
|
523
207
|
const identity = identifyingSourceUrl(sourceUrl);
|
|
524
208
|
if (identity === null)
|
|
525
209
|
return null;
|
|
210
|
+
// L2: with the platform, a one-item-per-URL item is found by its source_key, so a retitled
|
|
211
|
+
// PR is recognised as the row insertDecision is about to update, not as a new one.
|
|
212
|
+
const key = platform === undefined || !keyed ? undefined : connectorItemKey(platform, identity);
|
|
213
|
+
if (key !== undefined) {
|
|
214
|
+
const byKey = db.prepare(`SELECT id FROM decisions WHERE source_key = ?`).get(key);
|
|
215
|
+
if (byKey)
|
|
216
|
+
return byKey.id;
|
|
217
|
+
}
|
|
526
218
|
const row = db.prepare(`SELECT id FROM decisions WHERE source_url = ? AND title = ?`).get(identity, title);
|
|
527
219
|
return row?.id ?? null;
|
|
528
220
|
},
|
|
221
|
+
/**
|
|
222
|
+
* Review finding 4: what a keyed re-import may write over row `id`. A ratified or confirmed
|
|
223
|
+
* row keeps the text a person attested; the incoming text is recorded once as a
|
|
224
|
+
* `text_revision_pending` audit note and the stored text is returned. Any other row (or an
|
|
225
|
+
* unknown id) gets the incoming text back unchanged.
|
|
226
|
+
*/
|
|
227
|
+
keepProtectedText(id, title, summary, thin = false) {
|
|
228
|
+
const row = db.prepare(`SELECT title, summary, detail_pending, ratified_at, confirmed_at FROM decisions WHERE id = ?`).get(id);
|
|
229
|
+
if (row && row.ratified_at === null && row.confirmed_at === null && thin && row.detail_pending === 0) {
|
|
230
|
+
// L3: `thin` is an items-first arrival (discussion not fetched). The stored row is complete
|
|
231
|
+
// and has a discussion block: keep the BLOCK and take everything else from the arrival
|
|
232
|
+
// (title, body, Status, Repo), so a merge, a rename or an edit still lands. The result
|
|
233
|
+
// equals the stored text when nothing changed, which makes the caller's unchanged-skip fire.
|
|
234
|
+
const keep = discussionStart(row.summary);
|
|
235
|
+
if (keep !== -1 && discussionStart(summary) === -1) {
|
|
236
|
+
return { title, summary: summary + row.summary.slice(keep), keptDiscussion: true };
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
if (!row || (row.ratified_at === null && row.confirmed_at === null))
|
|
240
|
+
return { title, summary };
|
|
241
|
+
if (row.title !== title || row.summary !== summary) {
|
|
242
|
+
const detail = JSON.stringify({ title, summary });
|
|
243
|
+
const seen = db.prepare(`SELECT 1 AS hit FROM decision_audit WHERE decision_id = ? AND action = 'text_revision_pending' AND detail = ?`).get(id, detail);
|
|
244
|
+
if (!seen) {
|
|
245
|
+
api.insertAudit({ decisionId: id, action: 'text_revision_pending', actor: null, detail });
|
|
246
|
+
// Bounded: an upstream that changes every sync would otherwise add a row per sync.
|
|
247
|
+
db.prepare(`DELETE FROM decision_audit WHERE decision_id = ? AND action = 'text_revision_pending' AND rowid NOT IN
|
|
248
|
+
(SELECT rowid FROM decision_audit WHERE decision_id = ? AND action = 'text_revision_pending' ORDER BY rowid DESC LIMIT 5)`).run(id, id);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
return { title: row.title, summary: row.summary };
|
|
252
|
+
},
|
|
253
|
+
/** The id of the connector-imported item `url` names, under any platform, or null. A capture
|
|
254
|
+
* of that URL must not rewrite the imported text (L2 review finding 1). */
|
|
255
|
+
findKeyedIdByUrl(url) {
|
|
256
|
+
const identity = identifyingSourceUrl(url);
|
|
257
|
+
if (identity === null)
|
|
258
|
+
return null;
|
|
259
|
+
for (const platform of KEYED_PLATFORMS) {
|
|
260
|
+
const key = connectorItemKey(platform, identity);
|
|
261
|
+
const hit = key === undefined ? undefined : db.prepare(`SELECT id FROM decisions WHERE source_key = ?`).get(key);
|
|
262
|
+
if (hit)
|
|
263
|
+
return hit.id;
|
|
264
|
+
}
|
|
265
|
+
return null;
|
|
266
|
+
},
|
|
267
|
+
/**
|
|
268
|
+
* A keyless row at this (source_url, title) is a twin an older binary wrote beside the keyed
|
|
269
|
+
* one. Adopt it as the keyed row, or fold it with the row that already holds the key (the
|
|
270
|
+
* attested one survives). ingestOne calls this BEFORE it looks the item up, so the text it
|
|
271
|
+
* protects and embeds is the survivor's. No-op for an unkeyed call.
|
|
272
|
+
*/
|
|
273
|
+
foldPendingTwin(sourceUrl, title, platform, keyed) {
|
|
274
|
+
const key = keyed ? connectorItemKey(platform, sourceUrl) : undefined;
|
|
275
|
+
if (key === undefined)
|
|
276
|
+
return;
|
|
277
|
+
const twin = db.prepare(`SELECT id FROM decisions WHERE source_url = ? AND title = ? AND source_key IS NULL`).get(sourceUrl, title);
|
|
278
|
+
if (!twin)
|
|
279
|
+
return;
|
|
280
|
+
const holder = db.prepare(`SELECT id FROM decisions WHERE source_key = ?`).get(key);
|
|
281
|
+
if (holder)
|
|
282
|
+
foldKeylessTwin(db, twin.id, holder.id, key);
|
|
283
|
+
else
|
|
284
|
+
db.prepare(`UPDATE decisions SET source_key = ? WHERE id = ?`).run(key, twin.id);
|
|
285
|
+
},
|
|
286
|
+
/** A capture of a URL a connector already imported: audit it, change nothing, return the row. */
|
|
287
|
+
noteCaptureOfHeldItem(url) {
|
|
288
|
+
const id = api.findKeyedIdByUrl(url);
|
|
289
|
+
const row = id === null ? null : api.getDecisionById(id);
|
|
290
|
+
const today = id === null ? undefined : db.prepare(`SELECT 1 AS hit FROM decision_audit WHERE decision_id = ? AND action = 'capture_seen' AND date(created_at) = date('now')`).get(id);
|
|
291
|
+
if (row && !today)
|
|
292
|
+
api.insertAudit({ decisionId: row.id, action: 'capture_seen', actor: null, detail: url });
|
|
293
|
+
return row;
|
|
294
|
+
},
|
|
529
295
|
/**
|
|
530
296
|
* `filter.repo` scopes to one repo's rows. `includeUnattributed` (ALI-798's own rule:
|
|
531
297
|
* "repo = ? OR repo IS NULL") also returns rows with no repo at all - a Jira ticket, a
|
|
@@ -585,6 +351,19 @@ export function createLocalDb(dbPath) {
|
|
|
585
351
|
RETURNING confirmed_at AS confirmedAt`).get(confirmedBy, confirmedAt, id);
|
|
586
352
|
return row ?? null;
|
|
587
353
|
},
|
|
354
|
+
/**
|
|
355
|
+
* L2, Decision 30: the decision's ingest finished, link pass included. ingestOne is the one
|
|
356
|
+
* caller, and calls it as its last write; insertDecision clears it whenever it rewrites the
|
|
357
|
+
* row. NULL therefore means "links not known to be current", and the unchanged-skip will
|
|
358
|
+
* not skip such a row.
|
|
359
|
+
*/
|
|
360
|
+
markEnriched(id) {
|
|
361
|
+
db.prepare(`UPDATE decisions SET enriched_at = ? WHERE id = ?`).run(new Date().toISOString(), id);
|
|
362
|
+
},
|
|
363
|
+
getEnrichedAt(id) {
|
|
364
|
+
const row = db.prepare(`SELECT enriched_at AS e FROM decisions WHERE id = ?`).get(id);
|
|
365
|
+
return row?.e ?? null;
|
|
366
|
+
},
|
|
588
367
|
/** ALI-831: one row per human act on a decision (ratified, pushed), so "who stood behind
|
|
589
368
|
* this, and when" is answerable after the fact. Append-only by construction. */
|
|
590
369
|
insertAudit(entry) {
|
|
@@ -656,6 +435,10 @@ export function createLocalDb(dbPath) {
|
|
|
656
435
|
* (local-gateway-client.ts's ingestOne) always passes EMBEDDING_MODEL_ID.
|
|
657
436
|
*/
|
|
658
437
|
setEmbedding(decisionId, embedding, model) {
|
|
438
|
+
// Replacing a vector changes what a copy of the embeddings should hold; a first write
|
|
439
|
+
// only adds a row, which the writer appends itself. (rowSetEpoch's contract.)
|
|
440
|
+
if (db.prepare('SELECT 1 FROM decision_embeddings WHERE decision_id = ?').get(decisionId))
|
|
441
|
+
bumpRowSetEpoch(db);
|
|
659
442
|
db.prepare(`INSERT OR REPLACE INTO decision_embeddings (decision_id, embedding, model) VALUES (?, ?, ?)`).run(decisionId, Buffer.from(embedding.buffer, embedding.byteOffset, embedding.byteLength), model ?? null);
|
|
660
443
|
},
|
|
661
444
|
getEmbedding(decisionId) {
|
|
@@ -746,6 +529,16 @@ export function createLocalDb(dbPath) {
|
|
|
746
529
|
insertLink(link) {
|
|
747
530
|
insertLinkRow(link);
|
|
748
531
|
},
|
|
532
|
+
/**
|
|
533
|
+
* LM: the ONE way a link is deleted on behalf of a person's mark. `align mark <a> replaces <b>`
|
|
534
|
+
* writes its supersedes link under the id `mark:<judgement id>` (when the classifier had not
|
|
535
|
+
* already written that edge, in which case the edge keeps its own id and is not ours), and
|
|
536
|
+
* `--undo` removes exactly that row here. The id is built inside this method, so no caller can
|
|
537
|
+
* name another link: a classifier edge, or a link another mark owns, cannot be reached from here.
|
|
538
|
+
*/
|
|
539
|
+
deleteMarkLink(judgementId) {
|
|
540
|
+
return Number(db.prepare(`DELETE FROM decision_links WHERE id = ? AND relation = 'supersedes'`).run(`mark:${judgementId}`).changes);
|
|
541
|
+
},
|
|
749
542
|
/**
|
|
750
543
|
* ALI-1065: a pair gets ONE edge, never two. `insertLinkRow`'s unique index is on
|
|
751
544
|
* (source_id, target_id, relation), so writing `supersedes` for a pair that already
|
|
@@ -755,7 +548,10 @@ export function createLocalDb(dbPath) {
|
|
|
755
548
|
* classification can upgrade a cosine `relates` edge into a typed one atomically.
|
|
756
549
|
*/
|
|
757
550
|
replaceLink(link) {
|
|
758
|
-
|
|
551
|
+
// LM: an edge a person's `align mark ... replaces` wrote (id `mark:<judgement id>`) is theirs, not
|
|
552
|
+
// the classifier's to upgrade away: deleting it would orphan the judgement, and `--undo` could
|
|
553
|
+
// no longer find its link. The pair may then carry that edge beside the new one.
|
|
554
|
+
db.prepare(`DELETE FROM decision_links WHERE ((source_id = ? AND target_id = ?) OR (source_id = ? AND target_id = ?)) AND id NOT LIKE 'mark:%'`).run(link.sourceId, link.targetId, link.targetId, link.sourceId);
|
|
759
555
|
insertLinkRow(link);
|
|
760
556
|
},
|
|
761
557
|
/**
|
|
@@ -862,11 +658,30 @@ export function createLocalDb(dbPath) {
|
|
|
862
658
|
// decision_refs listed explicitly: SQLite leaves foreign_keys OFF unless asked,
|
|
863
659
|
// so the schema's ON DELETE CASCADE never fires (same fact the v2 migration
|
|
864
660
|
// documents above).
|
|
661
|
+
bumpRowSetEpoch(db);
|
|
865
662
|
db.exec(`DELETE FROM decision_refs; DELETE FROM decision_links; DELETE FROM decision_embeddings; DELETE FROM decisions;`);
|
|
866
663
|
},
|
|
664
|
+
/** Goes up whenever a decision is deleted or re-id'd or an embedding is deleted or replaced
|
|
665
|
+
* on this connection (see local-db-epoch.ts). A holder of a copy of the embeddings
|
|
666
|
+
* compares it to the value it built at. */
|
|
667
|
+
rowSetEpoch() {
|
|
668
|
+
return rowSetEpoch(db);
|
|
669
|
+
},
|
|
670
|
+
/** SQLite's data_version: changes when ANOTHER connection commits (another process, an
|
|
671
|
+
* MCP server, a second CLI), never for this connection's own writes. The cross-process
|
|
672
|
+
* half of "has the graph moved under my copy of it". */
|
|
673
|
+
dataVersion() {
|
|
674
|
+
return (dataVersionStmt ??= db.prepare('PRAGMA data_version')).get()['data_version'];
|
|
675
|
+
},
|
|
676
|
+
/** Stored embeddings of every model: an upper bound on what a matrix would hold, read
|
|
677
|
+
* before building one so a huge graph is never loaded just to be refused. */
|
|
678
|
+
countEmbeddings() {
|
|
679
|
+
return db.prepare('SELECT COUNT(*) AS n FROM decision_embeddings').get().n;
|
|
680
|
+
},
|
|
867
681
|
close() {
|
|
868
682
|
db.close();
|
|
869
683
|
},
|
|
870
684
|
};
|
|
685
|
+
return api;
|
|
871
686
|
}
|
|
872
687
|
//# sourceMappingURL=local-db.js.map
|