@aligndottech/cli 0.49.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 +4 -3
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +26 -8
- package/dist/cli.js.map +1 -1
- package/dist/commands/agents.d.ts.map +1 -1
- package/dist/commands/agents.js +4 -1
- package/dist/commands/agents.js.map +1 -1
- 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/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 +8 -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 +65 -50
- 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 +6 -1
- package/dist/commands/why.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- 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 +31 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +139 -0
- 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/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/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/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/agents.d.ts +2 -0
- package/dist/lib/launch/agents.d.ts.map +1 -1
- package/dist/lib/launch/agents.js +3 -1
- package/dist/lib/launch/agents.js.map +1 -1
- 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 +4 -0
- package/dist/lib/launch/config-writes.d.ts.map +1 -1
- package/dist/lib/launch/config-writes.js +8 -3
- 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 +3 -1
- package/dist/lib/launch/detect.js.map +1 -1
- 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/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 +17 -2
- package/dist/lib/launch/launch.d.ts.map +1 -1
- package/dist/lib/launch/launch.js +36 -3
- package/dist/lib/launch/launch.js.map +1 -1
- 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 +4 -4
- 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/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/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/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/index.d.ts +1 -1
- package/dist/lib/launch/registry/index.d.ts.map +1 -1
- package/dist/lib/launch/registry/index.js +7 -2
- package/dist/lib/launch/registry/index.js.map +1 -1
- package/dist/lib/launch/registry/types.d.ts +12 -1
- package/dist/lib/launch/registry/types.d.ts.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 +80 -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/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-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.map +1 -1
- package/dist/lib/safe-config-write.js +39 -2
- 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-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
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* L4: what a saved token can SEE, to offer as a choice or to check one against: Jira projects, Confluence spaces, Linear
|
|
3
|
+
* teams, whether a GitHub repo or GitLab project is visible at all.
|
|
4
|
+
*
|
|
5
|
+
* These run inside the CLI process with the token the person already saved. The token is sent only to the vendor's own host,
|
|
6
|
+
* built from the connector's stored fields and checked to be a plain hostname first (the SDK's addendum 1, applied here:
|
|
7
|
+
* a host never comes from a flag, a tool argument or a URL). Redirects are never followed with the credential. Results are
|
|
8
|
+
* keys and names. An error says what failed and never carries the token or a response body.
|
|
9
|
+
*
|
|
10
|
+
* Every function takes the `fetch` to use, so a test runs against scripted responses and nothing here touches a network
|
|
11
|
+
* it was not handed.
|
|
12
|
+
*/
|
|
13
|
+
export type FetchLike = typeof fetch;
|
|
14
|
+
export declare class ScopeLookupError extends Error {
|
|
15
|
+
readonly kind: 'auth' | 'unreachable' | 'unsupported';
|
|
16
|
+
constructor(message: string, kind: 'auth' | 'unreachable' | 'unsupported');
|
|
17
|
+
}
|
|
18
|
+
export type Visibility = 'visible' | 'invisible' | 'unknown';
|
|
19
|
+
export interface Listed<T> {
|
|
20
|
+
items: T[];
|
|
21
|
+
/** True when the vendor had more than was read. A key missing from a truncated list is NOT known to be invisible: look it up directly. */
|
|
22
|
+
truncated: boolean;
|
|
23
|
+
}
|
|
24
|
+
export declare function listJiraProjects(fields: Record<string, string>, f: FetchLike, o?: {
|
|
25
|
+
max?: number;
|
|
26
|
+
}): Promise<Listed<{
|
|
27
|
+
key: string;
|
|
28
|
+
name: string;
|
|
29
|
+
}>>;
|
|
30
|
+
export declare function listConfluenceSpaces(fields: Record<string, string>, f: FetchLike, o?: {
|
|
31
|
+
max?: number;
|
|
32
|
+
}): Promise<Listed<{
|
|
33
|
+
key: string;
|
|
34
|
+
name: string;
|
|
35
|
+
}>>;
|
|
36
|
+
type LinearTeam = {
|
|
37
|
+
id: string;
|
|
38
|
+
key: string;
|
|
39
|
+
name: string;
|
|
40
|
+
};
|
|
41
|
+
export declare function listLinearTeams(fields: Record<string, string>, f: FetchLike): Promise<Listed<LinearTeam>>;
|
|
42
|
+
/** One team by key, for a key a truncated list did not show. */
|
|
43
|
+
export declare function findLinearTeam(fields: Record<string, string>, key: string, f: FetchLike): Promise<LinearTeam | undefined>;
|
|
44
|
+
/** Is this one project visible? Asked directly, for a key a truncated list did not show. A refused token is an error, not "no". */
|
|
45
|
+
export declare function findJiraProject(fields: Record<string, string>, key: string, f: FetchLike): Promise<boolean>;
|
|
46
|
+
export declare function findConfluenceSpace(fields: Record<string, string>, key: string, f: FetchLike): Promise<boolean>;
|
|
47
|
+
/** Can this token search `repo:o/r`? P0 measured GitHub answering 422 "cannot be searched" for a private repo the token has no access to. */
|
|
48
|
+
export declare function githubRepoVisibility(token: string, repo: string, f: FetchLike): Promise<Visibility>;
|
|
49
|
+
export declare function gitlabProjectVisibility(fields: Record<string, string>, project: string, f: FetchLike): Promise<Visibility>;
|
|
50
|
+
export {};
|
|
51
|
+
//# sourceMappingURL=scope-choices.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope-choices.d.ts","sourceRoot":"","sources":["../../src/lib/scope-choices.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,SAAS,GAAG,OAAO,KAAK,CAAC;AAGrC,qBAAa,gBAAiB,SAAQ,KAAK;IACZ,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,aAAa;gBAAtE,OAAO,EAAE,MAAM,EAAW,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,aAAa;CAInF;AAED,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;AAuD7D,MAAM,WAAW,MAAM,CAAC,CAAC;IACvB,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,0IAA0I;IAC1I,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAkB7J;AAED,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,GAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAqBjK;AASD,KAAK,UAAU,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAW5D,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAK/G;AAED,gEAAgE;AAChE,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAK/H;AAED,mIAAmI;AACnI,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAQjH;AAED,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAIrH;AAYD,6IAA6I;AAC7I,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAQzG;AAED,wBAAsB,uBAAuB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAMhI"}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
export class ScopeLookupError extends Error {
|
|
2
|
+
kind;
|
|
3
|
+
constructor(message, kind) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.kind = kind;
|
|
6
|
+
this.name = 'ScopeLookupError';
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
const HOSTNAME = /^[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?(?:\.[A-Za-z0-9](?:[A-Za-z0-9-]{0,61}[A-Za-z0-9])?)+$/;
|
|
10
|
+
const TIMEOUT_MS = 10_000;
|
|
11
|
+
const MAX_LISTED = 1000;
|
|
12
|
+
/** A vendor cannot make this process read more than this much of one answer, or page through more than MAX_PAGES. */
|
|
13
|
+
const MAX_BODY_BYTES = 2_000_000;
|
|
14
|
+
const MAX_PAGES = 50;
|
|
15
|
+
async function readCapped(res, max) {
|
|
16
|
+
const reader = res.body?.getReader();
|
|
17
|
+
if (!reader)
|
|
18
|
+
return res.text();
|
|
19
|
+
const chunks = [];
|
|
20
|
+
let total = 0;
|
|
21
|
+
for (;;) {
|
|
22
|
+
const { done, value } = await reader.read();
|
|
23
|
+
if (done)
|
|
24
|
+
break;
|
|
25
|
+
total += value.byteLength;
|
|
26
|
+
if (total > max) {
|
|
27
|
+
await reader.cancel().catch(() => undefined);
|
|
28
|
+
throw new Error('too large');
|
|
29
|
+
}
|
|
30
|
+
chunks.push(value);
|
|
31
|
+
}
|
|
32
|
+
return Buffer.concat(chunks).toString('utf8');
|
|
33
|
+
}
|
|
34
|
+
function hostOf(vendor, domain) {
|
|
35
|
+
if (domain === undefined || !HOSTNAME.test(domain)) {
|
|
36
|
+
throw new ScopeLookupError(`The ${vendor} connection has no usable site saved, so its list cannot be read. Reconnect: align connect ${vendor.toLowerCase()}`, 'unsupported');
|
|
37
|
+
}
|
|
38
|
+
return domain;
|
|
39
|
+
}
|
|
40
|
+
async function get(vendor, url, headers, f, init = {}) {
|
|
41
|
+
let res;
|
|
42
|
+
try {
|
|
43
|
+
res = await f(url, { ...init, headers, redirect: 'manual', signal: AbortSignal.timeout(TIMEOUT_MS) });
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
throw new ScopeLookupError(`Could not reach ${vendor} to read the list.`, 'unreachable');
|
|
47
|
+
}
|
|
48
|
+
if (res.status === 401 || res.status === 403) {
|
|
49
|
+
throw new ScopeLookupError(`${vendor} refused the saved token. Reconnect: align connect ${vendor.toLowerCase()}`, 'auth');
|
|
50
|
+
}
|
|
51
|
+
if (!res.ok)
|
|
52
|
+
throw new ScopeLookupError(`${vendor} answered ${res.status} when reading the list.`, 'unreachable');
|
|
53
|
+
try {
|
|
54
|
+
return JSON.parse(await readCapped(res, MAX_BODY_BYTES));
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
throw new ScopeLookupError(`${vendor} sent a list this CLI could not read.`, 'unreachable');
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const asRecord = (v) => (typeof v === 'object' && v !== null ? v : {});
|
|
61
|
+
const text = (v) => (typeof v === 'string' && v !== '' ? v : undefined);
|
|
62
|
+
function atlassianHeaders(fields) {
|
|
63
|
+
const token = fields['token'];
|
|
64
|
+
const email = fields['email'];
|
|
65
|
+
if (!token || !email)
|
|
66
|
+
throw new ScopeLookupError('The Atlassian connection has no email saved, so its list cannot be read. Reconnect with: align connect <jira|confluence>', 'unsupported');
|
|
67
|
+
return { Authorization: `Basic ${Buffer.from(`${email}:${token}`).toString('base64')}`, Accept: 'application/json' };
|
|
68
|
+
}
|
|
69
|
+
export async function listJiraProjects(fields, f, o = {}) {
|
|
70
|
+
const max = o.max ?? MAX_LISTED;
|
|
71
|
+
const host = hostOf('Jira', fields['domain']);
|
|
72
|
+
const headers = atlassianHeaders(fields);
|
|
73
|
+
const items = [];
|
|
74
|
+
let truncated = false;
|
|
75
|
+
for (let startAt = 0; items.length < max;) {
|
|
76
|
+
const page = asRecord(await get('Jira', `https://${host}/rest/api/3/project/search?maxResults=100&startAt=${startAt}`, headers, f));
|
|
77
|
+
const values = Array.isArray(page['values']) ? page['values'] : [];
|
|
78
|
+
for (const v of values) {
|
|
79
|
+
const key = text(asRecord(v)['key']);
|
|
80
|
+
if (key !== undefined)
|
|
81
|
+
items.push({ key, name: text(asRecord(v)['name']) ?? key });
|
|
82
|
+
}
|
|
83
|
+
if (page['isLast'] !== false || values.length === 0)
|
|
84
|
+
break;
|
|
85
|
+
startAt += values.length;
|
|
86
|
+
if (items.length >= max)
|
|
87
|
+
truncated = true;
|
|
88
|
+
}
|
|
89
|
+
return { items, truncated };
|
|
90
|
+
}
|
|
91
|
+
export async function listConfluenceSpaces(fields, f, o = {}) {
|
|
92
|
+
const max = o.max ?? MAX_LISTED;
|
|
93
|
+
const host = hostOf('Confluence', fields['domain']);
|
|
94
|
+
const headers = atlassianHeaders(fields);
|
|
95
|
+
const base = `https://${host}`;
|
|
96
|
+
const items = [];
|
|
97
|
+
let truncated = false;
|
|
98
|
+
let next = '/wiki/api/v2/spaces?limit=250';
|
|
99
|
+
for (let pages = 0; next !== undefined; pages++) {
|
|
100
|
+
if (pages >= MAX_PAGES) {
|
|
101
|
+
truncated = true;
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
const page = asRecord(await get('Confluence', `${base}${next}`, headers, f));
|
|
105
|
+
for (const v of Array.isArray(page['results']) ? page['results'] : []) {
|
|
106
|
+
const key = text(asRecord(v)['key']);
|
|
107
|
+
if (key !== undefined)
|
|
108
|
+
items.push({ key, name: text(asRecord(v)['name']) ?? key });
|
|
109
|
+
}
|
|
110
|
+
// Only a path on the same site is followed: an absolute link elsewhere would carry the credential to another host.
|
|
111
|
+
const link = text(asRecord(page['_links'])['next']);
|
|
112
|
+
next = link !== undefined && link.startsWith('/') && !link.startsWith('//') ? link : undefined;
|
|
113
|
+
if (next !== undefined && items.length >= max) {
|
|
114
|
+
truncated = true;
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return { items, truncated };
|
|
119
|
+
}
|
|
120
|
+
function linearHeaders(fields) {
|
|
121
|
+
const token = fields['token'];
|
|
122
|
+
if (!token)
|
|
123
|
+
throw new ScopeLookupError('The Linear connection has no token saved. Reconnect: align connect linear', 'unsupported');
|
|
124
|
+
// A personal API key goes bare and an OAuth token as Bearer; Linear refuses the other way round with a 400 (connector-core).
|
|
125
|
+
return { Authorization: token.startsWith('lin_api_') ? token : `Bearer ${token}`, 'Content-Type': 'application/json' };
|
|
126
|
+
}
|
|
127
|
+
const toTeams = (nodes) => {
|
|
128
|
+
const out = [];
|
|
129
|
+
for (const n of Array.isArray(nodes) ? nodes : []) {
|
|
130
|
+
const id = text(asRecord(n)['id']);
|
|
131
|
+
const key = text(asRecord(n)['key']);
|
|
132
|
+
if (id !== undefined && key !== undefined)
|
|
133
|
+
out.push({ id, key, name: text(asRecord(n)['name']) ?? key });
|
|
134
|
+
}
|
|
135
|
+
return out;
|
|
136
|
+
};
|
|
137
|
+
export async function listLinearTeams(fields, f) {
|
|
138
|
+
const body = await get('Linear', 'https://api.linear.app/graphql', linearHeaders(fields), f, { method: 'POST', body: JSON.stringify({ query: 'query { teams(first: 100) { nodes { id key name } pageInfo { hasNextPage } } }' }) });
|
|
139
|
+
const teams = asRecord(asRecord(asRecord(body)['data'])['teams']);
|
|
140
|
+
if (!Array.isArray(teams['nodes']))
|
|
141
|
+
throw new ScopeLookupError('Linear did not return a team list.', 'unreachable');
|
|
142
|
+
return { items: toTeams(teams['nodes']), truncated: asRecord(teams['pageInfo'])['hasNextPage'] === true };
|
|
143
|
+
}
|
|
144
|
+
/** One team by key, for a key a truncated list did not show. */
|
|
145
|
+
export async function findLinearTeam(fields, key, f) {
|
|
146
|
+
// The key travels as a GraphQL variable, never spliced into the query text.
|
|
147
|
+
const query = 'query($key: String!) { teams(first: 1, filter: { key: { eq: $key } }) { nodes { id key name } } }';
|
|
148
|
+
const body = await get('Linear', 'https://api.linear.app/graphql', linearHeaders(fields), f, { method: 'POST', body: JSON.stringify({ query, variables: { key } }) });
|
|
149
|
+
return toTeams(asRecord(asRecord(asRecord(body)['data'])['teams'])['nodes'])[0];
|
|
150
|
+
}
|
|
151
|
+
/** Is this one project visible? Asked directly, for a key a truncated list did not show. A refused token is an error, not "no". */
|
|
152
|
+
export async function findJiraProject(fields, key, f) {
|
|
153
|
+
const host = hostOf('Jira', fields['domain']);
|
|
154
|
+
const headers = atlassianHeaders(fields);
|
|
155
|
+
const code = await status(`https://${host}/rest/api/3/project/${encodeURIComponent(key)}`, headers, f);
|
|
156
|
+
if (code === 200)
|
|
157
|
+
return true;
|
|
158
|
+
if (code === 404)
|
|
159
|
+
return false;
|
|
160
|
+
if (code === 401 || code === 403)
|
|
161
|
+
throw new ScopeLookupError('Jira refused the saved token. Reconnect: align connect jira', 'auth');
|
|
162
|
+
throw new ScopeLookupError(`Could not check a Jira project (Jira answered ${code ?? 'nothing'}).`, 'unreachable');
|
|
163
|
+
}
|
|
164
|
+
export async function findConfluenceSpace(fields, key, f) {
|
|
165
|
+
const host = hostOf('Confluence', fields['domain']);
|
|
166
|
+
const page = asRecord(await get('Confluence', `https://${host}/wiki/api/v2/spaces?keys=${encodeURIComponent(key)}&limit=1`, atlassianHeaders(fields), f));
|
|
167
|
+
return (Array.isArray(page['results']) ? page['results'] : []).some((v) => asRecord(v)['key'] === key);
|
|
168
|
+
}
|
|
169
|
+
async function status(url, headers, f) {
|
|
170
|
+
try {
|
|
171
|
+
return (await f(url, { headers, redirect: 'manual', signal: AbortSignal.timeout(TIMEOUT_MS) })).status;
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
return undefined;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
const REPO = /^[A-Za-z0-9_.-]{1,100}\/[A-Za-z0-9_.-]{1,100}$/;
|
|
178
|
+
/** Can this token search `repo:o/r`? P0 measured GitHub answering 422 "cannot be searched" for a private repo the token has no access to. */
|
|
179
|
+
export async function githubRepoVisibility(token, repo, f) {
|
|
180
|
+
if (!REPO.test(repo) || repo.split('/').some((seg) => /^\.+$/.test(seg)))
|
|
181
|
+
return 'unknown';
|
|
182
|
+
const code = await status(`https://api.github.com/search/issues?q=${encodeURIComponent(`repo:${repo}`)}&per_page=1`, { Authorization: `Bearer ${token}`, Accept: 'application/vnd.github+json', 'User-Agent': 'align-cli' }, f);
|
|
183
|
+
return code === 200 ? 'visible' : code === 422 ? 'invisible' : 'unknown';
|
|
184
|
+
}
|
|
185
|
+
export async function gitlabProjectVisibility(fields, project, f) {
|
|
186
|
+
const token = fields['token'];
|
|
187
|
+
const domain = fields['domain'] || 'gitlab.com';
|
|
188
|
+
if (!token || !HOSTNAME.test(domain))
|
|
189
|
+
return 'unknown';
|
|
190
|
+
const code = await status(`https://${domain}/api/v4/projects/${encodeURIComponent(project)}`, { Authorization: `Bearer ${token}` }, f);
|
|
191
|
+
return code === 200 ? 'visible' : code === 404 ? 'invisible' : 'unknown';
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=scope-choices.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope-choices.js","sourceRoot":"","sources":["../../src/lib/scope-choices.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { createConfigStore } from './config.js';
|
|
2
|
+
import type { CaptureFetchResult } from './fetchers/capture.js';
|
|
3
|
+
import { type ChangedBy, type ScopeDeps } from './scope.js';
|
|
4
|
+
import type { FetchExtras, SyncWindow } from './since.js';
|
|
5
|
+
export interface ScopeFlags {
|
|
6
|
+
scope?: string;
|
|
7
|
+
repo?: string;
|
|
8
|
+
projects?: string;
|
|
9
|
+
teams?: string;
|
|
10
|
+
gitlabProject?: string;
|
|
11
|
+
spaces?: string;
|
|
12
|
+
/** The `--since` the person actually gave, as the lower bound it read back to (null: `all`). Not a scope flag: it only sets a NEW scope row's window. */
|
|
13
|
+
windowSince?: string | null;
|
|
14
|
+
}
|
|
15
|
+
export interface PickOption {
|
|
16
|
+
value: string;
|
|
17
|
+
label: string;
|
|
18
|
+
hint?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface ScopePrompts {
|
|
21
|
+
/** The values the person chose, or null when they cancelled. */
|
|
22
|
+
multiselect(message: string, options: PickOption[], initial: string[], o: {
|
|
23
|
+
required: boolean;
|
|
24
|
+
}): Promise<string[] | null>;
|
|
25
|
+
/** A yes/no question whose default is No. A cancel, or a closed stdin, is No. */
|
|
26
|
+
confirm(message: string): Promise<boolean>;
|
|
27
|
+
}
|
|
28
|
+
export interface ConnectScopeCtx {
|
|
29
|
+
/** The store, graph and network the scope code uses. `store.fields` is overlaid with the in-flight fields per source. */
|
|
30
|
+
deps: ScopeDeps;
|
|
31
|
+
interactive: boolean;
|
|
32
|
+
/** `--json`: print nothing, and do not mark the disclosure told. */
|
|
33
|
+
quiet: boolean;
|
|
34
|
+
flags: ScopeFlags;
|
|
35
|
+
prompts: ScopePrompts;
|
|
36
|
+
/** Who the choices are attributed to. Absent: the person at this command line. A child `align_backfill` started is an agent's: its choices wait. */
|
|
37
|
+
by?: ChangedBy;
|
|
38
|
+
/** Ticket prefixes local decisions cite (scope-defaults.ts), to preselect. */
|
|
39
|
+
citedKeys(): string[];
|
|
40
|
+
say(line: string): void;
|
|
41
|
+
}
|
|
42
|
+
export interface ScopeDecision {
|
|
43
|
+
/** Handed to the source's fetch. */
|
|
44
|
+
extras: FetchExtras;
|
|
45
|
+
scope: 'yours' | 'team';
|
|
46
|
+
label: string;
|
|
47
|
+
/** True when this is a team read the person could not be told about (quiet): the disclosure is still owed. */
|
|
48
|
+
readonly disclosurePending?: boolean;
|
|
49
|
+
/** Write the choice. Called once, after the fetch succeeded. */
|
|
50
|
+
commit(): void;
|
|
51
|
+
}
|
|
52
|
+
/** Checked before any prompt or request. Returns the sentence to print with exit 2, or undefined when the flags are usable. */
|
|
53
|
+
export declare function checkScopeFlags(source: string | undefined, flags: ScopeFlags): string | undefined;
|
|
54
|
+
/** Decide the scope of one source being connected, with the in-flight `tokens`. May print (disclosure, notes). Throws to refuse. */
|
|
55
|
+
export declare function decideConnectScope(source: string, tokens: Record<string, string>, ctx: ConnectScopeCtx): Promise<ScopeDecision>;
|
|
56
|
+
/**
|
|
57
|
+
* The connect loop's one call: decide the scope, fetch under it, and write the choice only once the fetch succeeded. A team read says
|
|
58
|
+
* whose items it covered in the report, unless the fetcher already did (GitHub names the repo itself).
|
|
59
|
+
*/
|
|
60
|
+
export declare function fetchUnderScope(source: {
|
|
61
|
+
id: string;
|
|
62
|
+
fetch: (tokens: Record<string, string>, window?: SyncWindow, opts?: FetchExtras) => Promise<CaptureFetchResult>;
|
|
63
|
+
}, tokens: Record<string, string>, window: SyncWindow | undefined, ctx: ConnectScopeCtx,
|
|
64
|
+
/** Starts the caller's spinner. Called AFTER the questions and notes (a spinner redraws and listens to the keyboard, which garbles a picker),
|
|
65
|
+
* and also before a refusal is thrown, so the caller's stop line has a spinner to stop. */
|
|
66
|
+
startSpinner?: () => void): Promise<CaptureFetchResult>;
|
|
67
|
+
/** The real prompts: a clack multiselect. A cancel is null. Tests inject their own. */
|
|
68
|
+
export declare function clackScopePrompts(): ScopePrompts;
|
|
69
|
+
/**
|
|
70
|
+
* Was this process started by an agent's tool call (`align_backfill`, `align_sync run`)? Those children carry the marker, so any scope
|
|
71
|
+
* they would write is attributed to the agent and waits for a person, exactly like `align_scope set`.
|
|
72
|
+
*/
|
|
73
|
+
export declare function startedByAgent(env?: Record<string, string | undefined>): boolean;
|
|
74
|
+
/** The production wiring of `ConnectScopeCtx` for `align connect` and `align setup`: the real store, graph, folder, network and prompts. */
|
|
75
|
+
export declare function connectScopeCtx(o: {
|
|
76
|
+
config: ReturnType<typeof createConfigStore>;
|
|
77
|
+
dbPath: string | undefined;
|
|
78
|
+
interactive: boolean;
|
|
79
|
+
quiet: boolean;
|
|
80
|
+
flags?: ScopeFlags;
|
|
81
|
+
}): ConnectScopeCtx;
|
|
82
|
+
//# sourceMappingURL=scope-connect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope-connect.d.ts","sourceRoot":"","sources":["../../src/lib/scope-connect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* L4: choosing a scope while a source is being connected (`align connect --source <x>`, `align setup`).
|
|
3
|
+
*
|
|
4
|
+
* `decideConnectScope` runs BEFORE the fetch and returns what to fetch under; `fetchUnderScope` is the one call the connect loop makes:
|
|
5
|
+
* decide, fetch, and only then write the choice. A fetch that fails writes nothing, and the token is still saved by the caller only
|
|
6
|
+
* after the fetch succeeded, so a first connect has no saved token yet: every check here uses the IN-FLIGHT fields.
|
|
7
|
+
*
|
|
8
|
+
* What it decides, in order (a flag always wins, and a flag is checked against what the token can see before anything is fetched):
|
|
9
|
+
* - GitHub and GitLab: the folder's remote decides, with no question (resolveScope). A repo the token cannot see is yours, said so.
|
|
10
|
+
* - Jira and Linear: a picker on a terminal (cited keys preselected); otherwise the stored choice, else the cited keys the token can
|
|
11
|
+
* see, else yours with how to widen. A list that cannot be read never blocks: yours, and the reason is said.
|
|
12
|
+
* - Confluence: spaces, picked, flagged or stored. With none, refused with the command (there is no "yours" to fall back to).
|
|
13
|
+
* - Zoom: only yours, and it says why. Slack, Notion and Teams already read all the token can see: nothing to say.
|
|
14
|
+
*
|
|
15
|
+
* The team-scope disclosure is printed here, before the fetch, once per source. `quiet` (`--json`) prints nothing and does not mark
|
|
16
|
+
* it told, so the next foreground run still tells the person.
|
|
17
|
+
*/
|
|
18
|
+
import { askWithTimeout } from './confirm-timeout.js';
|
|
19
|
+
import * as p from '@clack/prompts';
|
|
20
|
+
import { STARTED_BY_AGENT_ENV } from './backfill-state.js';
|
|
21
|
+
import { chooseScope, commitScope, CONFLUENCE_NEEDS_SPACES, markTold, resolveScope } from './scope.js';
|
|
22
|
+
import { citedProjectKeys } from './scope-defaults.js';
|
|
23
|
+
import { realScopeDeps } from './scope-real.js';
|
|
24
|
+
import { listConfluenceSpaces, listJiraProjects, listLinearTeams, ScopeLookupError } from './scope-choices.js';
|
|
25
|
+
import { describeScopeKey, disclosureText, fetchOptsFor, FIXED_SCOPES, SCOPED_SOURCES, scopeKeyOf } from './scope-values.js';
|
|
26
|
+
import { CAPTURE_SOURCES } from './capture-sources.js';
|
|
27
|
+
const labelOf = (source) => CAPTURE_SOURCES[source]?.label ?? source;
|
|
28
|
+
const isScoped = (source) => SCOPED_SOURCES.includes(source);
|
|
29
|
+
const VALUE_FLAG = { github: 'repo', jira: 'projects', linear: 'teams', gitlab: 'gitlabProject', confluence: 'spaces' };
|
|
30
|
+
const FLAG_NAME = { repo: '--repo', projects: '--projects', teams: '--teams', gitlabProject: '--gitlab-project', spaces: '--spaces' };
|
|
31
|
+
const FLAG_FOR = { repo: 'GitHub', projects: 'Jira', teams: 'Linear', gitlabProject: 'GitLab', spaces: 'Confluence' };
|
|
32
|
+
const WHAT = { jira: 'Jira projects', linear: 'Linear teams', confluence: 'Confluence spaces' };
|
|
33
|
+
/** Checked before any prompt or request. Returns the sentence to print with exit 2, or undefined when the flags are usable. */
|
|
34
|
+
export function checkScopeFlags(source, flags) {
|
|
35
|
+
const valueFlags = Object.keys(FLAG_NAME).filter((k) => flags[k] !== undefined);
|
|
36
|
+
if (flags.scope === undefined && valueFlags.length === 0)
|
|
37
|
+
return undefined;
|
|
38
|
+
if (source === undefined)
|
|
39
|
+
return 'Scope flags (--scope, --repo, --projects, --teams, --gitlab-project, --spaces) need --source <id> to say which source they are for.';
|
|
40
|
+
const fixed = FIXED_SCOPES[source];
|
|
41
|
+
if (fixed)
|
|
42
|
+
return `${labelOf(source)} reads ${fixed.text}. There is no scope to choose for it.`;
|
|
43
|
+
if (!isScoped(source))
|
|
44
|
+
return 'That source has no scope to choose.';
|
|
45
|
+
if (flags.scope !== undefined && flags.scope !== 'yours' && flags.scope !== 'team')
|
|
46
|
+
return '--scope takes yours or team.';
|
|
47
|
+
const wrong = valueFlags.find((k) => VALUE_FLAG[source] !== k);
|
|
48
|
+
if (wrong !== undefined)
|
|
49
|
+
return `${FLAG_NAME[wrong]} is for ${FLAG_FOR[wrong]}; ${labelOf(source)} takes ${FLAG_NAME[VALUE_FLAG[source]]}.`;
|
|
50
|
+
const given = valueFlags.length > 0;
|
|
51
|
+
if (flags.scope === 'yours' && given)
|
|
52
|
+
return `Pass either --scope yours or ${FLAG_NAME[VALUE_FLAG[source]]}, not both.`;
|
|
53
|
+
if (flags.scope === 'team' && !given && source !== 'github' && source !== 'gitlab')
|
|
54
|
+
return `--scope team needs ${FLAG_NAME[VALUE_FLAG[source]]} to say which ${source === 'confluence' ? 'spaces' : source === 'jira' ? 'projects' : 'teams'}.`;
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
function flagInput(source, flags) {
|
|
58
|
+
if (flags.scope === 'yours')
|
|
59
|
+
return { scope: 'yours' };
|
|
60
|
+
const value = flags[VALUE_FLAG[source]];
|
|
61
|
+
return value !== undefined ? { scope: 'team', values: value } : undefined;
|
|
62
|
+
}
|
|
63
|
+
const LISTERS = {
|
|
64
|
+
jira: listJiraProjects,
|
|
65
|
+
confluence: listConfluenceSpaces,
|
|
66
|
+
linear: async (t, f) => { const r = await listLinearTeams(t, f); return { items: r.items.map(({ key, name }) => ({ key, name })), truncated: r.truncated }; },
|
|
67
|
+
};
|
|
68
|
+
/** Decide the scope of one source being connected, with the in-flight `tokens`. May print (disclosure, notes). Throws to refuse. */
|
|
69
|
+
export async function decideConnectScope(source, tokens, ctx) {
|
|
70
|
+
const tell = (line) => { if (!ctx.quiet)
|
|
71
|
+
ctx.say(line); };
|
|
72
|
+
const fixed = FIXED_SCOPES[source];
|
|
73
|
+
if (!isScoped(source)) {
|
|
74
|
+
if (source === 'zoom' && fixed)
|
|
75
|
+
tell(`${labelOf(source)} reads ${fixed.text}.`);
|
|
76
|
+
return { extras: {}, scope: 'yours', label: 'your own items', commit() { } };
|
|
77
|
+
}
|
|
78
|
+
// A person is someone at a terminal who can be shown the disclosure and asked: a TTY, and not --json. Everything else (a script, an agent's
|
|
79
|
+
// shell, a child `align_backfill` started) is UNATTENDED: it reads yours, it never widens from the folder or from cited keys, and a
|
|
80
|
+
// widening it is asked for is saved as PENDING for a person to confirm.
|
|
81
|
+
const person = ctx.interactive && !ctx.quiet;
|
|
82
|
+
// The store, with this source's fields replaced by the ones in hand: a first connect has nothing saved to read.
|
|
83
|
+
const deps = { ...ctx.deps, isTty: () => person, store: { ...ctx.deps.store, fields: (s) => (s === source ? tokens : ctx.deps.store.fields(s)) } };
|
|
84
|
+
const by = ctx.by ?? { via: 'cli', unattended: !person };
|
|
85
|
+
// A team read whose disclosure could not be shown (--json): the result says so, and it stays un-marked for the next foreground run.
|
|
86
|
+
let disclosurePending = false;
|
|
87
|
+
const blocked = (reason) => new Error(reason);
|
|
88
|
+
const told = (scopeKey, text) => {
|
|
89
|
+
if (deps.store.isDisclosed(source, scopeKey))
|
|
90
|
+
return;
|
|
91
|
+
if (ctx.quiet) {
|
|
92
|
+
disclosurePending = true;
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
tell(text);
|
|
96
|
+
markTold(deps.store, source, scopeKey);
|
|
97
|
+
};
|
|
98
|
+
const decision = (extras, scope, label, commit) => ({ extras, scope, label, get disclosurePending() { return disclosurePending; }, commit });
|
|
99
|
+
const fromChoice = (c) => {
|
|
100
|
+
if (c.scope === 'team')
|
|
101
|
+
told(c.scopeKey, disclosureText(source, c.labels));
|
|
102
|
+
const extras = c.scope === 'yours'
|
|
103
|
+
? { resolved: true }
|
|
104
|
+
: { resolved: true, ...(source === 'github' ? { repo: c.values[0], team: true } : fetchOptsFor(source, c.values)) };
|
|
105
|
+
return decision(extras, c.scope, c.label, () => { commitScope(deps, source, c, by, ctx.flags.windowSince); });
|
|
106
|
+
};
|
|
107
|
+
/** What is in force without the agent's waiting choice: the same answer a background run gets. */
|
|
108
|
+
const kept = () => resolveScope(source, { ...deps, isTty: () => false }, { foreground: false });
|
|
109
|
+
const fromResolved = async (r, o = {}) => {
|
|
110
|
+
if (r.blocked !== undefined)
|
|
111
|
+
throw blocked(r.blocked);
|
|
112
|
+
if (r.activates) {
|
|
113
|
+
// An agent's waiting scope, offered to a person: the disclosure every time, and only an explicit Yes makes it active.
|
|
114
|
+
tell(r.disclosure);
|
|
115
|
+
const yes = await ctx.prompts.confirm(`Read ${r.label} now? No keeps your current scope.`);
|
|
116
|
+
if (!yes)
|
|
117
|
+
return fromResolved(await kept());
|
|
118
|
+
markTold(deps.store, source, r.scopeKey);
|
|
119
|
+
}
|
|
120
|
+
else if (r.disclosure !== undefined)
|
|
121
|
+
told(r.scopeKey, r.disclosure);
|
|
122
|
+
if (r.note !== undefined && o.note !== false)
|
|
123
|
+
tell(r.note);
|
|
124
|
+
// A team scope read with nobody to tell (--json, no terminal) that was never told for this scope: the disclosure is still owed.
|
|
125
|
+
if (r.scope === 'team' && !person && !deps.store.isDisclosed(source, r.scopeKey))
|
|
126
|
+
disclosurePending = true;
|
|
127
|
+
return decision({ resolved: true, ...(r.repo ? { repo: r.repo, team: true } : {}), ...r.extras }, r.scope, r.label, () => { });
|
|
128
|
+
};
|
|
129
|
+
const resolved = async (o = {}) => fromResolved(await resolveScope(source, deps, { foreground: true }), o);
|
|
130
|
+
const list = async () => {
|
|
131
|
+
try {
|
|
132
|
+
const r = await LISTERS[source](tokens, deps.fetch, deps.listMax !== undefined ? { max: deps.listMax } : {});
|
|
133
|
+
if (r.truncated)
|
|
134
|
+
tell(`Only the first ${r.items.length} ${WHAT[source]} are listed. To pick one that is not shown: align connect --source ${source} ${source === 'jira' ? '--projects' : source === 'linear' ? '--teams' : '--spaces'} KEYS`);
|
|
135
|
+
return r.items;
|
|
136
|
+
}
|
|
137
|
+
catch (e) {
|
|
138
|
+
if (!(e instanceof ScopeLookupError))
|
|
139
|
+
throw e;
|
|
140
|
+
if (source === 'confluence')
|
|
141
|
+
throw blocked(`${e.message} Confluence reads only the spaces you choose, so nothing was read. Pick them: align connect --source confluence --spaces ENG,OPS`);
|
|
142
|
+
tell(`Could not list your ${WHAT[source]}: ${e.message}`);
|
|
143
|
+
return undefined;
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
const input = flagInput(source, ctx.flags);
|
|
147
|
+
if (input) {
|
|
148
|
+
const c = await chooseScope(deps, source, input, tokens);
|
|
149
|
+
if (c.scope === 'yours' || person)
|
|
150
|
+
return fromChoice(c);
|
|
151
|
+
// Unattended widening: read what is in force now, and save the request for a person to confirm at a terminal.
|
|
152
|
+
let k;
|
|
153
|
+
// One line for the person, not two: the "will read ... once you confirm" line below replaces the default scope's own hint.
|
|
154
|
+
try {
|
|
155
|
+
k = await resolved({ note: false });
|
|
156
|
+
}
|
|
157
|
+
catch (e) {
|
|
158
|
+
// Confluence with nothing chosen yet: the request is still saved for the person, and the refusal says so.
|
|
159
|
+
commitScope(deps, source, c, by, ctx.flags.windowSince);
|
|
160
|
+
throw new Error(`${e.message} Your request for ${c.label} is saved and waiting for you to confirm: run \`align sync ${source}\` at a terminal.`);
|
|
161
|
+
}
|
|
162
|
+
tell(`${labelOf(source)} will read ${c.label} once you confirm it: run \`align sync ${source}\` at a terminal (it will show what it reads).`);
|
|
163
|
+
return decision(k.extras, k.scope, k.label, () => { commitScope(deps, source, c, by, ctx.flags.windowSince); });
|
|
164
|
+
}
|
|
165
|
+
if (source === 'github' || source === 'gitlab') {
|
|
166
|
+
const d = await resolved();
|
|
167
|
+
if (ctx.flags.scope === 'team' && d.scope === 'yours') {
|
|
168
|
+
throw blocked(`--scope team needs a ${source === 'github' ? 'repo' : 'project'}: this folder is not one. Pass ${source === 'github' ? '--repo owner/repo' : '--gitlab-project group/project'}.`);
|
|
169
|
+
}
|
|
170
|
+
return d;
|
|
171
|
+
}
|
|
172
|
+
const stored = deps.store.getScope(source);
|
|
173
|
+
const confluence = source === 'confluence';
|
|
174
|
+
// Without a person there is no picker and no guess from cited keys: the stored choice, else yours (with how to widen).
|
|
175
|
+
if (!person)
|
|
176
|
+
return resolved();
|
|
177
|
+
const listed = await list();
|
|
178
|
+
if (listed === undefined)
|
|
179
|
+
return resolved();
|
|
180
|
+
const keys = listed.map((x) => x.key);
|
|
181
|
+
const waitingLabels = stored?.kind === 'team' && stored.pending ? stored.labels : [];
|
|
182
|
+
const inForce = stored?.kind === 'team' && stored.pending ? stored.pending.previous : stored;
|
|
183
|
+
// What is preselected is what is already in force, or what local decisions cite. An agent's WAITING choice is never preselected:
|
|
184
|
+
// it is said, and picking it here is the explicit confirmation.
|
|
185
|
+
if (waitingLabels.length > 0)
|
|
186
|
+
tell(`Your agent proposed ${source} scope ${describeScopeKey(source, scopeKeyOf(source, waitingLabels), 'team')}. It is not read until you pick it here.`);
|
|
187
|
+
const initial = inForce?.kind === 'team' ? inForce.labels.filter((k) => keys.includes(k)) : inForce?.kind === 'yours' ? [] : ctx.citedKeys().filter((k) => keys.includes(k));
|
|
188
|
+
const message = confluence
|
|
189
|
+
? 'Which Confluence spaces should Align read? Pick at least one.'
|
|
190
|
+
: `Which ${WHAT[source]} should Align read everything from? Leave all unselected to read only the items you are involved in.`;
|
|
191
|
+
const picked = await ctx.prompts.multiselect(message, listed.map((x) => ({ value: x.key, label: `${x.key} ${x.name}` })), initial, { required: confluence });
|
|
192
|
+
// Cancelled: nothing changes, and an agent's waiting scope stays waiting (it is not promoted, and not read).
|
|
193
|
+
if (picked === null) {
|
|
194
|
+
const k = await kept();
|
|
195
|
+
if (k.blocked !== undefined)
|
|
196
|
+
throw blocked(k.blocked);
|
|
197
|
+
return fromResolved(k);
|
|
198
|
+
}
|
|
199
|
+
if (confluence && picked.length === 0)
|
|
200
|
+
throw blocked(CONFLUENCE_NEEDS_SPACES);
|
|
201
|
+
return fromChoice(await chooseScope(deps, source, picked.length === 0 ? { scope: 'yours' } : { scope: 'team', values: picked }, tokens));
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* The connect loop's one call: decide the scope, fetch under it, and write the choice only once the fetch succeeded. A team read says
|
|
205
|
+
* whose items it covered in the report, unless the fetcher already did (GitHub names the repo itself).
|
|
206
|
+
*/
|
|
207
|
+
export async function fetchUnderScope(source, tokens, window, ctx,
|
|
208
|
+
/** Starts the caller's spinner. Called AFTER the questions and notes (a spinner redraws and listens to the keyboard, which garbles a picker),
|
|
209
|
+
* and also before a refusal is thrown, so the caller's stop line has a spinner to stop. */
|
|
210
|
+
startSpinner = () => { }) {
|
|
211
|
+
let decision;
|
|
212
|
+
try {
|
|
213
|
+
decision = await decideConnectScope(source.id, tokens, ctx);
|
|
214
|
+
}
|
|
215
|
+
catch (e) {
|
|
216
|
+
startSpinner();
|
|
217
|
+
throw e;
|
|
218
|
+
}
|
|
219
|
+
startSpinner();
|
|
220
|
+
const fetched = await source.fetch(tokens, window, decision.extras);
|
|
221
|
+
decision.commit();
|
|
222
|
+
// A copy, never an edit of what the fetcher returned.
|
|
223
|
+
const report = { ...fetched.report };
|
|
224
|
+
if (decision.scope === 'team' && report.scopeNote === undefined)
|
|
225
|
+
report.scopeNote = `${decision.label}, as far as your token can see`;
|
|
226
|
+
if (decision.disclosurePending)
|
|
227
|
+
report.disclosurePending = true;
|
|
228
|
+
return { ...fetched, report };
|
|
229
|
+
}
|
|
230
|
+
/** The real prompts: a clack multiselect. A cancel is null. Tests inject their own. */
|
|
231
|
+
export function clackScopePrompts() {
|
|
232
|
+
return {
|
|
233
|
+
async multiselect(message, options, initial, o) {
|
|
234
|
+
const answer = await p.multiselect({ message, options: options.map((x) => ({ value: x.value, label: x.label, ...(x.hint !== undefined ? { hint: x.hint } : {}) })), initialValues: initial, required: o.required, maxItems: 12 });
|
|
235
|
+
return p.isCancel(answer) ? null : answer;
|
|
236
|
+
},
|
|
237
|
+
async confirm(message) {
|
|
238
|
+
return askWithTimeout(async () => (await p.confirm({ message, initialValue: false })) === true);
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Was this process started by an agent's tool call (`align_backfill`, `align_sync run`)? Those children carry the marker, so any scope
|
|
244
|
+
* they would write is attributed to the agent and waits for a person, exactly like `align_scope set`.
|
|
245
|
+
*/
|
|
246
|
+
export function startedByAgent(env = process.env) {
|
|
247
|
+
return env[STARTED_BY_AGENT_ENV] === 'mcp';
|
|
248
|
+
}
|
|
249
|
+
/** The production wiring of `ConnectScopeCtx` for `align connect` and `align setup`: the real store, graph, folder, network and prompts. */
|
|
250
|
+
export function connectScopeCtx(o) {
|
|
251
|
+
const dbPath = o.dbPath;
|
|
252
|
+
return {
|
|
253
|
+
deps: realScopeDeps(dbPath, { config: o.config }), interactive: o.interactive, quiet: o.quiet, flags: o.flags ?? {}, prompts: clackScopePrompts(),
|
|
254
|
+
...(startedByAgent() ? { by: { via: 'mcp', agent: 'unknown' } } : {}),
|
|
255
|
+
citedKeys: () => (dbPath === undefined ? [] : citedProjectKeys(dbPath)), say: (line) => p.log.info(line),
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
//# sourceMappingURL=scope-connect.js.map
|