@productbrain/cli 0.1.0-beta.91 → 0.1.0-beta.917
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__/authority-domains.test.d.ts +2 -0
- package/dist/__tests__/authority-domains.test.d.ts.map +1 -0
- package/dist/__tests__/authority-domains.test.js +48 -0
- package/dist/__tests__/authority-domains.test.js.map +1 -0
- 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.d.ts +1 -1
- package/dist/__tests__/config.test.js +410 -10
- 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.d.ts +15 -0
- package/dist/__tests__/envelope-contract.test.d.ts.map +1 -0
- package/dist/__tests__/envelope-contract.test.js +152 -0
- package/dist/__tests__/envelope-contract.test.js.map +1 -0
- 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 +688 -3
- 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 +611 -2
- 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__/onboarding-path-b.test.js +4 -4
- package/dist/__tests__/onboarding-path-b.test.js.map +1 -1
- package/dist/__tests__/orient.test.js +135 -8
- 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__/personal-layer.test.d.ts +1 -2
- package/dist/__tests__/personal-layer.test.d.ts.map +1 -1
- package/dist/__tests__/personal-layer.test.js +12 -48
- package/dist/__tests__/personal-layer.test.js.map +1 -1
- package/dist/__tests__/profiles.test.js +153 -5
- package/dist/__tests__/profiles.test.js.map +1 -1
- package/dist/__tests__/promote.test.js +71 -2
- package/dist/__tests__/promote.test.js.map +1 -1
- 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 +129 -0
- package/dist/__tests__/session-switch.test.js.map +1 -0
- package/dist/__tests__/setup-ingest.test.d.ts +2 -0
- package/dist/__tests__/setup-ingest.test.d.ts.map +1 -0
- package/dist/__tests__/setup-ingest.test.js +71 -0
- package/dist/__tests__/setup-ingest.test.js.map +1 -0
- package/dist/__tests__/setup-resolver.test.d.ts +14 -0
- package/dist/__tests__/setup-resolver.test.d.ts.map +1 -0
- package/dist/__tests__/setup-resolver.test.js +228 -0
- package/dist/__tests__/setup-resolver.test.js.map +1 -0
- 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 +56 -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 +42 -0
- package/dist/__tests__/upgrade-runner.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/__tests__/workspace.test.js +32 -12
- package/dist/__tests__/workspace.test.js.map +1 -1
- 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 +46 -2
- package/dist/commands/admin/seed.d.ts.map +1 -1
- package/dist/commands/admin/seed.js +475 -33
- package/dist/commands/admin/seed.js.map +1 -1
- package/dist/commands/admin/seed.test.d.ts +5 -0
- package/dist/commands/admin/seed.test.d.ts.map +1 -1
- package/dist/commands/admin/seed.test.js +67 -2
- 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 +146 -0
- package/dist/commands/authority-domains.d.ts.map +1 -0
- package/dist/commands/authority-domains.js +282 -0
- package/dist/commands/authority-domains.js.map +1 -0
- package/dist/commands/capture.d.ts.map +1 -1
- package/dist/commands/capture.js +3 -2
- package/dist/commands/capture.js.map +1 -1
- package/dist/commands/codex-prep.d.ts +1 -0
- package/dist/commands/codex-prep.d.ts.map +1 -1
- package/dist/commands/codex-prep.js +10 -7
- 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 +29 -12
- package/dist/commands/connect-integration.test.js.map +1 -1
- package/dist/commands/connect-screens.d.ts +6 -4
- package/dist/commands/connect-screens.d.ts.map +1 -1
- package/dist/commands/connect-screens.js +30 -19
- package/dist/commands/connect-screens.js.map +1 -1
- package/dist/commands/connect.d.ts +21 -6
- package/dist/commands/connect.d.ts.map +1 -1
- package/dist/commands/connect.js +78 -51
- package/dist/commands/connect.js.map +1 -1
- package/dist/commands/connect.test.js +64 -1
- package/dist/commands/connect.test.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +68 -3
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/doctor.test.js +131 -0
- package/dist/commands/doctor.test.js.map +1 -1
- package/dist/commands/handshake.d.ts +194 -2
- package/dist/commands/handshake.d.ts.map +1 -1
- package/dist/commands/handshake.js +1738 -44
- package/dist/commands/handshake.js.map +1 -1
- package/dist/commands/method.d.ts.map +1 -1
- package/dist/commands/method.js +3 -0
- package/dist/commands/method.js.map +1 -1
- package/dist/commands/migrate-setup.d.ts +18 -0
- package/dist/commands/migrate-setup.d.ts.map +1 -0
- package/dist/commands/migrate-setup.js +198 -0
- package/dist/commands/migrate-setup.js.map +1 -0
- package/dist/commands/orient.d.ts +15 -2
- package/dist/commands/orient.d.ts.map +1 -1
- package/dist/commands/orient.js +86 -4
- package/dist/commands/orient.js.map +1 -1
- package/dist/commands/profile.d.ts +11 -1
- package/dist/commands/profile.d.ts.map +1 -1
- package/dist/commands/profile.js +109 -26
- package/dist/commands/profile.js.map +1 -1
- package/dist/commands/promote.d.ts.map +1 -1
- package/dist/commands/promote.js +25 -2
- package/dist/commands/promote.js.map +1 -1
- package/dist/commands/relate.d.ts.map +1 -1
- package/dist/commands/relate.js +13 -0
- package/dist/commands/relate.js.map +1 -1
- package/dist/commands/session.d.ts.map +1 -1
- package/dist/commands/session.js +55 -18
- 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 +17 -0
- package/dist/commands/setup-ingest.d.ts.map +1 -0
- package/dist/commands/setup-ingest.js +226 -0
- package/dist/commands/setup-ingest.js.map +1 -0
- package/dist/commands/setup-resolver.d.ts +58 -0
- package/dist/commands/setup-resolver.d.ts.map +1 -0
- package/dist/commands/setup-resolver.js +150 -0
- package/dist/commands/setup-resolver.js.map +1 -0
- 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/upgrade.d.ts +5 -0
- package/dist/commands/upgrade.d.ts.map +1 -0
- package/dist/commands/upgrade.js +89 -0
- package/dist/commands/upgrade.js.map +1 -0
- 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/commands/workspace.d.ts +74 -2
- package/dist/commands/workspace.d.ts.map +1 -1
- package/dist/commands/workspace.js +26 -2
- package/dist/commands/workspace.js.map +1 -1
- 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/handshake.d.ts +19 -3
- package/dist/formatters/handshake.d.ts.map +1 -1
- package/dist/formatters/handshake.js +48 -13
- package/dist/formatters/handshake.js.map +1 -1
- package/dist/formatters/orient.d.ts +50 -4
- package/dist/formatters/orient.d.ts.map +1 -1
- package/dist/formatters/orient.js +64 -16
- package/dist/formatters/orient.js.map +1 -1
- package/dist/formatters/session.js +1 -1
- package/dist/formatters/session.js.map +1 -1
- package/dist/generators/adapters.js +2 -2
- package/dist/generators/boundary-manifest.d.ts +29 -0
- package/dist/generators/boundary-manifest.d.ts.map +1 -0
- package/dist/generators/boundary-manifest.js +183 -0
- package/dist/generators/boundary-manifest.js.map +1 -0
- package/dist/generators/boundary-manifest.test.d.ts +2 -0
- package/dist/generators/boundary-manifest.test.d.ts.map +1 -0
- package/dist/generators/boundary-manifest.test.js +91 -0
- package/dist/generators/boundary-manifest.test.js.map +1 -0
- package/dist/generators/context-md.js +6 -6
- package/dist/generators/context-md.js.map +1 -1
- package/dist/generators/manifest.d.ts +78 -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 +6 -12
- package/dist/generators/portable-knowledge.d.ts.map +1 -1
- package/dist/generators/portable-knowledge.js +2 -19
- package/dist/generators/portable-knowledge.js.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 +242 -26
- package/dist/index.js.map +1 -1
- package/dist/lib/activation.d.ts.map +1 -1
- package/dist/lib/activation.js +3 -3
- 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 +141 -0
- package/dist/lib/canonicalRefs.d.ts.map +1 -0
- package/dist/lib/canonicalRefs.js +150 -0
- package/dist/lib/canonicalRefs.js.map +1 -0
- package/dist/lib/client.d.ts.map +1 -1
- package/dist/lib/client.js +27 -17
- package/dist/lib/client.js.map +1 -1
- package/dist/lib/config.d.ts +98 -9
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +231 -44
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/connectKeyLabel.d.ts +9 -0
- package/dist/lib/connectKeyLabel.d.ts.map +1 -0
- package/dist/lib/connectKeyLabel.js +12 -0
- package/dist/lib/connectKeyLabel.js.map +1 -0
- 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 +3 -0
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +3 -0
- package/dist/lib/errors.js.map +1 -1
- package/dist/lib/normalizeMaterializedFilename.d.ts +28 -0
- package/dist/lib/normalizeMaterializedFilename.d.ts.map +1 -0
- package/dist/lib/normalizeMaterializedFilename.js +56 -0
- package/dist/lib/normalizeMaterializedFilename.js.map +1 -0
- package/dist/lib/normalizeMaterializedFilename.test.d.ts +16 -0
- package/dist/lib/normalizeMaterializedFilename.test.d.ts.map +1 -0
- package/dist/lib/normalizeMaterializedFilename.test.js +90 -0
- package/dist/lib/normalizeMaterializedFilename.test.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 +14 -0
- package/dist/lib/session.js.map +1 -1
- package/dist/lib/update-check.d.ts +20 -0
- package/dist/lib/update-check.d.ts.map +1 -1
- package/dist/lib/update-check.js +122 -21
- package/dist/lib/update-check.js.map +1 -1
- package/dist/lib/upgrade-runner.d.ts +21 -0
- package/dist/lib/upgrade-runner.d.ts.map +1 -0
- package/dist/lib/upgrade-runner.js +109 -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 +2 -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
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { createHash } from 'crypto';
|
|
2
|
+
import { existsSync, readFileSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
const EXPECTED_SOURCE = '.productbrain/rules/architecture-boundaries.md';
|
|
5
|
+
const VALID_MODES = new Set(['advisory', 'drift-check', 'enforced']);
|
|
6
|
+
const VALID_KINDS = new Set(['policyBoundary', 'localOnlyTechnical', 'outOfScopeExisting']);
|
|
7
|
+
const VALID_STATUS = new Set(['active', 'planned', 'deprecated']);
|
|
8
|
+
const VALID_SCOPE = new Set(['convex', 'frontend', 'repo']);
|
|
9
|
+
const VALID_SEVERITY = new Set(['error', 'warn', 'info']);
|
|
10
|
+
export function getBoundaryEnforcementMode(manifest) {
|
|
11
|
+
const raw = manifest?.boundary_enforcement_mode ?? manifest?.boundaryEnforcementMode ?? 'advisory';
|
|
12
|
+
if (VALID_MODES.has(raw))
|
|
13
|
+
return raw;
|
|
14
|
+
throw new Error(`Unsupported boundary enforcement mode "${raw}". Use advisory, drift-check, or enforced.`);
|
|
15
|
+
}
|
|
16
|
+
export function generateBoundaryManifest(productbrainDir) {
|
|
17
|
+
const sourcePath = join(productbrainDir, 'rules', 'architecture-boundaries.md');
|
|
18
|
+
if (!existsSync(sourcePath))
|
|
19
|
+
return null;
|
|
20
|
+
const raw = readFileSync(sourcePath, 'utf8');
|
|
21
|
+
const rules = parseBoundaryRules(raw);
|
|
22
|
+
if (rules.length === 0)
|
|
23
|
+
return null;
|
|
24
|
+
validateBoundaryRules(rules);
|
|
25
|
+
const chainRefs = [...new Set(rules.flatMap((rule) => rule.chainRefs))].sort();
|
|
26
|
+
const manifest = {
|
|
27
|
+
schemaVersion: 1,
|
|
28
|
+
generator: 'pb-handshake-boundary-manifest',
|
|
29
|
+
sources: [
|
|
30
|
+
{
|
|
31
|
+
path: EXPECTED_SOURCE,
|
|
32
|
+
sha256: createHash('sha256').update(raw).digest('hex'),
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
chainSources: chainRefs.map((entryId) => ({ entryId })),
|
|
36
|
+
rules: [...rules].sort((a, b) => a.id.localeCompare(b.id)),
|
|
37
|
+
};
|
|
38
|
+
return `${JSON.stringify(manifest, null, 2)}\n`;
|
|
39
|
+
}
|
|
40
|
+
export function parseBoundaryRules(markdown) {
|
|
41
|
+
const frontmatter = extractFrontmatter(markdown);
|
|
42
|
+
if (!frontmatter)
|
|
43
|
+
return [];
|
|
44
|
+
const lines = frontmatter.split('\n');
|
|
45
|
+
const rules = [];
|
|
46
|
+
let inEnforcement = false;
|
|
47
|
+
let inBoundaries = false;
|
|
48
|
+
let current = null;
|
|
49
|
+
let nestedKey = null;
|
|
50
|
+
const commit = () => {
|
|
51
|
+
if (current)
|
|
52
|
+
rules.push(current);
|
|
53
|
+
current = null;
|
|
54
|
+
nestedKey = null;
|
|
55
|
+
};
|
|
56
|
+
for (const line of lines) {
|
|
57
|
+
const trimmed = line.trim();
|
|
58
|
+
if (!trimmed || trimmed.startsWith('#'))
|
|
59
|
+
continue;
|
|
60
|
+
if (/^\S/.test(line) && !line.startsWith('enforcement:')) {
|
|
61
|
+
if (inEnforcement) {
|
|
62
|
+
commit();
|
|
63
|
+
inEnforcement = false;
|
|
64
|
+
inBoundaries = false;
|
|
65
|
+
}
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
if (line === 'enforcement:') {
|
|
69
|
+
inEnforcement = true;
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (!inEnforcement)
|
|
73
|
+
continue;
|
|
74
|
+
if (/^ {2}boundaries:\s*$/.test(line)) {
|
|
75
|
+
inBoundaries = true;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (!inBoundaries)
|
|
79
|
+
continue;
|
|
80
|
+
const itemMatch = line.match(/^ {4}-\s+([A-Za-z0-9_.-]+):\s*(.*)$/);
|
|
81
|
+
if (itemMatch) {
|
|
82
|
+
commit();
|
|
83
|
+
current = {};
|
|
84
|
+
nestedKey = null;
|
|
85
|
+
current[itemMatch[1]] = parseScalar(itemMatch[2]);
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
if (!current)
|
|
89
|
+
continue;
|
|
90
|
+
const topMatch = line.match(/^ {6}([A-Za-z0-9_.-]+):\s*(.*)$/);
|
|
91
|
+
if (topMatch) {
|
|
92
|
+
const key = topMatch[1];
|
|
93
|
+
const value = topMatch[2];
|
|
94
|
+
if (value === '') {
|
|
95
|
+
current[key] = {};
|
|
96
|
+
nestedKey = key;
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
current[key] = parseScalar(value);
|
|
100
|
+
nestedKey = null;
|
|
101
|
+
}
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
const nestedMatch = line.match(/^ {8}([A-Za-z0-9_.-]+):\s*(.*)$/);
|
|
105
|
+
if (nestedMatch && nestedKey) {
|
|
106
|
+
const nested = current[nestedKey];
|
|
107
|
+
nested[nestedMatch[1]] = parseScalar(nestedMatch[2]);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
commit();
|
|
111
|
+
return rules;
|
|
112
|
+
}
|
|
113
|
+
function extractFrontmatter(markdown) {
|
|
114
|
+
if (!markdown.startsWith('---\n'))
|
|
115
|
+
return null;
|
|
116
|
+
const end = markdown.indexOf('\n---', 4);
|
|
117
|
+
if (end === -1)
|
|
118
|
+
return null;
|
|
119
|
+
return markdown.slice(4, end);
|
|
120
|
+
}
|
|
121
|
+
function parseScalar(raw) {
|
|
122
|
+
const trimmed = raw.trim();
|
|
123
|
+
if (trimmed.startsWith('[') && trimmed.endsWith(']')) {
|
|
124
|
+
const body = trimmed.slice(1, -1).trim();
|
|
125
|
+
if (!body)
|
|
126
|
+
return [];
|
|
127
|
+
return body.split(',').map((part) => stripQuotes(part.trim()));
|
|
128
|
+
}
|
|
129
|
+
return stripQuotes(trimmed);
|
|
130
|
+
}
|
|
131
|
+
function stripQuotes(value) {
|
|
132
|
+
return value.replace(/^['"]|['"]$/g, '');
|
|
133
|
+
}
|
|
134
|
+
function validateBoundaryRules(rules) {
|
|
135
|
+
const ids = new Set();
|
|
136
|
+
const depcruiseNames = new Set();
|
|
137
|
+
const chainSources = new Set(rules.flatMap((rule) => rule.chainRefs ?? []));
|
|
138
|
+
for (const rule of rules) {
|
|
139
|
+
if (!rule.id)
|
|
140
|
+
throw new Error('Boundary rule is missing id.');
|
|
141
|
+
if (ids.has(rule.id))
|
|
142
|
+
throw new Error(`Duplicate boundary id "${rule.id}".`);
|
|
143
|
+
ids.add(rule.id);
|
|
144
|
+
if (!VALID_KINDS.has(rule.kind))
|
|
145
|
+
throw new Error(`Boundary ${rule.id} has unsupported kind.`);
|
|
146
|
+
if (!VALID_STATUS.has(rule.status))
|
|
147
|
+
throw new Error(`Boundary ${rule.id} has unsupported status.`);
|
|
148
|
+
if (!VALID_SCOPE.has(rule.scope))
|
|
149
|
+
throw new Error(`Boundary ${rule.id} has unsupported scope.`);
|
|
150
|
+
if (!Array.isArray(rule.chainRefs))
|
|
151
|
+
throw new Error(`Boundary ${rule.id} has invalid chainRefs.`);
|
|
152
|
+
const depcruiseRuleName = rule.enforcement?.depcruiseRuleName;
|
|
153
|
+
if (!depcruiseRuleName)
|
|
154
|
+
throw new Error(`Boundary ${rule.id} is missing depcruiseRuleName.`);
|
|
155
|
+
if (depcruiseNames.has(depcruiseRuleName)) {
|
|
156
|
+
throw new Error(`Duplicate dependency-cruiser rule name "${depcruiseRuleName}".`);
|
|
157
|
+
}
|
|
158
|
+
depcruiseNames.add(depcruiseRuleName);
|
|
159
|
+
if (rule.kind === 'policyBoundary' && rule.status === 'active') {
|
|
160
|
+
const required = [
|
|
161
|
+
rule.description,
|
|
162
|
+
rule.from?.path,
|
|
163
|
+
rule.to?.path,
|
|
164
|
+
rule.severity,
|
|
165
|
+
depcruiseRuleName,
|
|
166
|
+
];
|
|
167
|
+
if (required.some((value) => typeof value !== 'string' || value.length === 0)) {
|
|
168
|
+
throw new Error(`This active Product Brain boundary has no dependency-cruiser rule. Add enforcement or change the boundary status. Boundary: ${rule.id}`);
|
|
169
|
+
}
|
|
170
|
+
if (!rule.chainRefs.length) {
|
|
171
|
+
throw new Error(`Boundary ${rule.id} is active Product Brain policy but has no chainRefs.`);
|
|
172
|
+
}
|
|
173
|
+
if (!VALID_SEVERITY.has(rule.severity)) {
|
|
174
|
+
throw new Error(`Boundary ${rule.id} has unsupported severity.`);
|
|
175
|
+
}
|
|
176
|
+
for (const ref of rule.chainRefs) {
|
|
177
|
+
if (!chainSources.has(ref))
|
|
178
|
+
throw new Error(`Boundary ${rule.id} references ${ref} without chainSources metadata.`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=boundary-manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"boundary-manifest.js","sourceRoot":"","sources":["../../src/generators/boundary-manifest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"boundary-manifest.test.d.ts","sourceRoot":"","sources":["../../src/generators/boundary-manifest.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
const { vfs, PB_DIR } = vi.hoisted(() => ({
|
|
4
|
+
vfs: {},
|
|
5
|
+
PB_DIR: '/tmp/pb-test/.productbrain',
|
|
6
|
+
}));
|
|
7
|
+
vi.mock('fs', () => ({
|
|
8
|
+
existsSync: vi.fn((path) => path in vfs),
|
|
9
|
+
readFileSync: vi.fn((path, _enc) => {
|
|
10
|
+
if (path in vfs)
|
|
11
|
+
return vfs[path];
|
|
12
|
+
throw Object.assign(new Error(`ENOENT: no such file '${path}'`), { code: 'ENOENT' });
|
|
13
|
+
}),
|
|
14
|
+
}));
|
|
15
|
+
import { generateBoundaryManifest, getBoundaryEnforcementMode, parseBoundaryRules, } from './boundary-manifest.js';
|
|
16
|
+
const SOURCE_PATH = join(PB_DIR, 'rules', 'architecture-boundaries.md');
|
|
17
|
+
function boundaryMarkdown(depcruiseRuleName = 'core-no-feature') {
|
|
18
|
+
return `---
|
|
19
|
+
name: architecture-boundaries
|
|
20
|
+
enforcement:
|
|
21
|
+
boundaries:
|
|
22
|
+
- id: core-no-feature
|
|
23
|
+
kind: policyBoundary
|
|
24
|
+
status: active
|
|
25
|
+
scope: convex
|
|
26
|
+
chainRefs: [BR-19, ARCH-29]
|
|
27
|
+
description: "Core must not import Feature."
|
|
28
|
+
from:
|
|
29
|
+
path: "^convex/gitchain/"
|
|
30
|
+
to:
|
|
31
|
+
path: "^convex/chainwork/"
|
|
32
|
+
severity: error
|
|
33
|
+
enforcement:
|
|
34
|
+
depcruiseRuleName: ${depcruiseRuleName}
|
|
35
|
+
- id: no-circular
|
|
36
|
+
kind: localOnlyTechnical
|
|
37
|
+
status: active
|
|
38
|
+
scope: repo
|
|
39
|
+
chainRefs: []
|
|
40
|
+
description: "Technical graph integrity check."
|
|
41
|
+
enforcement:
|
|
42
|
+
depcruiseRuleName: no-circular
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
# Architecture Boundaries
|
|
46
|
+
`;
|
|
47
|
+
}
|
|
48
|
+
describe('boundary manifest generator', () => {
|
|
49
|
+
beforeEach(() => {
|
|
50
|
+
Object.keys(vfs).forEach((key) => delete vfs[key]);
|
|
51
|
+
vi.clearAllMocks();
|
|
52
|
+
});
|
|
53
|
+
it('defaults new workspaces to advisory mode', () => {
|
|
54
|
+
expect(getBoundaryEnforcementMode(null)).toBe('advisory');
|
|
55
|
+
});
|
|
56
|
+
it('parses structured Product Brain boundary frontmatter', () => {
|
|
57
|
+
const rules = parseBoundaryRules(boundaryMarkdown());
|
|
58
|
+
expect(rules).toHaveLength(2);
|
|
59
|
+
expect(rules[0]).toMatchObject({
|
|
60
|
+
id: 'core-no-feature',
|
|
61
|
+
kind: 'policyBoundary',
|
|
62
|
+
status: 'active',
|
|
63
|
+
scope: 'convex',
|
|
64
|
+
chainRefs: ['BR-19', 'ARCH-29'],
|
|
65
|
+
from: { path: '^convex/gitchain/' },
|
|
66
|
+
to: { path: '^convex/chainwork/' },
|
|
67
|
+
severity: 'error',
|
|
68
|
+
enforcement: { depcruiseRuleName: 'core-no-feature' },
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
it('generates a stable manifest with source and chain metadata', () => {
|
|
72
|
+
vfs[SOURCE_PATH] = boundaryMarkdown();
|
|
73
|
+
const content = generateBoundaryManifest(PB_DIR);
|
|
74
|
+
expect(content).not.toBeNull();
|
|
75
|
+
const manifest = JSON.parse(content);
|
|
76
|
+
expect(manifest.sources[0].path).toBe('.productbrain/rules/architecture-boundaries.md');
|
|
77
|
+
expect(manifest.chainSources.map((source) => source.entryId)).toEqual([
|
|
78
|
+
'ARCH-29',
|
|
79
|
+
'BR-19',
|
|
80
|
+
]);
|
|
81
|
+
expect(manifest.rules.map((rule) => rule.id)).toEqual([
|
|
82
|
+
'core-no-feature',
|
|
83
|
+
'no-circular',
|
|
84
|
+
]);
|
|
85
|
+
});
|
|
86
|
+
it('rejects duplicate dependency-cruiser rule names', () => {
|
|
87
|
+
vfs[SOURCE_PATH] = boundaryMarkdown('no-circular');
|
|
88
|
+
expect(() => generateBoundaryManifest(PB_DIR)).toThrow('Duplicate dependency-cruiser rule name "no-circular".');
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
//# sourceMappingURL=boundary-manifest.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"boundary-manifest.test.js","sourceRoot":"","sources":["../../src/generators/boundary-manifest.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -43,17 +43,17 @@ export function generateContextMd(view, repo, timestamp, stage) {
|
|
|
43
43
|
lines.push(`- **Vision**: ${sc.vision}`);
|
|
44
44
|
if (sc.purpose)
|
|
45
45
|
lines.push(`- **Purpose**: ${sc.purpose}`);
|
|
46
|
-
if (sc.
|
|
47
|
-
lines.push(`- **Current
|
|
46
|
+
if (sc.currentWorkPackage)
|
|
47
|
+
lines.push(`- **Current work package**: ${sc.currentWorkPackage}`);
|
|
48
48
|
lines.push(`- **Active bets**: ${sc.activeBetCount}`);
|
|
49
49
|
lines.push(`- **Active tensions**: ${sc.activeTensionCount}`);
|
|
50
50
|
if (sc.productAreas.length > 0)
|
|
51
51
|
lines.push(`- **Product areas**: ${sc.productAreas.join(', ')}`);
|
|
52
52
|
lines.push('');
|
|
53
|
-
// Active
|
|
54
|
-
if (view.
|
|
55
|
-
lines.push('## Active
|
|
56
|
-
for (const bet of view.
|
|
53
|
+
// Active work packages
|
|
54
|
+
if (view.activeWorkPackages.length > 0) {
|
|
55
|
+
lines.push('## Active Work Packages');
|
|
56
|
+
for (const bet of view.activeWorkPackages.slice(0, 10)) {
|
|
57
57
|
lines.push(`- **${bet.entryId ?? bet.name}** — ${bet.name}`);
|
|
58
58
|
if (bet.linkedTensions && bet.linkedTensions.length > 0) {
|
|
59
59
|
for (const t of bet.linkedTensions.slice(0, 3)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context-md.js","sourceRoot":"","sources":["../../src/generators/context-md.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,SAAS,SAAS,CAAC,CAA6D,EAAE,UAAU,GAAG,GAAG;IAChG,MAAM,EAAE,GAAG,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,IAAI,CAAC;IAC/B,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;QACd,MAAM,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;QAC7F,OAAO,OAAO,EAAE,QAAQ,CAAC,EAAE,CAAC;IAC9B,CAAC;IACD,OAAO,OAAO,EAAE,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAuB,EAAE,IAAiB,EAAE,SAAiB,EAAE,KAAc;IAC7G,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,CAAC,IAAI,CAAC,wCAAwC,GAAG,SAAS,GAAG,MAAM,CAAC,CAAC;IAC1E,KAAK,CAAC,IAAI,CAAC,kEAAkE,CAAC,CAAC;IAC/E,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;IAClD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,eAAe,SAAS,GAAG,CAAC,CAAC;IACxC,IAAI,IAAI,CAAC,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC/F,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,QAAQ;IACR,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACvB,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;IAChC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,+CAA+C;IAC/C,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QAC/B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,oEAAoE,CAAC,CAAC;QACjF,KAAK,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC;QACxD,KAAK,CAAC,IAAI,CAAC,4FAA4F,CAAC,CAAC;QACzG,KAAK,CAAC,IAAI,CAAC,qDAAqD,CAAC,CAAC;QAClE,KAAK,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC;QAC5D,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,oBAAoB;IACpB,MAAM,EAAE,GAAG,IAAI,CAAC,gBAAgB,CAAC;IACjC,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IACnC,IAAI,EAAE,CAAC,MAAM;QAAE,KAAK,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;IACxD,IAAI,EAAE,CAAC,OAAO;QAAE,KAAK,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;IAC3D,IAAI,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"context-md.js","sourceRoot":"","sources":["../../src/generators/context-md.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,13 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Manifest reader — reads .productbrain/manifest.yaml for adoption state.
|
|
3
3
|
* WP-310 E1: personal workspace layer — manifest-based filtering.
|
|
4
|
+
* WP-421 S1 (#35): extends Manifest with DEC-951 authority keys (`materialize`,
|
|
5
|
+
* `surfaces`, `lock`) and adds `readManifestStatus()` — a typed reader that
|
|
6
|
+
* returns the FULL UNION of legacy + new fields plus a `parseStatus`
|
|
7
|
+
* discriminator (DEC-955, DEC-963 "Authority mode parse semantics").
|
|
4
8
|
*
|
|
5
9
|
* No external YAML dependency is required; the manifest schema is
|
|
6
10
|
* simple enough to parse with a minimal line-by-line parser.
|
|
7
11
|
*/
|
|
12
|
+
/** Authority materialize modes per DEC-951. */
|
|
13
|
+
export type AuthorityMode = 'off' | 'observe' | 'project' | 'govern';
|
|
14
|
+
/** Lock levels per DEC-951 — controls who can author a setup asset. */
|
|
15
|
+
export type LockLevel = 'platform' | 'workspace' | 'personal';
|
|
16
|
+
/** Parse status discriminator per DEC-963 (Authority mode parse semantics). */
|
|
17
|
+
export type ManifestParseStatus = 'absent' | 'unparseable' | 'ok';
|
|
8
18
|
export interface Manifest {
|
|
9
19
|
version: string;
|
|
10
20
|
method_source?: 'chain' | 'bundled';
|
|
21
|
+
boundary_enforcement_mode?: string;
|
|
22
|
+
boundaryEnforcementMode?: string;
|
|
11
23
|
/** Allowlist — if present and non-empty, ONLY these rule/skill names pass. */
|
|
12
24
|
adopted?: string[];
|
|
13
25
|
/** Denylist — always excluded regardless of adopted list. */
|
|
@@ -16,12 +28,78 @@ export interface Manifest {
|
|
|
16
28
|
cursor?: boolean;
|
|
17
29
|
copilot?: boolean;
|
|
18
30
|
};
|
|
31
|
+
/**
|
|
32
|
+
* Authority materialize mode (DEC-951). Optional in the manifest file.
|
|
33
|
+
* When absent, `readManifestStatus()` defaults to 'observe' per DEC-955.
|
|
34
|
+
*/
|
|
35
|
+
materialize?: AuthorityMode;
|
|
36
|
+
/**
|
|
37
|
+
* Surfaces this workspace allows PB to project to (e.g. `.claude`, `.cursor`).
|
|
38
|
+
* Per STD-236, disk writes are permitted ONLY within these surfaces (plus
|
|
39
|
+
* the hard-coded `.productbrain/` root).
|
|
40
|
+
*/
|
|
41
|
+
surfaces?: string[];
|
|
42
|
+
/**
|
|
43
|
+
* Per-asset lock overrides — maps asset id → lock level (DEC-951).
|
|
44
|
+
* Example: { "RULE-foo": "platform", "SKILL-bar": "workspace" }.
|
|
45
|
+
*/
|
|
46
|
+
lock?: Record<string, LockLevel>;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Typed result returned by `readManifestStatus()` (WP-421 S1, #35).
|
|
50
|
+
*
|
|
51
|
+
* Shape: full union of legacy + WP-421 keys + parse-status discriminator.
|
|
52
|
+
* Defaults (DEC-955, DEC-963):
|
|
53
|
+
* - No `.productbrain/` directory: mode='off', parseStatus='absent'
|
|
54
|
+
* - Folder + no manifest: mode='observe', parseStatus='absent'
|
|
55
|
+
* - Manifest present + no `materialize`: mode='observe', parseStatus='ok'
|
|
56
|
+
* - Malformed YAML: mode='observe', parseStatus='unparseable'
|
|
57
|
+
*
|
|
58
|
+
* Critical invariant (DEC-963): when `parseStatus !== 'ok'`, mode is NEVER
|
|
59
|
+
* 'project' or 'govern'. The reader fails closed to 'observe'.
|
|
60
|
+
*/
|
|
61
|
+
export interface ManifestStatus {
|
|
62
|
+
/** Effective authority mode after defaults applied. */
|
|
63
|
+
mode: AuthorityMode;
|
|
64
|
+
/** Surfaces list; empty array when manifest is absent or `surfaces` key missing. */
|
|
65
|
+
surfaces: string[];
|
|
66
|
+
/** Per-asset lock overrides; empty object when absent. */
|
|
67
|
+
lock: Record<string, LockLevel>;
|
|
68
|
+
/** Parse-status discriminator. */
|
|
69
|
+
parseStatus: ManifestParseStatus;
|
|
70
|
+
/**
|
|
71
|
+
* The underlying parsed `Manifest` when `parseStatus === 'ok'`, else null.
|
|
72
|
+
* Callers needing legacy fields (adopted/rejected/hooks/method_source) read
|
|
73
|
+
* them from this object — keeps the legacy `readManifest()` shape intact
|
|
74
|
+
* while exposing the WP-421 typed contract through `mode`/`surfaces`/`lock`.
|
|
75
|
+
*/
|
|
76
|
+
manifest: Manifest | null;
|
|
19
77
|
}
|
|
20
78
|
/**
|
|
21
79
|
* Read .productbrain/manifest.yaml.
|
|
22
80
|
* Returns null if the file is absent or unparseable (treat as no-op).
|
|
81
|
+
*
|
|
82
|
+
* Legacy reader — kept for callers that only need adoption-state filtering.
|
|
83
|
+
* WP-421 callers should prefer `readManifestStatus()` for typed authority
|
|
84
|
+
* mode + parse-status discriminator.
|
|
23
85
|
*/
|
|
24
86
|
export declare function readManifest(productbrainDir: string): Manifest | null;
|
|
87
|
+
/**
|
|
88
|
+
* Read manifest with full WP-421 authority typing (#35).
|
|
89
|
+
*
|
|
90
|
+
* Returns the FULL UNION of legacy + DEC-951 keys plus a `parseStatus`
|
|
91
|
+
* discriminator. Defaults per DEC-955 / DEC-963:
|
|
92
|
+
* - `.productbrain/` directory absent → mode='off', parseStatus='absent'
|
|
93
|
+
* - Directory present, manifest absent → mode='observe', parseStatus='absent'
|
|
94
|
+
* - Manifest present, no `materialize:` → mode='observe', parseStatus='ok'
|
|
95
|
+
* - Manifest unparseable / fails shape validation → mode='observe',
|
|
96
|
+
* parseStatus='unparseable' (NEVER 'project'/'govern' — fail closed).
|
|
97
|
+
*
|
|
98
|
+
* @param productbrainDir Absolute path to the `.productbrain/` directory.
|
|
99
|
+
* The directory itself MAY be absent — caller passes the candidate path
|
|
100
|
+
* regardless and this reader infers the mode from filesystem state.
|
|
101
|
+
*/
|
|
102
|
+
export declare function readManifestStatus(productbrainDir: string): ManifestStatus;
|
|
25
103
|
/**
|
|
26
104
|
* Filter a list of items by the manifest's adopted/rejected lists.
|
|
27
105
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/generators/manifest.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/generators/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,+CAA+C;AAC/C,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;AAErE,uEAAuE;AACvE,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,WAAW,GAAG,UAAU,CAAC;AAE9D,+EAA+E;AAC/E,MAAM,MAAM,mBAAmB,GAAG,QAAQ,GAAG,aAAa,GAAG,IAAI,CAAC;AAElE,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACpC,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,8EAA8E;IAC9E,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,KAAK,CAAC,EAAE;QACN,MAAM,CAAC,EAAE,OAAO,CAAC;QACjB,OAAO,CAAC,EAAE,OAAO,CAAC;KACnB,CAAC;IAEF;;;OAGG;IACH,WAAW,CAAC,EAAE,aAAa,CAAC;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;CAClC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,cAAc;IAC7B,uDAAuD;IACvD,IAAI,EAAE,aAAa,CAAC;IACpB,oFAAoF;IACpF,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,0DAA0D;IAC1D,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAChC,kCAAkC;IAClC,WAAW,EAAE,mBAAmB,CAAC;IACjC;;;;;OAKG;IACH,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;CAC3B;AA8KD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,eAAe,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAUrE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAAC,eAAe,EAAE,MAAM,GAAG,cAAc,CAyC1E;AAED;;;;;;;;GAQG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,SAAS;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,EAC9D,KAAK,EAAE,CAAC,EAAE,EACV,QAAQ,EAAE,QAAQ,GAAG,IAAI,GACxB,CAAC,EAAE,CAgBL"}
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Manifest reader — reads .productbrain/manifest.yaml for adoption state.
|
|
3
3
|
* WP-310 E1: personal workspace layer — manifest-based filtering.
|
|
4
|
+
* WP-421 S1 (#35): extends Manifest with DEC-951 authority keys (`materialize`,
|
|
5
|
+
* `surfaces`, `lock`) and adds `readManifestStatus()` — a typed reader that
|
|
6
|
+
* returns the FULL UNION of legacy + new fields plus a `parseStatus`
|
|
7
|
+
* discriminator (DEC-955, DEC-963 "Authority mode parse semantics").
|
|
4
8
|
*
|
|
5
9
|
* No external YAML dependency is required; the manifest schema is
|
|
6
10
|
* simple enough to parse with a minimal line-by-line parser.
|
|
@@ -110,9 +114,75 @@ function parseScalar(val) {
|
|
|
110
114
|
return stripped;
|
|
111
115
|
}
|
|
112
116
|
// ── Public API ─────────────────────────────────────────────────────────
|
|
117
|
+
/** Valid AuthorityMode values, derived once for runtime guards. */
|
|
118
|
+
const VALID_AUTHORITY_MODES = new Set([
|
|
119
|
+
'off',
|
|
120
|
+
'observe',
|
|
121
|
+
'project',
|
|
122
|
+
'govern',
|
|
123
|
+
]);
|
|
124
|
+
/** Valid LockLevel values. */
|
|
125
|
+
const VALID_LOCK_LEVELS = new Set([
|
|
126
|
+
'platform',
|
|
127
|
+
'workspace',
|
|
128
|
+
'personal',
|
|
129
|
+
]);
|
|
130
|
+
/**
|
|
131
|
+
* Validate a parsed manifest object against the union schema.
|
|
132
|
+
* Returns the typed Manifest on success, null on any shape violation.
|
|
133
|
+
*
|
|
134
|
+
* Shared between `readManifest()` and `readManifestStatus()` so legacy
|
|
135
|
+
* callers and the WP-421 typed reader agree on what counts as parseable.
|
|
136
|
+
*/
|
|
137
|
+
function validateManifestShape(parsed) {
|
|
138
|
+
// Require version to be a string; reject missing or non-string values
|
|
139
|
+
if (typeof parsed.version !== 'string')
|
|
140
|
+
return null;
|
|
141
|
+
// Validate array fields — scalar values (e.g. adopted: "rule-a") must be rejected
|
|
142
|
+
if (parsed.adopted !== undefined && !Array.isArray(parsed.adopted))
|
|
143
|
+
return null;
|
|
144
|
+
if (parsed.rejected !== undefined && !Array.isArray(parsed.rejected))
|
|
145
|
+
return null;
|
|
146
|
+
// Validate method_source if present — only 'chain' | 'bundled' are valid
|
|
147
|
+
if (parsed.method_source !== undefined &&
|
|
148
|
+
parsed.method_source !== 'chain' &&
|
|
149
|
+
parsed.method_source !== 'bundled')
|
|
150
|
+
return null;
|
|
151
|
+
// ── WP-421 S1 — DEC-951 keys ─────────────────────────────────────────
|
|
152
|
+
// materialize: optional; if present, must be a known AuthorityMode.
|
|
153
|
+
if (parsed.materialize !== undefined &&
|
|
154
|
+
!(typeof parsed.materialize === 'string' && VALID_AUTHORITY_MODES.has(parsed.materialize))) {
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
// surfaces: optional; if present, must be an array of strings.
|
|
158
|
+
if (parsed.surfaces !== undefined) {
|
|
159
|
+
if (!Array.isArray(parsed.surfaces))
|
|
160
|
+
return null;
|
|
161
|
+
if (!parsed.surfaces.every((s) => typeof s === 'string'))
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
// lock: optional; if present, must be a plain object whose values are valid LockLevels.
|
|
165
|
+
if (parsed.lock !== undefined) {
|
|
166
|
+
if (parsed.lock === null ||
|
|
167
|
+
typeof parsed.lock !== 'object' ||
|
|
168
|
+
Array.isArray(parsed.lock)) {
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
for (const value of Object.values(parsed.lock)) {
|
|
172
|
+
if (typeof value !== 'string' || !VALID_LOCK_LEVELS.has(value)) {
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return parsed;
|
|
178
|
+
}
|
|
113
179
|
/**
|
|
114
180
|
* Read .productbrain/manifest.yaml.
|
|
115
181
|
* Returns null if the file is absent or unparseable (treat as no-op).
|
|
182
|
+
*
|
|
183
|
+
* Legacy reader — kept for callers that only need adoption-state filtering.
|
|
184
|
+
* WP-421 callers should prefer `readManifestStatus()` for typed authority
|
|
185
|
+
* mode + parse-status discriminator.
|
|
116
186
|
*/
|
|
117
187
|
export function readManifest(productbrainDir) {
|
|
118
188
|
const manifestPath = join(productbrainDir, 'manifest.yaml');
|
|
@@ -121,25 +191,66 @@ export function readManifest(productbrainDir) {
|
|
|
121
191
|
try {
|
|
122
192
|
const raw = readFileSync(manifestPath, 'utf8');
|
|
123
193
|
const parsed = parseManifestYaml(raw);
|
|
124
|
-
|
|
125
|
-
if (typeof parsed.version !== 'string')
|
|
126
|
-
return null;
|
|
127
|
-
// Validate array fields — scalar values (e.g. adopted: "rule-a") must be rejected
|
|
128
|
-
if (parsed.adopted !== undefined && !Array.isArray(parsed.adopted))
|
|
129
|
-
return null;
|
|
130
|
-
if (parsed.rejected !== undefined && !Array.isArray(parsed.rejected))
|
|
131
|
-
return null;
|
|
132
|
-
// Validate method_source if present — only 'chain' | 'bundled' are valid
|
|
133
|
-
if (parsed.method_source !== undefined &&
|
|
134
|
-
parsed.method_source !== 'chain' &&
|
|
135
|
-
parsed.method_source !== 'bundled')
|
|
136
|
-
return null;
|
|
137
|
-
return parsed;
|
|
194
|
+
return validateManifestShape(parsed);
|
|
138
195
|
}
|
|
139
196
|
catch {
|
|
140
197
|
return null; // malformed manifest = treat as absent
|
|
141
198
|
}
|
|
142
199
|
}
|
|
200
|
+
/**
|
|
201
|
+
* Read manifest with full WP-421 authority typing (#35).
|
|
202
|
+
*
|
|
203
|
+
* Returns the FULL UNION of legacy + DEC-951 keys plus a `parseStatus`
|
|
204
|
+
* discriminator. Defaults per DEC-955 / DEC-963:
|
|
205
|
+
* - `.productbrain/` directory absent → mode='off', parseStatus='absent'
|
|
206
|
+
* - Directory present, manifest absent → mode='observe', parseStatus='absent'
|
|
207
|
+
* - Manifest present, no `materialize:` → mode='observe', parseStatus='ok'
|
|
208
|
+
* - Manifest unparseable / fails shape validation → mode='observe',
|
|
209
|
+
* parseStatus='unparseable' (NEVER 'project'/'govern' — fail closed).
|
|
210
|
+
*
|
|
211
|
+
* @param productbrainDir Absolute path to the `.productbrain/` directory.
|
|
212
|
+
* The directory itself MAY be absent — caller passes the candidate path
|
|
213
|
+
* regardless and this reader infers the mode from filesystem state.
|
|
214
|
+
*/
|
|
215
|
+
export function readManifestStatus(productbrainDir) {
|
|
216
|
+
// No `.productbrain/` directory at all → mode 'off' (DEC-955).
|
|
217
|
+
if (!existsSync(productbrainDir)) {
|
|
218
|
+
return { mode: 'off', surfaces: [], lock: {}, parseStatus: 'absent', manifest: null };
|
|
219
|
+
}
|
|
220
|
+
const manifestPath = join(productbrainDir, 'manifest.yaml');
|
|
221
|
+
// Directory present but no manifest file → mode 'observe', absent.
|
|
222
|
+
if (!existsSync(manifestPath)) {
|
|
223
|
+
return { mode: 'observe', surfaces: [], lock: {}, parseStatus: 'absent', manifest: null };
|
|
224
|
+
}
|
|
225
|
+
let raw;
|
|
226
|
+
try {
|
|
227
|
+
raw = readFileSync(manifestPath, 'utf8');
|
|
228
|
+
}
|
|
229
|
+
catch {
|
|
230
|
+
// I/O failure — treat as unparseable, fail closed to observe (DEC-963).
|
|
231
|
+
return { mode: 'observe', surfaces: [], lock: {}, parseStatus: 'unparseable', manifest: null };
|
|
232
|
+
}
|
|
233
|
+
let parsed;
|
|
234
|
+
try {
|
|
235
|
+
parsed = parseManifestYaml(raw);
|
|
236
|
+
}
|
|
237
|
+
catch {
|
|
238
|
+
return { mode: 'observe', surfaces: [], lock: {}, parseStatus: 'unparseable', manifest: null };
|
|
239
|
+
}
|
|
240
|
+
const validated = validateManifestShape(parsed);
|
|
241
|
+
if (validated === null) {
|
|
242
|
+
// Shape violation (e.g. invalid materialize value, malformed lock map).
|
|
243
|
+
// Fail closed to observe per DEC-963 — NEVER project/govern.
|
|
244
|
+
return { mode: 'observe', surfaces: [], lock: {}, parseStatus: 'unparseable', manifest: null };
|
|
245
|
+
}
|
|
246
|
+
return {
|
|
247
|
+
mode: validated.materialize ?? 'observe',
|
|
248
|
+
surfaces: validated.surfaces ?? [],
|
|
249
|
+
lock: validated.lock ?? {},
|
|
250
|
+
parseStatus: 'ok',
|
|
251
|
+
manifest: validated,
|
|
252
|
+
};
|
|
253
|
+
}
|
|
143
254
|
/**
|
|
144
255
|
* Filter a list of items by the manifest's adopted/rejected lists.
|
|
145
256
|
*
|