@productbrain/cli 0.1.0-beta.108 → 0.1.0-beta.1087
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/dist/__tests__/audit.test.js +5 -0
- package/dist/__tests__/audit.test.js.map +1 -1
- package/dist/__tests__/canonicalRefs.vocab.test.d.ts +2 -0
- package/dist/__tests__/canonicalRefs.vocab.test.d.ts.map +1 -0
- package/dist/__tests__/canonicalRefs.vocab.test.js +251 -0
- package/dist/__tests__/canonicalRefs.vocab.test.js.map +1 -0
- package/dist/__tests__/config.test.js +272 -2
- package/dist/__tests__/config.test.js.map +1 -1
- package/dist/__tests__/constants.test.js +6 -1
- package/dist/__tests__/constants.test.js.map +1 -1
- package/dist/__tests__/envelope-contract.test.js +29 -3
- package/dist/__tests__/envelope-contract.test.js.map +1 -1
- package/dist/__tests__/errors.test.js +1 -0
- package/dist/__tests__/errors.test.js.map +1 -1
- package/dist/__tests__/handshake-augment.test.d.ts +2 -0
- package/dist/__tests__/handshake-augment.test.d.ts.map +1 -0
- package/dist/__tests__/handshake-augment.test.js +423 -0
- package/dist/__tests__/handshake-augment.test.js.map +1 -0
- package/dist/__tests__/handshake-dormancy.test.d.ts +2 -0
- package/dist/__tests__/handshake-dormancy.test.d.ts.map +1 -0
- package/dist/__tests__/handshake-dormancy.test.js +207 -0
- package/dist/__tests__/handshake-dormancy.test.js.map +1 -0
- package/dist/__tests__/handshake-formatter.test.d.ts +2 -0
- package/dist/__tests__/handshake-formatter.test.d.ts.map +1 -0
- package/dist/__tests__/handshake-formatter.test.js +67 -0
- package/dist/__tests__/handshake-formatter.test.js.map +1 -0
- package/dist/__tests__/handshake-preview.test.js +566 -4
- package/dist/__tests__/handshake-preview.test.js.map +1 -1
- package/dist/__tests__/handshake.e2e.test.d.ts +2 -0
- package/dist/__tests__/handshake.e2e.test.d.ts.map +1 -0
- package/dist/__tests__/handshake.e2e.test.js +1252 -0
- package/dist/__tests__/handshake.e2e.test.js.map +1 -0
- package/dist/__tests__/handshake.test.js +255 -5
- package/dist/__tests__/handshake.test.js.map +1 -1
- package/dist/__tests__/manifest.test.js +118 -1
- package/dist/__tests__/manifest.test.js.map +1 -1
- package/dist/__tests__/notice-marker.test.d.ts +2 -0
- package/dist/__tests__/notice-marker.test.d.ts.map +1 -0
- package/dist/__tests__/notice-marker.test.js +41 -0
- package/dist/__tests__/notice-marker.test.js.map +1 -0
- package/dist/__tests__/onboarding-path-b.test.js +4 -4
- package/dist/__tests__/onboarding-path-b.test.js.map +1 -1
- package/dist/__tests__/orient.test.js +117 -26
- package/dist/__tests__/orient.test.js.map +1 -1
- package/dist/__tests__/perimeter.test.d.ts +2 -0
- package/dist/__tests__/perimeter.test.d.ts.map +1 -0
- package/dist/__tests__/perimeter.test.js +165 -0
- package/dist/__tests__/perimeter.test.js.map +1 -0
- package/dist/__tests__/preview-key-refresh.test.d.ts +2 -0
- package/dist/__tests__/preview-key-refresh.test.d.ts.map +1 -0
- package/dist/__tests__/preview-key-refresh.test.js +126 -0
- package/dist/__tests__/preview-key-refresh.test.js.map +1 -0
- package/dist/__tests__/profiles.test.js +106 -2
- package/dist/__tests__/profiles.test.js.map +1 -1
- package/dist/__tests__/promote.test.js +2 -2
- package/dist/__tests__/promote.test.js.map +1 -1
- package/dist/__tests__/session-reset.test.d.ts +2 -0
- package/dist/__tests__/session-reset.test.d.ts.map +1 -0
- package/dist/__tests__/session-reset.test.js +122 -0
- package/dist/__tests__/session-reset.test.js.map +1 -0
- package/dist/__tests__/session-resume-backstop.test.d.ts +2 -0
- package/dist/__tests__/session-resume-backstop.test.d.ts.map +1 -0
- package/dist/__tests__/session-resume-backstop.test.js +97 -0
- package/dist/__tests__/session-resume-backstop.test.js.map +1 -0
- package/dist/__tests__/session-start-key-refresh.test.d.ts +2 -0
- package/dist/__tests__/session-start-key-refresh.test.d.ts.map +1 -0
- package/dist/__tests__/session-start-key-refresh.test.js +178 -0
- package/dist/__tests__/session-start-key-refresh.test.js.map +1 -0
- package/dist/__tests__/session-state-machine.test.js +45 -1
- package/dist/__tests__/session-state-machine.test.js.map +1 -1
- package/dist/__tests__/session-switch.test.d.ts +2 -0
- package/dist/__tests__/session-switch.test.d.ts.map +1 -0
- package/dist/__tests__/session-switch.test.js +130 -0
- package/dist/__tests__/session-switch.test.js.map +1 -0
- package/dist/__tests__/setup-ingest.test.js +16 -0
- package/dist/__tests__/setup-ingest.test.js.map +1 -1
- package/dist/__tests__/skill-vocabulary.test.d.ts +21 -0
- package/dist/__tests__/skill-vocabulary.test.d.ts.map +1 -0
- package/dist/__tests__/skill-vocabulary.test.js +187 -0
- package/dist/__tests__/skill-vocabulary.test.js.map +1 -0
- package/dist/__tests__/update-check.test.d.ts +2 -0
- package/dist/__tests__/update-check.test.d.ts.map +1 -0
- package/dist/__tests__/update-check.test.js +215 -0
- package/dist/__tests__/update-check.test.js.map +1 -0
- package/dist/__tests__/upgrade-runner.test.d.ts +2 -0
- package/dist/__tests__/upgrade-runner.test.d.ts.map +1 -0
- package/dist/__tests__/upgrade-runner.test.js +54 -0
- package/dist/__tests__/upgrade-runner.test.js.map +1 -0
- package/dist/__tests__/upgrade.test.d.ts +2 -0
- package/dist/__tests__/upgrade.test.d.ts.map +1 -0
- package/dist/__tests__/upgrade.test.js +56 -0
- package/dist/__tests__/upgrade.test.js.map +1 -0
- package/dist/__tests__/vocabulary-leak.test.d.ts +39 -0
- package/dist/__tests__/vocabulary-leak.test.d.ts.map +1 -0
- package/dist/__tests__/vocabulary-leak.test.js +534 -0
- package/dist/__tests__/vocabulary-leak.test.js.map +1 -0
- package/dist/commands/__tests__/connect-handoff.test.d.ts +11 -0
- package/dist/commands/__tests__/connect-handoff.test.d.ts.map +1 -0
- package/dist/commands/__tests__/connect-handoff.test.js +111 -0
- package/dist/commands/__tests__/connect-handoff.test.js.map +1 -0
- package/dist/commands/__tests__/setup-detect-surfaces.test.d.ts +15 -0
- package/dist/commands/__tests__/setup-detect-surfaces.test.d.ts.map +1 -0
- package/dist/commands/__tests__/setup-detect-surfaces.test.js +149 -0
- package/dist/commands/__tests__/setup-detect-surfaces.test.js.map +1 -0
- package/dist/commands/__tests__/setup-state.test.d.ts +2 -0
- package/dist/commands/__tests__/setup-state.test.d.ts.map +1 -0
- package/dist/commands/__tests__/setup-state.test.js +194 -0
- package/dist/commands/__tests__/setup-state.test.js.map +1 -0
- package/dist/commands/admin/seed.d.ts +32 -2
- package/dist/commands/admin/seed.d.ts.map +1 -1
- package/dist/commands/admin/seed.js +279 -33
- package/dist/commands/admin/seed.js.map +1 -1
- package/dist/commands/admin/seed.test.js +7 -0
- package/dist/commands/admin/seed.test.js.map +1 -1
- package/dist/commands/admin/seedRegistryEntries.generated.d.ts +14 -0
- package/dist/commands/admin/seedRegistryEntries.generated.d.ts.map +1 -0
- package/dist/commands/admin/seedRegistryEntries.generated.js +117 -0
- package/dist/commands/admin/seedRegistryEntries.generated.js.map +1 -0
- package/dist/commands/admin/seedRegistryEntries.test.d.ts +11 -0
- package/dist/commands/admin/seedRegistryEntries.test.d.ts.map +1 -0
- package/dist/commands/admin/seedRegistryEntries.test.js +67 -0
- package/dist/commands/admin/seedRegistryEntries.test.js.map +1 -0
- package/dist/commands/audit.d.ts.map +1 -1
- package/dist/commands/audit.js +30 -3
- package/dist/commands/audit.js.map +1 -1
- package/dist/commands/authority-domains.d.ts +7 -1
- package/dist/commands/authority-domains.d.ts.map +1 -1
- package/dist/commands/authority-domains.js +19 -4
- package/dist/commands/authority-domains.js.map +1 -1
- package/dist/commands/capture.d.ts +2 -0
- package/dist/commands/capture.d.ts.map +1 -1
- package/dist/commands/capture.js +8 -3
- package/dist/commands/capture.js.map +1 -1
- package/dist/commands/codex-prep.js +6 -6
- package/dist/commands/codex-prep.js.map +1 -1
- package/dist/commands/connect-config.test.d.ts +2 -0
- package/dist/commands/connect-config.test.d.ts.map +1 -0
- package/dist/commands/connect-config.test.js +44 -0
- package/dist/commands/connect-config.test.js.map +1 -0
- package/dist/commands/connect-context.d.ts +45 -0
- package/dist/commands/connect-context.d.ts.map +1 -0
- package/dist/commands/connect-context.js +64 -0
- package/dist/commands/connect-context.js.map +1 -0
- package/dist/commands/connect-context.test.d.ts +2 -0
- package/dist/commands/connect-context.test.d.ts.map +1 -0
- package/dist/commands/connect-context.test.js +110 -0
- package/dist/commands/connect-context.test.js.map +1 -0
- package/dist/commands/connect-handoff.d.ts +51 -0
- package/dist/commands/connect-handoff.d.ts.map +1 -0
- package/dist/commands/connect-handoff.js +70 -0
- package/dist/commands/connect-handoff.js.map +1 -0
- package/dist/commands/connect-integration.test.js +13 -12
- package/dist/commands/connect-integration.test.js.map +1 -1
- package/dist/commands/connect-screens.d.ts +7 -8
- package/dist/commands/connect-screens.d.ts.map +1 -1
- package/dist/commands/connect-screens.js +30 -37
- package/dist/commands/connect-screens.js.map +1 -1
- package/dist/commands/connect.d.ts +19 -6
- package/dist/commands/connect.d.ts.map +1 -1
- package/dist/commands/connect.js +31 -56
- package/dist/commands/connect.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +67 -2
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/doctor.test.js +150 -0
- package/dist/commands/doctor.test.js.map +1 -1
- package/dist/commands/handshake.d.ts +84 -4
- package/dist/commands/handshake.d.ts.map +1 -1
- package/dist/commands/handshake.js +1169 -97
- package/dist/commands/handshake.js.map +1 -1
- package/dist/commands/method.d.ts.map +1 -1
- package/dist/commands/method.js +5 -1
- package/dist/commands/method.js.map +1 -1
- package/dist/commands/orient.d.ts +52 -2
- package/dist/commands/orient.d.ts.map +1 -1
- package/dist/commands/orient.js +41 -7
- package/dist/commands/orient.js.map +1 -1
- package/dist/commands/profile.d.ts +1 -14
- package/dist/commands/profile.d.ts.map +1 -1
- package/dist/commands/profile.js +89 -72
- package/dist/commands/profile.js.map +1 -1
- package/dist/commands/reject.d.ts.map +1 -1
- package/dist/commands/reject.js +2 -1
- package/dist/commands/reject.js.map +1 -1
- package/dist/commands/relate.d.ts.map +1 -1
- package/dist/commands/relate.js +4 -2
- package/dist/commands/relate.js.map +1 -1
- package/dist/commands/session.d.ts +26 -2
- package/dist/commands/session.d.ts.map +1 -1
- package/dist/commands/session.js +216 -31
- package/dist/commands/session.js.map +1 -1
- package/dist/commands/setup-audit.d.ts +59 -0
- package/dist/commands/setup-audit.d.ts.map +1 -0
- package/dist/commands/setup-audit.js +250 -0
- package/dist/commands/setup-audit.js.map +1 -0
- package/dist/commands/setup-detect-surfaces.d.ts +38 -0
- package/dist/commands/setup-detect-surfaces.d.ts.map +1 -0
- package/dist/commands/setup-detect-surfaces.js +76 -0
- package/dist/commands/setup-detect-surfaces.js.map +1 -0
- package/dist/commands/setup-ingest.d.ts.map +1 -1
- package/dist/commands/setup-ingest.js +4 -2
- package/dist/commands/setup-ingest.js.map +1 -1
- package/dist/commands/setup-state.d.ts +42 -0
- package/dist/commands/setup-state.d.ts.map +1 -0
- package/dist/commands/setup-state.js +93 -0
- package/dist/commands/setup-state.js.map +1 -0
- package/dist/commands/setup.d.ts +17 -9
- package/dist/commands/setup.d.ts.map +1 -1
- package/dist/commands/setup.js +52 -131
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +2 -1
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/upgrade.d.ts +5 -0
- package/dist/commands/upgrade.d.ts.map +1 -0
- package/dist/commands/upgrade.js +110 -0
- package/dist/commands/upgrade.js.map +1 -0
- package/dist/commands/verify.d.ts.map +1 -1
- package/dist/commands/verify.js +2 -1
- package/dist/commands/verify.js.map +1 -1
- package/dist/commands/whoami.d.ts +12 -0
- package/dist/commands/whoami.d.ts.map +1 -0
- package/dist/commands/whoami.js +70 -0
- package/dist/commands/whoami.js.map +1 -0
- package/dist/commands/whoami.test.d.ts +2 -0
- package/dist/commands/whoami.test.d.ts.map +1 -0
- package/dist/commands/whoami.test.js +50 -0
- package/dist/commands/whoami.test.js.map +1 -0
- package/dist/formatters/__tests__/orient-provenance.test.d.ts +7 -0
- package/dist/formatters/__tests__/orient-provenance.test.d.ts.map +1 -0
- package/dist/formatters/__tests__/orient-provenance.test.js +454 -0
- package/dist/formatters/__tests__/orient-provenance.test.js.map +1 -0
- package/dist/formatters/audit.d.ts +6 -0
- package/dist/formatters/audit.d.ts.map +1 -1
- package/dist/formatters/audit.js.map +1 -1
- package/dist/formatters/entry.d.ts +21 -0
- package/dist/formatters/entry.d.ts.map +1 -1
- package/dist/formatters/entry.js +46 -5
- package/dist/formatters/entry.js.map +1 -1
- package/dist/formatters/handshake.d.ts +19 -3
- package/dist/formatters/handshake.d.ts.map +1 -1
- package/dist/formatters/handshake.js +47 -12
- package/dist/formatters/handshake.js.map +1 -1
- package/dist/formatters/orient.d.ts +64 -4
- package/dist/formatters/orient.d.ts.map +1 -1
- package/dist/formatters/orient.js +103 -18
- package/dist/formatters/orient.js.map +1 -1
- package/dist/generators/adapters.js +4 -4
- package/dist/generators/context-md.js +6 -6
- package/dist/generators/context-md.js.map +1 -1
- package/dist/generators/manifest.d.ts +76 -0
- package/dist/generators/manifest.d.ts.map +1 -1
- package/dist/generators/manifest.js +125 -14
- package/dist/generators/manifest.js.map +1 -1
- package/dist/generators/portable-knowledge.d.ts +2 -2
- package/dist/generators/portable-knowledge.d.ts.map +1 -1
- package/dist/generators/region-projections.d.ts +18 -0
- package/dist/generators/region-projections.d.ts.map +1 -0
- package/dist/generators/region-projections.js +49 -0
- package/dist/generators/region-projections.js.map +1 -0
- package/dist/generators/region-projections.test.d.ts +2 -0
- package/dist/generators/region-projections.test.d.ts.map +1 -0
- package/dist/generators/region-projections.test.js +63 -0
- package/dist/generators/region-projections.test.js.map +1 -0
- package/dist/generators/region.d.ts +24 -0
- package/dist/generators/region.d.ts.map +1 -0
- package/dist/generators/region.js +87 -0
- package/dist/generators/region.js.map +1 -0
- package/dist/generators/region.test.d.ts +2 -0
- package/dist/generators/region.test.d.ts.map +1 -0
- package/dist/generators/region.test.js +126 -0
- package/dist/generators/region.test.js.map +1 -0
- package/dist/generators/surface-profiles.d.ts +1 -2
- package/dist/generators/surface-profiles.d.ts.map +1 -1
- package/dist/generators/surface-profiles.js.map +1 -1
- package/dist/index.js +144 -25
- package/dist/index.js.map +1 -1
- package/dist/lib/activation.js +2 -2
- package/dist/lib/activation.js.map +1 -1
- package/dist/lib/activation.test.js +3 -3
- package/dist/lib/activation.test.js.map +1 -1
- package/dist/lib/canonicalRefs.d.ts +72 -0
- package/dist/lib/canonicalRefs.d.ts.map +1 -1
- package/dist/lib/canonicalRefs.js +67 -0
- package/dist/lib/canonicalRefs.js.map +1 -1
- package/dist/lib/client.d.ts.map +1 -1
- package/dist/lib/client.js +13 -3
- package/dist/lib/client.js.map +1 -1
- package/dist/lib/config.d.ts +101 -4
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +225 -11
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/constants.d.ts +2 -0
- package/dist/lib/constants.d.ts.map +1 -1
- package/dist/lib/constants.js +2 -0
- package/dist/lib/constants.js.map +1 -1
- package/dist/lib/errors.d.ts +1 -0
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +1 -0
- package/dist/lib/errors.js.map +1 -1
- package/dist/lib/notice-marker.d.ts +3 -0
- package/dist/lib/notice-marker.d.ts.map +1 -0
- package/dist/lib/notice-marker.js +53 -0
- package/dist/lib/notice-marker.js.map +1 -0
- package/dist/lib/onboarding-path-b.d.ts.map +1 -1
- package/dist/lib/onboarding-path-b.js +0 -1
- package/dist/lib/onboarding-path-b.js.map +1 -1
- package/dist/lib/onboarding-shared.d.ts +0 -1
- package/dist/lib/onboarding-shared.d.ts.map +1 -1
- package/dist/lib/onboarding-shared.js +1 -17
- package/dist/lib/onboarding-shared.js.map +1 -1
- package/dist/lib/profiles.d.ts +3 -1
- package/dist/lib/profiles.d.ts.map +1 -1
- package/dist/lib/profiles.js +9 -6
- package/dist/lib/profiles.js.map +1 -1
- package/dist/lib/session.d.ts +10 -0
- package/dist/lib/session.d.ts.map +1 -1
- package/dist/lib/session.js +26 -1
- package/dist/lib/session.js.map +1 -1
- package/dist/lib/update-check.d.ts +42 -7
- package/dist/lib/update-check.d.ts.map +1 -1
- package/dist/lib/update-check.js +213 -62
- package/dist/lib/update-check.js.map +1 -1
- package/dist/lib/upgrade-runner.d.ts +22 -0
- package/dist/lib/upgrade-runner.d.ts.map +1 -0
- package/dist/lib/upgrade-runner.js +110 -0
- package/dist/lib/upgrade-runner.js.map +1 -0
- package/dist/lib/workspaceVocabCache.d.ts +60 -0
- package/dist/lib/workspaceVocabCache.d.ts.map +1 -0
- package/dist/lib/workspaceVocabCache.js +98 -0
- package/dist/lib/workspaceVocabCache.js.map +1 -0
- package/dist/setup/__tests__/coach-traces.test.d.ts +2 -0
- package/dist/setup/__tests__/coach-traces.test.d.ts.map +1 -0
- package/dist/setup/__tests__/coach-traces.test.js +189 -0
- package/dist/setup/__tests__/coach-traces.test.js.map +1 -0
- package/dist/setup/__tests__/setup-commands.test.d.ts +2 -0
- package/dist/setup/__tests__/setup-commands.test.d.ts.map +1 -0
- package/dist/setup/__tests__/setup-commands.test.js +177 -0
- package/dist/setup/__tests__/setup-commands.test.js.map +1 -0
- package/dist/setup/__tests__/state-machine.test.d.ts +2 -0
- package/dist/setup/__tests__/state-machine.test.d.ts.map +1 -0
- package/dist/setup/__tests__/state-machine.test.js +341 -0
- package/dist/setup/__tests__/state-machine.test.js.map +1 -0
- package/dist/setup/detect-surfaces.d.ts +21 -0
- package/dist/setup/detect-surfaces.d.ts.map +1 -0
- package/dist/setup/detect-surfaces.js +39 -0
- package/dist/setup/detect-surfaces.js.map +1 -0
- package/dist/setup/manifest-writer.d.ts +17 -0
- package/dist/setup/manifest-writer.d.ts.map +1 -0
- package/dist/setup/manifest-writer.js +153 -0
- package/dist/setup/manifest-writer.js.map +1 -0
- package/dist/setup/perimeter.d.ts +72 -0
- package/dist/setup/perimeter.d.ts.map +1 -0
- package/dist/setup/perimeter.js +128 -0
- package/dist/setup/perimeter.js.map +1 -0
- package/dist/setup/state-machine.d.ts +67 -0
- package/dist/setup/state-machine.d.ts.map +1 -0
- package/dist/setup/state-machine.js +124 -0
- package/dist/setup/state-machine.js.map +1 -0
- package/dist/surfaces/__tests__/adapter.test.d.ts +2 -0
- package/dist/surfaces/__tests__/adapter.test.d.ts.map +1 -0
- package/dist/surfaces/__tests__/adapter.test.js +90 -0
- package/dist/surfaces/__tests__/adapter.test.js.map +1 -0
- package/dist/surfaces/__tests__/pb-setup-passthrough.test.d.ts +2 -0
- package/dist/surfaces/__tests__/pb-setup-passthrough.test.d.ts.map +1 -0
- package/dist/surfaces/__tests__/pb-setup-passthrough.test.js +132 -0
- package/dist/surfaces/__tests__/pb-setup-passthrough.test.js.map +1 -0
- package/dist/surfaces/__tests__/telemetry.test.d.ts +2 -0
- package/dist/surfaces/__tests__/telemetry.test.d.ts.map +1 -0
- package/dist/surfaces/__tests__/telemetry.test.js +55 -0
- package/dist/surfaces/__tests__/telemetry.test.js.map +1 -0
- package/dist/surfaces/adapter.d.ts +70 -0
- package/dist/surfaces/adapter.d.ts.map +1 -0
- package/dist/surfaces/adapter.js +2 -0
- package/dist/surfaces/adapter.js.map +1 -0
- package/dist/surfaces/adapters/claude.d.ts +3 -0
- package/dist/surfaces/adapters/claude.d.ts.map +1 -0
- package/dist/surfaces/adapters/claude.js +67 -0
- package/dist/surfaces/adapters/claude.js.map +1 -0
- package/dist/surfaces/adapters/codex.d.ts +3 -0
- package/dist/surfaces/adapters/codex.d.ts.map +1 -0
- package/dist/surfaces/adapters/codex.js +61 -0
- package/dist/surfaces/adapters/codex.js.map +1 -0
- package/dist/surfaces/adapters/copilot.d.ts +3 -0
- package/dist/surfaces/adapters/copilot.d.ts.map +1 -0
- package/dist/surfaces/adapters/copilot.js +59 -0
- package/dist/surfaces/adapters/copilot.js.map +1 -0
- package/dist/surfaces/adapters/cursor.d.ts +3 -0
- package/dist/surfaces/adapters/cursor.d.ts.map +1 -0
- package/dist/surfaces/adapters/cursor.js +78 -0
- package/dist/surfaces/adapters/cursor.js.map +1 -0
- package/dist/surfaces/registry.d.ts +58 -2
- package/dist/surfaces/registry.d.ts.map +1 -1
- package/dist/surfaces/registry.js +82 -7
- package/dist/surfaces/registry.js.map +1 -1
- package/dist/surfaces/telemetry.d.ts +17 -0
- package/dist/surfaces/telemetry.d.ts.map +1 -0
- package/dist/surfaces/telemetry.js +31 -0
- package/dist/surfaces/telemetry.js.map +1 -0
- package/package.json +3 -1
- package/dist/__tests__/setup.test.d.ts +0 -2
- package/dist/__tests__/setup.test.d.ts.map +0 -1
- package/dist/__tests__/setup.test.js +0 -141
- package/dist/__tests__/setup.test.js.map +0 -1
- package/dist/generators/__tests__/surface-profiles.test.d.ts +0 -2
- package/dist/generators/__tests__/surface-profiles.test.d.ts.map +0 -1
- package/dist/generators/__tests__/surface-profiles.test.js +0 -89
- package/dist/generators/__tests__/surface-profiles.test.js.map +0 -1
- package/dist/lib/onboarding-phases.d.ts +0 -9
- package/dist/lib/onboarding-phases.d.ts.map +0 -1
- package/dist/lib/onboarding-phases.js +0 -120
- package/dist/lib/onboarding-phases.js.map +0 -1
|
@@ -15,6 +15,10 @@
|
|
|
15
15
|
* {{ref:canonicalKey:display}}, {{ref:domain:data/analytics}}, or
|
|
16
16
|
* {{ref:entry:DEC-123}}.
|
|
17
17
|
* Chain: WP-345 E4, DEC-K (projection hash trailer)
|
|
18
|
+
*
|
|
19
|
+
* WP-436 S1 — Axis 2 vocabulary resolver (DEC-1021, STD-253):
|
|
20
|
+
* {{vocab:<canonicalKey>.<form>}} tokens + getCollectionLabel resolver.
|
|
21
|
+
* PAT-230: resolver is pure — no Convex import, workspace context passed as arg.
|
|
18
22
|
*/
|
|
19
23
|
/**
|
|
20
24
|
* Regex for matching semantic refs. Captures: [1] ref key/path, [2] optional display label.
|
|
@@ -80,4 +84,67 @@ export function replaceSemanticRefs(body, resolvedMap) {
|
|
|
80
84
|
return `[unresolved: ${key}]`;
|
|
81
85
|
});
|
|
82
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* Regex for matching vocab tokens: {{vocab:<canonicalKey>.<form>}}
|
|
89
|
+
* STD-253: canonicalKey + form are both lowercase snake_case.
|
|
90
|
+
* Captures: [1] canonicalKey, [2] form.
|
|
91
|
+
*/
|
|
92
|
+
export const VOCAB_TOKEN_REGEX = /\{\{vocab:([a-z_]+)\.([a-z_]+)\}\}/g;
|
|
93
|
+
/**
|
|
94
|
+
* Resolve the display label for a canonical type + form.
|
|
95
|
+
*
|
|
96
|
+
* Resolution chain (DEC-1021):
|
|
97
|
+
* 1. workspaceCtx.collectionLabels[canonicalKey][form] — workspace override
|
|
98
|
+
* 2. collectionCtx.labels[form] — collection default
|
|
99
|
+
* 3. canonicalKey literal — fallback (no throw)
|
|
100
|
+
*
|
|
101
|
+
* Pure function. No Convex imports. No side effects. (PAT-230)
|
|
102
|
+
*
|
|
103
|
+
* @param canonicalKey - e.g. 'work_package', 'decision'
|
|
104
|
+
* @param form - e.g. 'singular', 'plural', 'verb_start'
|
|
105
|
+
* @param workspaceCtx - optional workspace-level override context
|
|
106
|
+
* @param collectionCtx - optional collection-level default context
|
|
107
|
+
* @returns resolved label string
|
|
108
|
+
*/
|
|
109
|
+
export function getCollectionLabel(canonicalKey, form, workspaceCtx, collectionCtx) {
|
|
110
|
+
// Layer 1: workspace override
|
|
111
|
+
const wsLabels = workspaceCtx?.collectionLabels?.[canonicalKey];
|
|
112
|
+
if (wsLabels) {
|
|
113
|
+
const wsVal = wsLabels[form];
|
|
114
|
+
if (wsVal !== undefined && wsVal.length > 0)
|
|
115
|
+
return wsVal;
|
|
116
|
+
}
|
|
117
|
+
// Layer 2: explicit collection ctx (granular call sites — handshake projector)
|
|
118
|
+
const colLabels = collectionCtx?.labels;
|
|
119
|
+
if (colLabels) {
|
|
120
|
+
const colVal = colLabels[form];
|
|
121
|
+
if (colVal !== undefined && colVal.length > 0)
|
|
122
|
+
return colVal;
|
|
123
|
+
}
|
|
124
|
+
// Layer 2.5: collection defaults from WorkspaceVocabCtx (threaded via chain.getVocabulary)
|
|
125
|
+
// New: wires the dead Layer 2 path for consumers that don't pass explicit collectionCtx.
|
|
126
|
+
const defaultLabels = workspaceCtx?.collectionDefaults?.[canonicalKey];
|
|
127
|
+
if (defaultLabels) {
|
|
128
|
+
const defVal = defaultLabels[form];
|
|
129
|
+
if (defVal !== undefined && defVal.length > 0)
|
|
130
|
+
return defVal;
|
|
131
|
+
}
|
|
132
|
+
// Layer 3: canonicalKey literal fallback
|
|
133
|
+
return canonicalKey;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Replace all {{vocab:<canonicalKey>.<form>}} tokens in a string.
|
|
137
|
+
*
|
|
138
|
+
* For each token, calls getCollectionLabel with the provided contexts.
|
|
139
|
+
* STD-253.
|
|
140
|
+
*/
|
|
141
|
+
export function replaceVocabTokens(body, workspaceCtx, collectionCtxMap) {
|
|
142
|
+
if (!body || body.length === 0)
|
|
143
|
+
return body;
|
|
144
|
+
const regex = new RegExp(VOCAB_TOKEN_REGEX.source, 'g');
|
|
145
|
+
return body.replace(regex, (_match, canonicalKey, form) => {
|
|
146
|
+
const collectionCtx = collectionCtxMap?.get(canonicalKey);
|
|
147
|
+
return getCollectionLabel(canonicalKey, form, workspaceCtx, collectionCtx);
|
|
148
|
+
});
|
|
149
|
+
}
|
|
83
150
|
//# sourceMappingURL=canonicalRefs.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canonicalRefs.js","sourceRoot":"","sources":["../../src/lib/canonicalRefs.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH
|
|
1
|
+
{"version":3,"file":"canonicalRefs.js","sourceRoot":"","sources":["../../src/lib/canonicalRefs.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/lib/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAAE,QAAQ,EAAa,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/lib/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,EAAE,QAAQ,EAAa,MAAM,aAAa,CAAC;AAKlD,uEAAuE;AACvE,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,SAAS,EAAE,eAAe,GAAG,gBAAgB,GAAG,UAAU,CAAC;IAC3D,OAAO,EAAE,MAAM,CAAC;CACjB;AAeD,kGAAkG;AAClG,qBAAa,QAAS,SAAQ,QAAQ;IACpC,OAAO,CAAC,EAAE,qBAAqB,EAAE,CAAC;gBAEtB,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB,EAAE;CAQ9E;AA2DD,gFAAgF;AAChF,MAAM,MAAM,iBAAiB,GACzB;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GACpC;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpC;;;;;;;GAOG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,SAAS,SAAO,GACf,OAAO,CAAC,iBAAiB,CAAC,CAqC5B;AA0BD,mEAAmE;AACnE,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;;;;;GAMG;AACH,wBAAsB,SAAS,CAC7B,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,OAAO,CAAC,OAAO,CAAC,CAsBlB;AAED,wBAAsB,UAAU,CAAC,CAAC,GAAG,OAAO,EAC1C,EAAE,EAAE,MAAM,EACV,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACjC,OAAO,CAAC,CAAC,CAAC,CAyBZ;AA0BD;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CAAC,CAAC,GAAG,OAAO,EACrD,EAAE,EAAE,MAAM,EACV,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GACjC,OAAO,CAAC,CAAC,CAAC,CAwCZ"}
|
package/dist/lib/client.js
CHANGED
|
@@ -13,6 +13,7 @@ import { getConfig, resolveAdminConfig } from './config.js';
|
|
|
13
13
|
import { readSession } from './session.js';
|
|
14
14
|
import { CLIError, ErrorCode } from './errors.js';
|
|
15
15
|
import { withSpinner } from './spinner.js';
|
|
16
|
+
import { recordServerLatest } from './update-check.js';
|
|
16
17
|
/**
|
|
17
18
|
* Map MCP server error codes to CLIError categories.
|
|
18
19
|
* Keeps backward compat: McpError.code is still a free string from the server,
|
|
@@ -41,6 +42,13 @@ export class McpError extends CLIError {
|
|
|
41
42
|
this.details = details;
|
|
42
43
|
}
|
|
43
44
|
}
|
|
45
|
+
function recordLatestFromResponse(res) {
|
|
46
|
+
recordServerLatest(res.headers?.get?.('pb-latest-cli-version') ?? null);
|
|
47
|
+
}
|
|
48
|
+
async function parseKernelEnvelope(res) {
|
|
49
|
+
recordLatestFromResponse(res);
|
|
50
|
+
return (await res.json().catch(() => ({})));
|
|
51
|
+
}
|
|
44
52
|
// Configure proxy at module load — runs once, before any fetch call.
|
|
45
53
|
// Node.js fetch (undici) ignores HTTPS_PROXY env vars. We detect the proxy
|
|
46
54
|
// and install a ProxyAgent as the global dispatcher so all fetch() calls
|
|
@@ -101,10 +109,12 @@ export async function validateKey(apiKey, siteUrl, timeoutMs = 5000) {
|
|
|
101
109
|
signal: controller.signal,
|
|
102
110
|
});
|
|
103
111
|
clearTimeout(timer);
|
|
112
|
+
// Record header BEFORE the 401/403 short-circuit — auth-fail responses still carry the version skew signal.
|
|
113
|
+
recordLatestFromResponse(res);
|
|
104
114
|
if (res.status === 401 || res.status === 403) {
|
|
105
115
|
return { valid: false, error: 'Invalid API key.' };
|
|
106
116
|
}
|
|
107
|
-
const envelope =
|
|
117
|
+
const envelope = await parseKernelEnvelope(res);
|
|
108
118
|
if (!res.ok || envelope.ok === false) {
|
|
109
119
|
return { valid: false, error: envelope.message || envelope.error || `Server error (${res.status})` };
|
|
110
120
|
}
|
|
@@ -191,7 +201,7 @@ export async function kernelCall(fn, args = {}) {
|
|
|
191
201
|
catch (err) {
|
|
192
202
|
rethrowWithGuidance(err, siteUrl);
|
|
193
203
|
}
|
|
194
|
-
const envelope =
|
|
204
|
+
const envelope = await parseKernelEnvelope(res);
|
|
195
205
|
if (!res.ok || envelope.ok === false) {
|
|
196
206
|
throw new McpError(envelope.message || envelope.error || res.statusText, envelope.code, envelope.details);
|
|
197
207
|
}
|
|
@@ -250,7 +260,7 @@ export async function kernelCallWithSession(fn, args = {}) {
|
|
|
250
260
|
catch (err) {
|
|
251
261
|
rethrowWithGuidance(err, siteUrl);
|
|
252
262
|
}
|
|
253
|
-
const envelope =
|
|
263
|
+
const envelope = await parseKernelEnvelope(res);
|
|
254
264
|
if (!res.ok || envelope.ok === false) {
|
|
255
265
|
throw new McpError(envelope.message || envelope.error || res.statusText, envelope.code, envelope.details);
|
|
256
266
|
}
|
package/dist/lib/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/lib/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAElD,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/lib/client.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/config.d.ts
CHANGED
|
@@ -25,11 +25,29 @@ interface ProjectConfig {
|
|
|
25
25
|
/** Local project config shape — .productbrain/config.local.json (gitignored, machine-local) */
|
|
26
26
|
interface LocalProjectConfig {
|
|
27
27
|
profile?: string;
|
|
28
|
+
/** Direct preview API key — set by `npm run pb:preview`, cleared by `npm run pb:real`. */
|
|
29
|
+
apiKey?: string;
|
|
30
|
+
/** Preview site URL — set alongside apiKey by `npm run pb:preview`. */
|
|
31
|
+
siteUrl?: string;
|
|
32
|
+
/** Marks this config as preview-bound; the CLI shows a loud banner on every command. */
|
|
33
|
+
preview?: boolean;
|
|
34
|
+
/** Human-readable preview workspace name for the banner (e.g. "Preview Workspace"). */
|
|
35
|
+
workspaceName?: string;
|
|
28
36
|
}
|
|
29
37
|
/**
|
|
30
|
-
* Walk up the directory tree (git-style) to find the nearest
|
|
31
|
-
*
|
|
32
|
-
*
|
|
38
|
+
* Walk up the directory tree (git-style) to find the nearest CLI project root.
|
|
39
|
+
*
|
|
40
|
+
* A `.productbrain/` directory only counts as a CLI project root when it carries
|
|
41
|
+
* CLI configuration — `config.json` (committed siteUrl gateway) or
|
|
42
|
+
* `config.local.json` (machine-local profile pin or preview binding). A
|
|
43
|
+
* projection-only `.productbrain/` written by `pb handshake` (briefing.md,
|
|
44
|
+
* context.md, rules/, etc.) does NOT count — otherwise a subrepo like
|
|
45
|
+
* `packages/cli/.productbrain/` would shadow the real configuring root and
|
|
46
|
+
* `npm run pb:preview` writes (which always land at the repo-root
|
|
47
|
+
* `.productbrain/`) would be invisible to commands run from the subrepo.
|
|
48
|
+
*
|
|
49
|
+
* Stops at home directory or filesystem root. Returns the directory containing
|
|
50
|
+
* a config-bearing `.productbrain/`, or null if not found.
|
|
33
51
|
*/
|
|
34
52
|
export declare function findProjectRoot(startDir: string): string | null;
|
|
35
53
|
/**
|
|
@@ -41,11 +59,90 @@ export declare function findProjectRoot(startDir: string): string | null;
|
|
|
41
59
|
declare function readProjectConfig(): ProjectConfig | null;
|
|
42
60
|
/**
|
|
43
61
|
* Read .productbrain/config.local.json from the walked-up project root.
|
|
44
|
-
*
|
|
62
|
+
* Returns the machine-local pin (`profile`) and any preview-binding fields
|
|
63
|
+
* (`apiKey`, `siteUrl`, `preview`, `workspaceName`) written by
|
|
64
|
+
* `npm run pb:preview` — all gitignored, never committed.
|
|
45
65
|
* Returns null if file missing or project root not found.
|
|
46
66
|
* Warns to stderr on invalid JSON but does not throw.
|
|
47
67
|
*/
|
|
48
68
|
export declare function readLocalProjectConfig(): LocalProjectConfig | null;
|
|
69
|
+
/**
|
|
70
|
+
* Returns the preview binding metadata when pb is currently bound to a throwaway preview,
|
|
71
|
+
* or null when bound to the real Chain (the default).
|
|
72
|
+
*
|
|
73
|
+
* Effective-binding mirror: this only reports a preview binding when
|
|
74
|
+
* `resolveConfig()`/`loadEnv()` would actually honor it — `preview === true` AND
|
|
75
|
+
* an atomic apiKey+siteUrl pair (SF-3) AND no `PRODUCTBRAIN_API_KEY` env override
|
|
76
|
+
* (env always wins in resolveConfig step 1). Without these guards the PREVIEW
|
|
77
|
+
* banner could fire while writes still hit the real Chain, defeating the safety
|
|
78
|
+
* warning. Used by the PREVIEW banner (index.ts preAction hook) and the
|
|
79
|
+
* capture/update advisory.
|
|
80
|
+
*
|
|
81
|
+
* Security classification: reads only the gitignored machine-local config.local.json.
|
|
82
|
+
* The preview key in that file is a throwaway preview-scoped key, set by explicit
|
|
83
|
+
* `npm run pb:preview` opt-in and reversed by `npm run pb:real`. Never throws — returns
|
|
84
|
+
* null on any error so the banner/advisory path is never the source of a CLI crash.
|
|
85
|
+
*/
|
|
86
|
+
export declare function getPreviewBinding(): {
|
|
87
|
+
workspaceName: string | null;
|
|
88
|
+
} | null;
|
|
89
|
+
/**
|
|
90
|
+
* Write/merge the profile pin into <projectRoot>/.productbrain/config.local.json,
|
|
91
|
+
* preserving any sibling keys. Single source of truth for the local pin write —
|
|
92
|
+
* used by `pb profile use --local`, the default reconcile path, and `pb connect`.
|
|
93
|
+
*
|
|
94
|
+
* Co-writer note (SF-2): scripts/pb-binding.mjs is the OTHER writer of config.local.json — it
|
|
95
|
+
* merges/strips the preview-binding keys (apiKey, siteUrl, preview, workspaceName) for
|
|
96
|
+
* `npm run pb:preview` / `npm run pb:real`. Both writers preserve the `profile` pin. If you add
|
|
97
|
+
* a preview-scoped key here or in readLocalProjectConfig(), update pb-binding.mjs's PREVIEW_KEYS.
|
|
98
|
+
*/
|
|
99
|
+
export declare function setLocalProfilePin(projectRoot: string, profile: string): void;
|
|
100
|
+
/**
|
|
101
|
+
* Outcome of a preview apiKey refresh attempt (WP-458 E2). The discriminated result lets the
|
|
102
|
+
* caller (session.ts) react precisely instead of conflating "couldn't recover" with "the failure
|
|
103
|
+
* wasn't a stale key at all":
|
|
104
|
+
* - 'refreshed' — a DIFFERENT valid key was loaded; a retry is worthwhile.
|
|
105
|
+
* - 'unchanged' — preview.json's key already matches the bound key, so the auth/INTERNAL failure
|
|
106
|
+
* is NOT a stale-key problem. The caller must surface the ORIGINAL error rather
|
|
107
|
+
* than relabel it (the reviewer's no-masking concern; R2 honesty).
|
|
108
|
+
* - 'unavailable' — preview-bound but preview.json is missing/malformed/lacks a valid key, so the
|
|
109
|
+
* stale binding cannot be recovered. The caller surfaces a clean, actionable
|
|
110
|
+
* error (doneWhen #1: no opaque INTERNAL).
|
|
111
|
+
* - 'not-bound' — not a preview binding, or a genuine env override is in play; leave the error
|
|
112
|
+
* untouched.
|
|
113
|
+
*/
|
|
114
|
+
export type PreviewKeyRefresh = 'refreshed' | 'unchanged' | 'unavailable' | 'not-bound';
|
|
115
|
+
/**
|
|
116
|
+
* WP-458 E2 — one-shot preview apiKey refresh from disk.
|
|
117
|
+
*
|
|
118
|
+
* After a worktree preview is reseeded, seed-preview.mjs Step 6 mints a NEW apiKey into
|
|
119
|
+
* `.productbrain/preview.json`, but `config.local.json` (and the live `process.env` binding it
|
|
120
|
+
* seeded via loadEnv) still carry the PRE-reseed key — so the next `pb session start` fails auth
|
|
121
|
+
* with an opaque INTERNAL. This re-reads the fresh key from preview.json so the caller can retry
|
|
122
|
+
* ONCE (session.ts). It is deliberately disk-to-disk: it compares preview.json's key against
|
|
123
|
+
* config.local.json's bound key, NOT against process.env (which loadEnv already populated from the
|
|
124
|
+
* stale binding), so it can't be confused by its own prior population. Never throws — any error
|
|
125
|
+
* degrades to 'unavailable'/'not-bound' so it can sit on the session-start path.
|
|
126
|
+
*
|
|
127
|
+
* Co-writer note (SF-2): mirrors pb-binding.mjs / setLocalProfilePin — preserves every sibling key
|
|
128
|
+
* in config.local.json (profile, preview, workspaceName) and only rewrites apiKey + siteUrl.
|
|
129
|
+
*/
|
|
130
|
+
export declare function refreshPreviewApiKeyFromDisk(): PreviewKeyRefresh;
|
|
131
|
+
/** Source of the effective profile, in resolution-precedence order. */
|
|
132
|
+
export type EffectiveProfileSource = 'env' | 'local' | 'global' | 'default' | 'none';
|
|
133
|
+
/**
|
|
134
|
+
* Resolve the effective profile NAME + where it came from. The SOURCE-PRECEDENCE
|
|
135
|
+
* ORDER matches resolveConfig() (env > local pin > global > default), but unlike
|
|
136
|
+
* resolveConfig() this reports the *configured* pin name even when that profile is
|
|
137
|
+
* unresolvable (deleted / missing key). That divergence is intentional: a dangling
|
|
138
|
+
* repo pin must be surfaced by `pb whoami`, not silently masked by the global
|
|
139
|
+
* profile — masking it is the TEN-2163 silent-drift bug. Used by `pb whoami` and
|
|
140
|
+
* the inline "now using" prints.
|
|
141
|
+
*/
|
|
142
|
+
export declare function resolveEffectiveProfile(): {
|
|
143
|
+
profile: string | null;
|
|
144
|
+
source: EffectiveProfileSource;
|
|
145
|
+
};
|
|
49
146
|
/** Config source in resolution priority order. */
|
|
50
147
|
export type ConfigSource = 'env' | 'project' | 'profile' | 'cwd' | 'default';
|
|
51
148
|
/** Result of the full config resolution cascade. */
|
package/dist/lib/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAWH,QAAA,MAAM,eAAe,QAAgD,CAAC;AACtE,QAAA,MAAM,aAAa,QAAmC,CAAC;AAUvD,iFAAiF;AACjF,UAAU,aAAa;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,+FAA+F;AAC/F,UAAU,kBAAkB;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/config.js
CHANGED
|
@@ -21,7 +21,7 @@ import { resolve } from 'path';
|
|
|
21
21
|
import { homedir } from 'os';
|
|
22
22
|
import { DEFAULT_SITE_URL, isDevMode } from './constants.js';
|
|
23
23
|
import { API_KEY_PREFIX } from './tokenConstants.js';
|
|
24
|
-
import { resolveProfileConfig, resolveNamedProfileConfig } from './profiles.js';
|
|
24
|
+
import { resolveProfileConfig, resolveNamedProfileConfig, getGlobalActiveProfile } from './profiles.js';
|
|
25
25
|
import { CLIError, ErrorCode } from './errors.js';
|
|
26
26
|
import { confirm as promptConfirm, password as promptPassword } from './prompts.js';
|
|
27
27
|
const HOME_CONFIG_DIR = resolve(homedir(), '.config', 'productbrain');
|
|
@@ -32,16 +32,30 @@ const NON_TTY_MESSAGE = 'No API key. Set PRODUCTBRAIN_API_KEY or run pb login.';
|
|
|
32
32
|
/** Track whether env has been loaded to avoid redundant file reads. */
|
|
33
33
|
let envLoaded = false;
|
|
34
34
|
/**
|
|
35
|
-
* Walk up the directory tree (git-style) to find the nearest
|
|
36
|
-
*
|
|
37
|
-
*
|
|
35
|
+
* Walk up the directory tree (git-style) to find the nearest CLI project root.
|
|
36
|
+
*
|
|
37
|
+
* A `.productbrain/` directory only counts as a CLI project root when it carries
|
|
38
|
+
* CLI configuration — `config.json` (committed siteUrl gateway) or
|
|
39
|
+
* `config.local.json` (machine-local profile pin or preview binding). A
|
|
40
|
+
* projection-only `.productbrain/` written by `pb handshake` (briefing.md,
|
|
41
|
+
* context.md, rules/, etc.) does NOT count — otherwise a subrepo like
|
|
42
|
+
* `packages/cli/.productbrain/` would shadow the real configuring root and
|
|
43
|
+
* `npm run pb:preview` writes (which always land at the repo-root
|
|
44
|
+
* `.productbrain/`) would be invisible to commands run from the subrepo.
|
|
45
|
+
*
|
|
46
|
+
* Stops at home directory or filesystem root. Returns the directory containing
|
|
47
|
+
* a config-bearing `.productbrain/`, or null if not found.
|
|
38
48
|
*/
|
|
39
49
|
export function findProjectRoot(startDir) {
|
|
40
50
|
let dir = startDir;
|
|
41
51
|
const home = homedir();
|
|
42
52
|
while (true) {
|
|
43
|
-
|
|
53
|
+
const pbDir = resolve(dir, '.productbrain');
|
|
54
|
+
if (existsSync(pbDir) &&
|
|
55
|
+
(existsSync(resolve(pbDir, 'config.json')) ||
|
|
56
|
+
existsSync(resolve(pbDir, 'config.local.json')))) {
|
|
44
57
|
return dir;
|
|
58
|
+
}
|
|
45
59
|
const parent = resolve(dir, '..');
|
|
46
60
|
if (parent === dir || dir === home)
|
|
47
61
|
return null;
|
|
@@ -82,7 +96,9 @@ function readProjectConfig() {
|
|
|
82
96
|
}
|
|
83
97
|
/**
|
|
84
98
|
* Read .productbrain/config.local.json from the walked-up project root.
|
|
85
|
-
*
|
|
99
|
+
* Returns the machine-local pin (`profile`) and any preview-binding fields
|
|
100
|
+
* (`apiKey`, `siteUrl`, `preview`, `workspaceName`) written by
|
|
101
|
+
* `npm run pb:preview` — all gitignored, never committed.
|
|
86
102
|
* Returns null if file missing or project root not found.
|
|
87
103
|
* Warns to stderr on invalid JSON but does not throw.
|
|
88
104
|
*/
|
|
@@ -104,6 +120,19 @@ export function readLocalProjectConfig() {
|
|
|
104
120
|
if (typeof parsed.profile === 'string' && parsed.profile) {
|
|
105
121
|
result.profile = parsed.profile;
|
|
106
122
|
}
|
|
123
|
+
// Preview binding fields — written by `npm run pb:preview`, cleared by `npm run pb:real`.
|
|
124
|
+
if (typeof parsed.apiKey === 'string' && parsed.apiKey.startsWith(API_KEY_PREFIX)) {
|
|
125
|
+
result.apiKey = parsed.apiKey;
|
|
126
|
+
}
|
|
127
|
+
if (typeof parsed.siteUrl === 'string' && parsed.siteUrl) {
|
|
128
|
+
result.siteUrl = parsed.siteUrl;
|
|
129
|
+
}
|
|
130
|
+
if (parsed.preview === true) {
|
|
131
|
+
result.preview = true;
|
|
132
|
+
}
|
|
133
|
+
if (typeof parsed.workspaceName === 'string' && parsed.workspaceName) {
|
|
134
|
+
result.workspaceName = parsed.workspaceName;
|
|
135
|
+
}
|
|
107
136
|
return result;
|
|
108
137
|
}
|
|
109
138
|
catch {
|
|
@@ -111,6 +140,159 @@ export function readLocalProjectConfig() {
|
|
|
111
140
|
return null;
|
|
112
141
|
}
|
|
113
142
|
}
|
|
143
|
+
/**
|
|
144
|
+
* Returns the preview binding metadata when pb is currently bound to a throwaway preview,
|
|
145
|
+
* or null when bound to the real Chain (the default).
|
|
146
|
+
*
|
|
147
|
+
* Effective-binding mirror: this only reports a preview binding when
|
|
148
|
+
* `resolveConfig()`/`loadEnv()` would actually honor it — `preview === true` AND
|
|
149
|
+
* an atomic apiKey+siteUrl pair (SF-3) AND no `PRODUCTBRAIN_API_KEY` env override
|
|
150
|
+
* (env always wins in resolveConfig step 1). Without these guards the PREVIEW
|
|
151
|
+
* banner could fire while writes still hit the real Chain, defeating the safety
|
|
152
|
+
* warning. Used by the PREVIEW banner (index.ts preAction hook) and the
|
|
153
|
+
* capture/update advisory.
|
|
154
|
+
*
|
|
155
|
+
* Security classification: reads only the gitignored machine-local config.local.json.
|
|
156
|
+
* The preview key in that file is a throwaway preview-scoped key, set by explicit
|
|
157
|
+
* `npm run pb:preview` opt-in and reversed by `npm run pb:real`. Never throws — returns
|
|
158
|
+
* null on any error so the banner/advisory path is never the source of a CLI crash.
|
|
159
|
+
*/
|
|
160
|
+
export function getPreviewBinding() {
|
|
161
|
+
try {
|
|
162
|
+
if (process.env.PRODUCTBRAIN_API_KEY)
|
|
163
|
+
return null;
|
|
164
|
+
const localConfig = readLocalProjectConfig();
|
|
165
|
+
if (localConfig?.preview === true && localConfig.apiKey && localConfig.siteUrl) {
|
|
166
|
+
return { workspaceName: localConfig.workspaceName ?? null };
|
|
167
|
+
}
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Write/merge the profile pin into <projectRoot>/.productbrain/config.local.json,
|
|
176
|
+
* preserving any sibling keys. Single source of truth for the local pin write —
|
|
177
|
+
* used by `pb profile use --local`, the default reconcile path, and `pb connect`.
|
|
178
|
+
*
|
|
179
|
+
* Co-writer note (SF-2): scripts/pb-binding.mjs is the OTHER writer of config.local.json — it
|
|
180
|
+
* merges/strips the preview-binding keys (apiKey, siteUrl, preview, workspaceName) for
|
|
181
|
+
* `npm run pb:preview` / `npm run pb:real`. Both writers preserve the `profile` pin. If you add
|
|
182
|
+
* a preview-scoped key here or in readLocalProjectConfig(), update pb-binding.mjs's PREVIEW_KEYS.
|
|
183
|
+
*/
|
|
184
|
+
export function setLocalProfilePin(projectRoot, profile) {
|
|
185
|
+
const configDir = resolve(projectRoot, '.productbrain');
|
|
186
|
+
const localConfigPath = resolve(configDir, 'config.local.json');
|
|
187
|
+
let existing = {};
|
|
188
|
+
if (existsSync(localConfigPath)) {
|
|
189
|
+
try {
|
|
190
|
+
const parsed = JSON.parse(readFileSync(localConfigPath, 'utf8'));
|
|
191
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed))
|
|
192
|
+
existing = parsed;
|
|
193
|
+
}
|
|
194
|
+
catch { /* ignore parse errors — we overwrite the pin below */ }
|
|
195
|
+
}
|
|
196
|
+
mkdirSync(configDir, { recursive: true });
|
|
197
|
+
writeFileSync(localConfigPath, JSON.stringify({ ...existing, profile }, null, 2) + '\n');
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* WP-458 E2 — one-shot preview apiKey refresh from disk.
|
|
201
|
+
*
|
|
202
|
+
* After a worktree preview is reseeded, seed-preview.mjs Step 6 mints a NEW apiKey into
|
|
203
|
+
* `.productbrain/preview.json`, but `config.local.json` (and the live `process.env` binding it
|
|
204
|
+
* seeded via loadEnv) still carry the PRE-reseed key — so the next `pb session start` fails auth
|
|
205
|
+
* with an opaque INTERNAL. This re-reads the fresh key from preview.json so the caller can retry
|
|
206
|
+
* ONCE (session.ts). It is deliberately disk-to-disk: it compares preview.json's key against
|
|
207
|
+
* config.local.json's bound key, NOT against process.env (which loadEnv already populated from the
|
|
208
|
+
* stale binding), so it can't be confused by its own prior population. Never throws — any error
|
|
209
|
+
* degrades to 'unavailable'/'not-bound' so it can sit on the session-start path.
|
|
210
|
+
*
|
|
211
|
+
* Co-writer note (SF-2): mirrors pb-binding.mjs / setLocalProfilePin — preserves every sibling key
|
|
212
|
+
* in config.local.json (profile, preview, workspaceName) and only rewrites apiKey + siteUrl.
|
|
213
|
+
*/
|
|
214
|
+
export function refreshPreviewApiKeyFromDisk() {
|
|
215
|
+
try {
|
|
216
|
+
const projectRoot = findProjectRoot(process.cwd());
|
|
217
|
+
if (!projectRoot)
|
|
218
|
+
return 'not-bound';
|
|
219
|
+
const local = readLocalProjectConfig();
|
|
220
|
+
// Only act on a real preview binding (preview:true + atomic apiKey+siteUrl pair, SF-3).
|
|
221
|
+
if (!local?.preview || !local.apiKey || !local.siteUrl)
|
|
222
|
+
return 'not-bound';
|
|
223
|
+
// Never clobber a genuine env override: if the live key is NOT the bound preview key, either
|
|
224
|
+
// the user exported their own PRODUCTBRAIN_API_KEY (env wins in resolveConfig) or a refresh
|
|
225
|
+
// already happened — bail either way. An unset env key is fine (loadEnv may not have run yet).
|
|
226
|
+
const liveKey = process.env.PRODUCTBRAIN_API_KEY;
|
|
227
|
+
if (liveKey && liveKey !== local.apiKey)
|
|
228
|
+
return 'not-bound';
|
|
229
|
+
// Read the freshly-minted key from preview.json (seed-preview.mjs Step 6).
|
|
230
|
+
const previewPath = resolve(projectRoot, '.productbrain', 'preview.json');
|
|
231
|
+
if (!existsSync(previewPath))
|
|
232
|
+
return 'unavailable';
|
|
233
|
+
let fresh;
|
|
234
|
+
try {
|
|
235
|
+
const parsed = JSON.parse(readFileSync(previewPath, 'utf8'));
|
|
236
|
+
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed))
|
|
237
|
+
return 'unavailable';
|
|
238
|
+
fresh = parsed;
|
|
239
|
+
}
|
|
240
|
+
catch {
|
|
241
|
+
return 'unavailable';
|
|
242
|
+
}
|
|
243
|
+
const freshKey = typeof fresh.apiKey === 'string' ? fresh.apiKey : '';
|
|
244
|
+
if (!freshKey.startsWith(API_KEY_PREFIX))
|
|
245
|
+
return 'unavailable';
|
|
246
|
+
// Same key as the one already bound — retrying would just fail again; the failure is not a
|
|
247
|
+
// stale key, so the caller surfaces the real error rather than relabelling it.
|
|
248
|
+
if (freshKey === local.apiKey)
|
|
249
|
+
return 'unchanged';
|
|
250
|
+
const freshSite = typeof fresh.siteUrl === 'string' && fresh.siteUrl ? fresh.siteUrl : local.siteUrl;
|
|
251
|
+
// Merge the fresh preview key into config.local.json, preserving siblings.
|
|
252
|
+
const localConfigPath = resolve(projectRoot, '.productbrain', 'config.local.json');
|
|
253
|
+
let existing = {};
|
|
254
|
+
if (existsSync(localConfigPath)) {
|
|
255
|
+
try {
|
|
256
|
+
const parsed = JSON.parse(readFileSync(localConfigPath, 'utf8'));
|
|
257
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed))
|
|
258
|
+
existing = parsed;
|
|
259
|
+
}
|
|
260
|
+
catch { /* overwrite below */ }
|
|
261
|
+
}
|
|
262
|
+
writeFileSync(localConfigPath, JSON.stringify({ ...existing, apiKey: freshKey, siteUrl: freshSite }, null, 2) + '\n');
|
|
263
|
+
// Update the live binding + drop the load cache so the next getConfig() uses the fresh key.
|
|
264
|
+
process.env.PRODUCTBRAIN_API_KEY = freshKey;
|
|
265
|
+
process.env.CONVEX_SITE_URL = freshSite.replace(/\/$/, '');
|
|
266
|
+
resetConfigCache();
|
|
267
|
+
return 'refreshed';
|
|
268
|
+
}
|
|
269
|
+
catch {
|
|
270
|
+
return 'unavailable';
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Resolve the effective profile NAME + where it came from. The SOURCE-PRECEDENCE
|
|
275
|
+
* ORDER matches resolveConfig() (env > local pin > global > default), but unlike
|
|
276
|
+
* resolveConfig() this reports the *configured* pin name even when that profile is
|
|
277
|
+
* unresolvable (deleted / missing key). That divergence is intentional: a dangling
|
|
278
|
+
* repo pin must be surfaced by `pb whoami`, not silently masked by the global
|
|
279
|
+
* profile — masking it is the TEN-2163 silent-drift bug. Used by `pb whoami` and
|
|
280
|
+
* the inline "now using" prints.
|
|
281
|
+
*/
|
|
282
|
+
export function resolveEffectiveProfile() {
|
|
283
|
+
const envProfile = process.env.PB_PROFILE?.trim();
|
|
284
|
+
if (envProfile)
|
|
285
|
+
return { profile: envProfile, source: 'env' };
|
|
286
|
+
const localProfile = readLocalProjectConfig()?.profile;
|
|
287
|
+
if (localProfile)
|
|
288
|
+
return { profile: localProfile, source: 'local' };
|
|
289
|
+
const globalProfile = getGlobalActiveProfile();
|
|
290
|
+
if (globalProfile)
|
|
291
|
+
return { profile: globalProfile, source: 'global' };
|
|
292
|
+
if (resolveNamedProfileConfig('default'))
|
|
293
|
+
return { profile: 'default', source: 'default' };
|
|
294
|
+
return { profile: null, source: 'none' };
|
|
295
|
+
}
|
|
114
296
|
/**
|
|
115
297
|
* Run the full config resolution cascade and return a typed result.
|
|
116
298
|
* Resolution order:
|
|
@@ -134,8 +316,26 @@ export function resolveConfig() {
|
|
|
134
316
|
source: 'env',
|
|
135
317
|
};
|
|
136
318
|
}
|
|
137
|
-
// 2. Local project config — profile pin
|
|
319
|
+
// 2. Local project config — check for direct preview binding first, then profile pin.
|
|
138
320
|
const localConfig = readLocalProjectConfig();
|
|
321
|
+
// 2a. Direct preview binding (config.local.json apiKey) — set by `npm run pb:preview`.
|
|
322
|
+
// Security classification: gitignored machine-local file; throwaway preview-scoped key;
|
|
323
|
+
// explicit opt-in via `npm run pb:preview`; reversible via `npm run pb:real`;
|
|
324
|
+
// loud PREVIEW banner on every command makes it un-missable (index.ts preAction hook).
|
|
325
|
+
//
|
|
326
|
+
// Atomic apiKey+siteUrl (SF-3): only honor the preview key when its OWN siteUrl is present.
|
|
327
|
+
// Never let a preview key borrow config.json's (real-dev) siteUrl — that would send a
|
|
328
|
+
// preview credential to a non-preview gateway (STD-261). If siteUrl is absent we skip this
|
|
329
|
+
// branch and fall through to the profile pin / default, so it is impossible by construction
|
|
330
|
+
// for a `preview:true` key to be paired with the committed real-dev gateway.
|
|
331
|
+
if (localConfig?.apiKey && localConfig.siteUrl) {
|
|
332
|
+
return {
|
|
333
|
+
apiKey: localConfig.apiKey,
|
|
334
|
+
siteUrl: localConfig.siteUrl.replace(/\/$/, ''),
|
|
335
|
+
source: 'project',
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
// 2b. Profile pin (config.local.json profile field, gitignored)
|
|
139
339
|
if (localConfig?.profile) {
|
|
140
340
|
const namedConfig = resolveNamedProfileConfig(localConfig.profile);
|
|
141
341
|
if (namedConfig?.apiKey) {
|
|
@@ -216,21 +416,35 @@ function loadEnv() {
|
|
|
216
416
|
if (envLoaded)
|
|
217
417
|
return;
|
|
218
418
|
envLoaded = true;
|
|
219
|
-
// 1. Try local project config first (profile pin, config.local.json)
|
|
419
|
+
// 1. Try local project config first (preview binding or profile pin, config.local.json)
|
|
220
420
|
const localConfig = readLocalProjectConfig();
|
|
421
|
+
// 1a. Direct preview binding — set by `npm run pb:preview`, takes priority over profile pin.
|
|
422
|
+
// Atomic apiKey+siteUrl (SF-3): only bind the preview key when its OWN siteUrl is present —
|
|
423
|
+
// never let it fall through to config.json's (real-dev) siteUrl (STD-261). Mirror of the
|
|
424
|
+
// resolveConfig() 2a guard so loadEnv() and resolveConfig() agree on what counts as a binding.
|
|
425
|
+
if (localConfig?.apiKey && localConfig.siteUrl && !process.env.PRODUCTBRAIN_API_KEY) {
|
|
426
|
+
process.env.PRODUCTBRAIN_API_KEY = localConfig.apiKey;
|
|
427
|
+
// SF-3 atomic pair: when we accept the preview key, we MUST pair it with
|
|
428
|
+
// its OWN siteUrl — even if CONVEX_SITE_URL is already exported. Otherwise
|
|
429
|
+
// a stale/real exported CONVEX_SITE_URL would silently route the preview
|
|
430
|
+
// credential to a non-preview gateway. Mirror of resolveConfig() step 2a,
|
|
431
|
+
// which returns localConfig.siteUrl unconditionally inside this branch.
|
|
432
|
+
process.env.CONVEX_SITE_URL = localConfig.siteUrl.replace(/\/$/, '');
|
|
433
|
+
}
|
|
434
|
+
// 1b. Profile pin
|
|
221
435
|
if (localConfig?.profile && !process.env.PRODUCTBRAIN_API_KEY) {
|
|
222
436
|
const namedConfig = resolveNamedProfileConfig(localConfig.profile);
|
|
223
437
|
if (namedConfig?.apiKey) {
|
|
224
438
|
process.env.PRODUCTBRAIN_API_KEY = namedConfig.apiKey;
|
|
225
439
|
if (!process.env.CONVEX_SITE_URL && namedConfig.siteUrl) {
|
|
226
|
-
process.env.CONVEX_SITE_URL = namedConfig.siteUrl;
|
|
440
|
+
process.env.CONVEX_SITE_URL = namedConfig.siteUrl.replace(/\/$/, '');
|
|
227
441
|
}
|
|
228
442
|
}
|
|
229
443
|
}
|
|
230
444
|
// 1b. Apply siteUrl from config.json (gateway override — no apiKey reading here)
|
|
231
445
|
const projectConfig = readProjectConfig();
|
|
232
446
|
if (projectConfig?.siteUrl && !process.env.CONVEX_SITE_URL) {
|
|
233
|
-
process.env.CONVEX_SITE_URL = projectConfig.siteUrl;
|
|
447
|
+
process.env.CONVEX_SITE_URL = projectConfig.siteUrl.replace(/\/$/, '');
|
|
234
448
|
}
|
|
235
449
|
// 2. Try profile system (handles auto-migration from legacy .env)
|
|
236
450
|
const profileConfig = resolveProfileConfig();
|
|
@@ -240,7 +454,7 @@ function loadEnv() {
|
|
|
240
454
|
process.env.PRODUCTBRAIN_API_KEY = profileConfig.apiKey;
|
|
241
455
|
}
|
|
242
456
|
if (!process.env.CONVEX_SITE_URL && profileConfig.siteUrl) {
|
|
243
|
-
process.env.CONVEX_SITE_URL = profileConfig.siteUrl;
|
|
457
|
+
process.env.CONVEX_SITE_URL = profileConfig.siteUrl.replace(/\/$/, '');
|
|
244
458
|
}
|
|
245
459
|
}
|
|
246
460
|
// 3. Legacy home config (in case profiles didn't find it)
|