@geraldmaron/construct 1.2.2 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -10
- package/bin/construct +286 -220
- package/bin/construct-postinstall.mjs +0 -21
- package/commands/work/optimize-prompts.md +1 -1
- package/examples/distribution/sources/adr.md +2 -2
- package/examples/seed-observations/decisions.md +1 -1
- package/lib/artifact-loop-core.mjs +412 -0
- package/lib/artifact-manifest.mjs +6 -0
- package/lib/artifact-release-gate.mjs +115 -49
- package/lib/audit-rules.mjs +2 -4
- package/lib/audit-skills.mjs +32 -20
- package/lib/audit-specialists.mjs +44 -26
- package/lib/auto-docs.mjs +6 -5
- package/lib/brand-prose.mjs +3 -3
- package/lib/brand-tokens.mjs +2 -2
- package/lib/certification/artifact-fixtures.mjs +4 -1
- package/lib/certification/demo-parity.mjs +6 -32
- package/lib/certification/real-llm-scenarios.mjs +58 -13
- package/lib/certification/role-cards.mjs +7 -6
- package/lib/certification/role-overlays.mjs +4 -4
- package/lib/certification/runner.mjs +9 -2
- package/lib/certification/skill-inventory.mjs +34 -22
- package/lib/certification/skill-scenarios.mjs +21 -8
- package/lib/certification/specialist-contracts.mjs +4 -3
- package/lib/certification/specialist-scenarios.mjs +7 -6
- package/lib/certification/status.mjs +5 -4
- package/lib/cli-commands.mjs +56 -57
- package/lib/comment-lint.mjs +1 -5
- package/lib/completions.mjs +20 -2
- package/lib/config/legacy-config-migration.mjs +125 -0
- package/lib/config/schema.mjs +5 -5
- package/lib/config/source-targets.mjs +80 -0
- package/lib/contracts/validate.mjs +119 -51
- package/lib/decisions/golden.mjs +3 -2
- package/lib/decisions/registry.mjs +11 -6
- package/lib/demo-project.mjs +188 -0
- package/lib/demo-recording.mjs +9 -34
- package/lib/demo-script.mjs +2 -2
- package/lib/demo-surface.mjs +13 -131
- package/lib/demo-tour-renderer.mjs +92 -0
- package/lib/demo.mjs +69 -54
- package/lib/diagram-export.mjs +63 -14
- package/lib/doctor/source-checkout.mjs +3 -4
- package/lib/doctor/watchers/consistency.mjs +90 -22
- package/lib/doctor/watchers/credential-parity.mjs +97 -0
- package/lib/doctor/watchers/mcp-protocol.mjs +1 -1
- package/lib/doctor/watchers/service-health.mjs +4 -32
- package/lib/document-export.mjs +73 -9
- package/lib/document-extract.mjs +10 -198
- package/lib/embed/artifact.mjs +2 -3
- package/lib/embed/cli.mjs +1 -1
- package/lib/embed/config.mjs +1 -2
- package/lib/embed/customer-profiles.mjs +1 -1
- package/lib/embed/daemon.mjs +5 -6
- package/lib/embed/demand-fetch.mjs +114 -2
- package/lib/embed/docs-lifecycle.mjs +9 -5
- package/lib/embed/intake-metrics.mjs +2 -2
- package/lib/embed/notifications.mjs +2 -3
- package/lib/embed/recommendation-store.mjs +25 -22
- package/lib/embed/role-framing.mjs +4 -9
- package/lib/embedded-contract/capability.mjs +4 -2
- package/lib/embedded-contract/contract-version.mjs +1 -1
- package/lib/env-config.mjs +2 -2
- package/lib/flavors/loader.mjs +21 -19
- package/lib/graph/build-from-registry.mjs +31 -7
- package/lib/graph/staleness.mjs +1 -1
- package/lib/headhunt.mjs +82 -35
- package/lib/hooks/agent-tracker.mjs +2 -2
- package/lib/hooks/config-protection.mjs +1 -1
- package/lib/hooks/registry-sync.mjs +3 -3
- package/lib/host-capabilities.mjs +5 -5
- package/lib/improvement/controller.mjs +2 -2
- package/lib/init-unified.mjs +19 -21
- package/lib/intake/classify.mjs +26 -0
- package/lib/intake/daemon.mjs +2 -3
- package/lib/intake/prepare.mjs +10 -3
- package/lib/intake/session-prelude.mjs +1 -1
- package/lib/intake/tables/creative.mjs +9 -9
- package/lib/intake/tables/operations.mjs +4 -4
- package/lib/intake/tables/research.mjs +2 -2
- package/lib/integrations/intake-integrations.mjs +9 -10
- package/lib/knowledge/research-store.mjs +2 -2
- package/lib/mcp/server.mjs +104 -61
- package/lib/mcp/tool-budget.mjs +1 -46
- package/lib/mcp/tool-recovery.mjs +44 -0
- package/lib/mcp/tools/artifact-author.mjs +36 -0
- package/lib/mcp/tools/find-tool.mjs +86 -0
- package/lib/mcp/tools/orchestration-run.mjs +107 -69
- package/lib/mcp/tools/project.mjs +4 -3
- package/lib/mcp/tools/{profile.mjs → scope.mjs} +54 -52
- package/lib/mcp/tools/skills.mjs +39 -22
- package/lib/mcp/tools/telemetry.mjs +2 -1
- package/lib/mcp/tools/workflow.mjs +1 -1
- package/lib/mcp-platform-config.mjs +7 -5
- package/lib/migrations/index.mjs +4 -2
- package/lib/migrations/v2-unified-registry.mjs +35 -0
- package/lib/model-router.mjs +203 -36
- package/lib/models/catalog.mjs +25 -9
- package/lib/models/execution-capability-profile.mjs +3 -3
- package/lib/models/execution-policy.mjs +7 -6
- package/lib/models/provider-poll.mjs +18 -4
- package/lib/opencode-config.mjs +56 -1
- package/lib/opencode-runtime-plugin.mjs +13 -10
- package/lib/oracle/artifact-gate.mjs +14 -4
- package/lib/oracle/cli.mjs +2 -0
- package/lib/oracle/dispatch.mjs +18 -1
- package/lib/oracle/execute.mjs +39 -7
- package/lib/oracle/index.mjs +1 -1
- package/lib/oracle/org-graph.mjs +10 -5
- package/lib/oracle/policy.mjs +6 -0
- package/lib/oracle/read-model.mjs +103 -6
- package/lib/oracle/reconcile.mjs +31 -4
- package/lib/oracle/remediation-dispatch.mjs +53 -0
- package/lib/oracle/routing.mjs +5 -0
- package/lib/oracle/synthesize.mjs +80 -3
- package/lib/orchestration/routing-tables.mjs +44 -10
- package/lib/orchestration/runtime.mjs +2 -0
- package/lib/orchestration/worker.mjs +1 -1
- package/lib/orchestration-policy.mjs +351 -62
- package/lib/overrides/resolver.mjs +1 -12
- package/lib/parity.mjs +37 -11
- package/lib/policy/engine.mjs +80 -15
- package/lib/prompt-composer.js +51 -15
- package/lib/prompt-metadata.mjs +3 -2
- package/lib/providers/connection-probe.mjs +58 -0
- package/lib/providers/copilot-auth.mjs +1 -1
- package/lib/providers/credential-bootstrap.mjs +1 -1
- package/lib/providers/op-run.mjs +3 -4
- package/lib/providers/secret-resolver.mjs +31 -0
- package/lib/publish-tooling.mjs +3 -11
- package/lib/publish.mjs +12 -29
- package/lib/reconcile/mcp-entry-reconcile.mjs +14 -9
- package/lib/reflect.mjs +2 -2
- package/lib/registry/agent-manifest.mjs +190 -0
- package/lib/registry/assemble.mjs +133 -0
- package/lib/registry/catalog.mjs +171 -0
- package/lib/registry/cli.mjs +590 -6
- package/lib/registry/consolidation.mjs +5 -4
- package/lib/registry/docs-sync.mjs +67 -0
- package/lib/registry/loader.mjs +147 -0
- package/lib/registry/org-io.mjs +76 -0
- package/lib/registry/retired-paths.mjs +71 -0
- package/lib/registry/surface-map.mjs +5 -7
- package/lib/registry/validator.mjs +438 -0
- package/lib/research-execution-policy.mjs +173 -0
- package/lib/roles/catalog.mjs +4 -9
- package/lib/roles/fence.mjs +107 -1
- package/lib/roles/flavor-bindings.mjs +68 -0
- package/lib/roles/gateway.mjs +140 -29
- package/lib/roles/manifest.mjs +22 -13
- package/lib/roles/router.mjs +1 -1
- package/lib/runtime-env.mjs +1 -1
- package/lib/scopes/enrich.mjs +67 -0
- package/lib/scopes/hooks.mjs +12 -0
- package/lib/{profiles → scopes}/lifecycle.mjs +70 -70
- package/lib/scopes/loader.mjs +104 -0
- package/lib/scopes/rebrand.mjs +32 -0
- package/lib/scopes/research-profile.mjs +16 -0
- package/lib/scopes/teams.mjs +98 -0
- package/lib/service-manager.mjs +1 -117
- package/lib/setup-prompts.mjs +1 -1
- package/lib/setup.mjs +17 -28
- package/lib/skills/composition-graph.mjs +98 -0
- package/lib/skills/router.mjs +80 -0
- package/lib/specialist-contracts.mjs +17 -18
- package/lib/specialists/postconditions.mjs +2 -2
- package/lib/specialists/prompt-schema.mjs +6 -5
- package/lib/specialists/roster.mjs +7 -12
- package/lib/specialists/schema.mjs +9 -6
- package/lib/status.mjs +25 -90
- package/lib/storage/file-lock.mjs +6 -3
- package/lib/telemetry/skill-calls.mjs +1 -1
- package/lib/templates/doc-presentation.mjs +63 -0
- package/lib/templates/visual-requirements.mjs +35 -2
- package/lib/term-format.mjs +107 -2
- package/lib/test-env-setup.mjs +21 -0
- package/lib/ui/components.mjs +42 -0
- package/lib/ui/glyphs.mjs +58 -0
- package/lib/ui/links.mjs +115 -0
- package/lib/ui/theme.mjs +108 -0
- package/lib/uninstall/uninstall.mjs +2 -1
- package/lib/validator.mjs +45 -8
- package/lib/validators/skill-effectiveness.mjs +174 -0
- package/lib/validators/skills.mjs +1 -1
- package/package.json +12 -7
- package/personas/construct.md +12 -3
- package/platforms/claude/CLAUDE.md +1 -1
- package/rules/common/beads-hygiene.md +52 -0
- package/rules/common/neurodivergent-output.md +4 -7
- package/rules/common/research.md +2 -0
- package/scripts/sync-specialists.mjs +260 -49
- package/skills/ai/prompt-optimizer.md +3 -3
- package/skills/brand/output-vibe.md +48 -0
- package/skills/docs/adr-workflow.md +3 -0
- package/skills/docs/backlog-proposal-workflow.md +3 -0
- package/skills/docs/codebase-research-workflow.md +5 -2
- package/skills/docs/customer-profile-workflow.md +3 -0
- package/skills/docs/document-ingest-workflow.md +3 -0
- package/skills/docs/evidence-ingest-workflow.md +4 -1
- package/skills/docs/init-project.md +1 -1
- package/skills/docs/prd-workflow.md +1 -1
- package/skills/docs/prfaq-workflow.md +3 -0
- package/skills/docs/product-intelligence-workflow.md +4 -1
- package/skills/docs/product-signal-workflow.md +3 -0
- package/skills/docs/research-workflow.md +13 -6
- package/skills/docs/runbook-workflow.md +3 -0
- package/skills/docs/strategy-workflow.md +3 -0
- package/skills/docs/user-research-workflow.md +6 -3
- package/skills/operating/orchestration-reference.md +1 -1
- package/skills/roles/{engineer.ai.md → ai-engineer.md} +2 -2
- package/skills/roles/architect.ai-systems.md +1 -1
- package/skills/roles/architect.data.md +1 -1
- package/skills/roles/architect.enterprise.md +1 -1
- package/skills/roles/architect.integration.md +1 -1
- package/skills/roles/architect.md +1 -1
- package/skills/roles/architect.platform.md +1 -1
- package/skills/roles/{product-manager.business-strategy.md → business-strategist.md} +3 -3
- package/skills/roles/data-analyst.experiment.md +1 -1
- package/skills/roles/data-analyst.md +1 -1
- package/skills/roles/data-analyst.product-intelligence.md +1 -1
- package/skills/roles/data-analyst.product.md +1 -1
- package/skills/roles/data-analyst.telemetry.md +1 -1
- package/skills/roles/{engineer.data.md → data-engineer.md} +2 -2
- package/skills/roles/data-engineer.pipeline.md +2 -2
- package/skills/roles/data-engineer.vector-retrieval.md +2 -2
- package/skills/roles/data-engineer.warehouse.md +2 -2
- package/skills/roles/debugger.md +1 -1
- package/skills/roles/designer.accessibility.md +1 -1
- package/skills/roles/designer.md +1 -1
- package/skills/roles/{reviewer.devil-advocate.md → devil-advocate.md} +2 -2
- package/skills/roles/{operator.docs.md → docs-keeper.md} +3 -3
- package/skills/roles/engineer.md +3 -7
- package/skills/roles/{reviewer.evaluator.md → evaluator.md} +2 -2
- package/skills/roles/{researcher.explorer.md → explorer.md} +2 -2
- package/skills/roles/{operator.md → operations.md} +2 -5
- package/skills/roles/orchestrator.md +1 -1
- package/skills/roles/{engineer.platform.md → platform-engineer.md} +2 -2
- package/skills/roles/product-manager.ai-product.md +1 -1
- package/skills/roles/product-manager.enterprise.md +1 -1
- package/skills/roles/product-manager.growth.md +1 -2
- package/skills/roles/product-manager.md +1 -2
- package/skills/roles/product-manager.platform.md +1 -1
- package/skills/roles/product-manager.product.md +1 -1
- package/skills/roles/qa.ai-eval.md +1 -1
- package/skills/roles/qa.api-contract.md +1 -1
- package/skills/roles/qa.data-pipeline.md +1 -1
- package/skills/roles/qa.md +1 -1
- package/skills/roles/qa.web-ui.md +1 -1
- package/skills/roles/{operator.release.md → release-manager.md} +3 -3
- package/skills/roles/researcher.md +1 -1
- package/skills/roles/reviewer.md +1 -1
- package/skills/roles/security.ai.md +1 -1
- package/skills/roles/security.appsec.md +1 -1
- package/skills/roles/security.cloud.md +1 -1
- package/skills/roles/security.legal-compliance.md +1 -1
- package/skills/roles/security.md +1 -1
- package/skills/roles/security.privacy.md +1 -1
- package/skills/roles/security.supply-chain.md +1 -1
- package/skills/roles/{operator.sre.md → sre.md} +3 -3
- package/skills/roles/{qa.test-automation.md → test-automation.md} +2 -2
- package/skills/roles/{reviewer.trace.md → trace-reviewer.md} +2 -2
- package/skills/roles/{researcher.ux.md → ux-researcher.md} +2 -2
- package/skills/routing.json +18 -0
- package/skills/routing.md +1 -1
- package/specialists/artifact-manifest.json +2 -1
- package/specialists/audit-enrichments.json +14 -14
- package/specialists/org/contracts/accessibility-to-qa.json +37 -0
- package/specialists/org/contracts/any-to-business-strategist.json +57 -0
- package/specialists/org/contracts/any-to-debugger.json +38 -0
- package/specialists/org/contracts/any-to-designer.json +33 -0
- package/specialists/org/contracts/any-to-docs-keeper.json +34 -0
- package/specialists/org/contracts/any-to-explorer.json +39 -0
- package/specialists/org/contracts/any-to-sre-incident.json +33 -0
- package/specialists/org/contracts/any-to-trace-reviewer.json +32 -0
- package/specialists/org/contracts/architect-to-ai-engineer.json +32 -0
- package/specialists/org/contracts/architect-to-data-engineer.json +52 -0
- package/specialists/org/contracts/architect-to-devil-advocate.json +38 -0
- package/specialists/org/contracts/architect-to-engineer.json +34 -0
- package/specialists/org/contracts/architect-to-evaluator.json +59 -0
- package/specialists/org/contracts/architect-to-legal-compliance.json +55 -0
- package/specialists/org/contracts/architect-to-operations.json +45 -0
- package/specialists/org/contracts/architect-to-platform-engineer.json +42 -0
- package/specialists/org/contracts/business-strategist-to-product-manager.json +39 -0
- package/specialists/org/contracts/construct-to-orchestrator.json +36 -0
- package/specialists/org/contracts/construct-to-rd-lead.json +53 -0
- package/specialists/org/contracts/data-analyst-to-product-manager.json +43 -0
- package/specialists/org/contracts/data-engineer-to-platform-engineer.json +36 -0
- package/specialists/org/contracts/designer-to-accessibility.json +36 -0
- package/specialists/org/contracts/engineer-to-qa.json +34 -0
- package/specialists/org/contracts/engineer-to-reviewer.json +52 -0
- package/specialists/org/contracts/explorer-to-engineer.json +38 -0
- package/specialists/org/contracts/legal-compliance-to-release-manager.json +43 -0
- package/specialists/org/contracts/platform-engineer-to-engineer.json +31 -0
- package/specialists/org/contracts/product-manager-to-architect.json +71 -0
- package/specialists/org/contracts/product-manager-to-data-analyst.json +49 -0
- package/specialists/org/contracts/product-manager-to-ux-researcher.json +51 -0
- package/specialists/org/contracts/qa-to-release-manager.json +42 -0
- package/specialists/org/contracts/qa-to-test-automation.json +42 -0
- package/specialists/org/contracts/rd-lead-to-architect.json +38 -0
- package/specialists/org/contracts/researcher-to-architect.json +40 -0
- package/specialists/org/contracts/researcher-to-product-manager.json +57 -0
- package/specialists/org/contracts/reviewer-to-security.json +41 -0
- package/specialists/org/contracts/sre-to-release-manager.json +36 -0
- package/specialists/org/contracts/test-automation-to-engineer.json +34 -0
- package/specialists/org/contracts/trace-reviewer-to-sre.json +41 -0
- package/specialists/org/contracts/user-to-construct.json +30 -0
- package/specialists/org/groups/engineering-group.json +43 -0
- package/specialists/org/groups/governance-group.json +38 -0
- package/specialists/org/groups/operations-group.json +41 -0
- package/specialists/org/groups/product-group.json +46 -0
- package/specialists/org/groups/quality-group.json +42 -0
- package/specialists/org/groups/strategy-group.json +41 -0
- package/specialists/org/policies/action-approval.json +13 -0
- package/specialists/org/policies/agents-routing.json +13 -0
- package/specialists/org/policies/architecture.json +20 -0
- package/specialists/org/policies/bash-safety.json +13 -0
- package/specialists/org/policies/beads-hygiene.json +13 -0
- package/specialists/org/policies/bootstrap-state.json +13 -0
- package/specialists/org/policies/code-review.json +13 -0
- package/specialists/org/policies/coding-style.json +13 -0
- package/specialists/org/policies/comments.json +13 -0
- package/specialists/org/policies/commit-approval.json +13 -0
- package/specialists/org/policies/contract-preconditions.json +13 -0
- package/specialists/org/policies/deployment.json +20 -0
- package/specialists/org/policies/description.json +14 -0
- package/specialists/org/policies/design-approval.json +19 -0
- package/specialists/org/policies/doc-ownership.json +13 -0
- package/specialists/org/policies/file-path-fence.json +13 -0
- package/specialists/org/policies/framing.json +13 -0
- package/specialists/org/policies/git-workflow.json +13 -0
- package/specialists/org/policies/incident-response.json +15 -0
- package/specialists/org/policies/intake-triage.json +15 -0
- package/specialists/org/policies/neurodivergent-output.json +13 -0
- package/specialists/org/policies/no-fabrication.json +13 -0
- package/specialists/org/policies/patterns.json +13 -0
- package/specialists/org/policies/quality-gate-approval.json +17 -0
- package/specialists/org/policies/release-gates.json +13 -0
- package/specialists/org/policies/research-evidence.json +13 -0
- package/specialists/org/policies/review-before-change.json +13 -0
- package/specialists/org/policies/rollback.json +15 -0
- package/specialists/org/policies/scope-change.json +20 -0
- package/specialists/org/policies/secret-scan.json +13 -0
- package/specialists/org/policies/security-approval.json +17 -0
- package/specialists/org/policies/security.json +13 -0
- package/specialists/org/policies/session-efficiency.json +13 -0
- package/specialists/org/policies/skill-routing.json +13 -0
- package/specialists/org/policies/strategic-prioritization.json +17 -0
- package/specialists/org/policies/testing.json +13 -0
- package/specialists/org/policies/tool-invisibility.json +14 -0
- package/specialists/org/scopes/creative.json +54 -0
- package/specialists/org/scopes/operations.json +51 -0
- package/specialists/org/scopes/research.json +60 -0
- package/specialists/org/scopes/rnd.json +81 -0
- package/specialists/org/specialists/cx-accessibility.json +69 -0
- package/specialists/org/specialists/cx-ai-engineer.json +75 -0
- package/specialists/org/specialists/cx-architect.json +89 -0
- package/specialists/org/specialists/cx-business-strategist.json +72 -0
- package/specialists/org/specialists/cx-data-analyst.json +68 -0
- package/specialists/org/specialists/cx-data-engineer.json +71 -0
- package/specialists/org/specialists/cx-debugger.json +75 -0
- package/specialists/org/specialists/cx-designer.json +85 -0
- package/specialists/org/specialists/cx-devil-advocate.json +71 -0
- package/specialists/org/specialists/cx-docs-keeper.json +82 -0
- package/specialists/org/specialists/cx-engineer.json +106 -0
- package/specialists/org/specialists/cx-evaluator.json +69 -0
- package/specialists/org/specialists/cx-explorer.json +69 -0
- package/specialists/org/specialists/cx-legal-compliance.json +74 -0
- package/specialists/org/specialists/cx-operations.json +72 -0
- package/specialists/org/specialists/cx-oracle.json +46 -0
- package/specialists/org/specialists/cx-orchestrator.json +81 -0
- package/specialists/org/specialists/cx-platform-engineer.json +80 -0
- package/specialists/org/specialists/cx-product-manager.json +102 -0
- package/specialists/org/specialists/cx-qa.json +79 -0
- package/specialists/org/specialists/cx-rd-lead.json +73 -0
- package/specialists/org/specialists/cx-release-manager.json +77 -0
- package/specialists/org/specialists/cx-researcher.json +82 -0
- package/specialists/org/specialists/cx-reviewer.json +71 -0
- package/specialists/org/specialists/cx-security.json +91 -0
- package/specialists/org/specialists/cx-sre.json +94 -0
- package/specialists/org/specialists/cx-test-automation.json +69 -0
- package/specialists/org/specialists/cx-trace-reviewer.json +69 -0
- package/specialists/org/specialists/cx-ux-researcher.json +68 -0
- package/specialists/org/teams/accessibility-team.json +39 -0
- package/specialists/org/teams/design-team.json +40 -0
- package/specialists/org/teams/engineering-team.json +50 -0
- package/specialists/org/teams/governance-team.json +41 -0
- package/specialists/org/teams/operations-team.json +46 -0
- package/specialists/org/teams/product-management-team.json +45 -0
- package/specialists/org/teams/quality-team.json +49 -0
- package/specialists/org/teams/research-team.json +39 -0
- package/specialists/org/teams/strategy-team.json +48 -0
- package/specialists/org/teams/ux-research-team.json +39 -0
- package/specialists/prompts/_shared/validation-contract.md +1 -1
- package/specialists/prompts/_team-template.md +10 -0
- package/specialists/prompts/cx-accessibility.md +1 -0
- package/specialists/prompts/cx-ai-engineer.md +1 -1
- package/specialists/prompts/cx-business-strategist.md +1 -1
- package/specialists/prompts/cx-data-engineer.md +1 -1
- package/specialists/prompts/cx-designer.md +1 -0
- package/specialists/prompts/cx-devil-advocate.md +1 -1
- package/specialists/prompts/cx-docs-keeper.md +1 -1
- package/specialists/prompts/cx-evaluator.md +1 -1
- package/specialists/prompts/cx-explorer.md +1 -1
- package/specialists/prompts/cx-operations.md +1 -1
- package/specialists/prompts/cx-oracle.md +7 -3
- package/specialists/prompts/cx-orchestrator.md +17 -1
- package/specialists/prompts/cx-platform-engineer.md +1 -1
- package/specialists/prompts/cx-product-manager.md +2 -0
- package/specialists/prompts/cx-release-manager.md +1 -1
- package/specialists/prompts/cx-researcher.md +7 -4
- package/specialists/prompts/cx-sre.md +1 -1
- package/specialists/prompts/cx-test-automation.md +2 -2
- package/specialists/prompts/cx-trace-reviewer.md +3 -3
- package/specialists/prompts/cx-ux-researcher.md +2 -1
- package/templates/demos/scripts/architecture-review-adr.json +30 -0
- package/templates/demos/scripts/capability-contract.json +25 -0
- package/templates/demos/scripts/intake-triage.json +25 -0
- package/templates/demos/scripts/profile-doctor-health.json +25 -0
- package/templates/demos/tapes/agentic-platforms-prd.tape +2 -2
- package/templates/demos/tapes/architecture-review-adr.tape +44 -0
- package/templates/demos/tapes/capability-contract.tape +39 -0
- package/templates/demos/tapes/intake-triage.tape +39 -0
- package/templates/demos/tapes/profile-doctor-health.tape +39 -0
- package/templates/distribution/construct-brand.typ +23 -18
- package/templates/distribution/construct-decision.typ +1 -1
- package/templates/distribution/construct-pdf.typ +1 -1
- package/templates/distribution/construct-prd.typ +1 -1
- package/templates/distribution/construct-research.typ +1 -1
- package/templates/distribution/mermaid-puppeteer.json +8 -0
- package/templates/docs/persona-artifact.md +1 -1
- package/templates/docs/prd.md +6 -0
- package/lib/boundary.mjs +0 -127
- package/lib/certification/dashboard-api.mjs +0 -71
- package/lib/chat/cli.mjs +0 -333
- package/lib/chat/command-suggest.mjs +0 -161
- package/lib/chat/commands.mjs +0 -215
- package/lib/chat/config.mjs +0 -142
- package/lib/chat/context-compactor.mjs +0 -250
- package/lib/chat/context-continuation.mjs +0 -253
- package/lib/chat/continuation-source.mjs +0 -58
- package/lib/chat/demo-guide.mjs +0 -61
- package/lib/chat/design-tokens.mjs +0 -91
- package/lib/chat/desktop-binary.mjs +0 -81
- package/lib/chat/desktop-build.mjs +0 -130
- package/lib/chat/desktop-launcher.mjs +0 -133
- package/lib/chat/evidence.mjs +0 -145
- package/lib/chat/export.mjs +0 -74
- package/lib/chat/harness/driver.mjs +0 -91
- package/lib/chat/list-picker.mjs +0 -112
- package/lib/chat/model-picker.mjs +0 -356
- package/lib/chat/openrouter-fallback.mjs +0 -151
- package/lib/chat/permission-prompt.mjs +0 -33
- package/lib/chat/picker-catalog.mjs +0 -45
- package/lib/chat/policy-telemetry.mjs +0 -34
- package/lib/chat/present.mjs +0 -246
- package/lib/chat/session-context.mjs +0 -39
- package/lib/chat/session-persist.mjs +0 -73
- package/lib/chat/session-restore.mjs +0 -71
- package/lib/chat/session-settings.mjs +0 -53
- package/lib/chat/system-prompt.mjs +0 -52
- package/lib/chat/transparency.mjs +0 -93
- package/lib/chat/tui/color-scheme.mjs +0 -42
- package/lib/chat/tui/markdown.mjs +0 -123
- package/lib/chat/tui/presentation.mjs +0 -100
- package/lib/chat/tui/render.mjs +0 -500
- package/lib/chat/tui/turn-block.mjs +0 -284
- package/lib/chat/tui/turn-present.mjs +0 -18
- package/lib/chat/tui/turn-state.mjs +0 -88
- package/lib/chat/tui/usage.mjs +0 -122
- package/lib/chat/web-commands.mjs +0 -146
- package/lib/chat/web-launcher.mjs +0 -63
- package/lib/chat/web-picker-keys.mjs +0 -46
- package/lib/chat/web-session.mjs +0 -159
- package/lib/config/alias.mjs +0 -57
- package/lib/dashboard-demo.mjs +0 -71
- package/lib/dashboard-static.mjs +0 -175
- package/lib/install/desktop-binary-download.mjs +0 -88
- package/lib/profiles/loader.mjs +0 -123
- package/lib/profiles/rebrand.mjs +0 -46
- package/lib/server/auth.mjs +0 -169
- package/lib/server/chat-loop.mjs +0 -622
- package/lib/server/chat.mjs +0 -336
- package/lib/server/cors.mjs +0 -77
- package/lib/server/csrf.mjs +0 -103
- package/lib/server/demo-preview.mjs +0 -63
- package/lib/server/index.mjs +0 -2641
- package/lib/server/insights.mjs +0 -780
- package/lib/server/langfuse-login.mjs +0 -58
- package/lib/server/rate-limit.mjs +0 -93
- package/lib/server/telemetry-login.mjs +0 -100
- package/lib/server/webhook.mjs +0 -512
- package/specialists/contracts.json +0 -1032
- package/specialists/contracts.schema.json +0 -83
- package/specialists/policy-inventory.json +0 -188
- package/specialists/registry.json +0 -1412
- package/specialists/role-manifests.json +0 -217
- package/specialists/teams.json +0 -94
package/lib/oracle/reconcile.mjs
CHANGED
|
@@ -93,6 +93,20 @@ function pruneRaisedIssues(projectDir, { dryRun = false } = {}) {
|
|
|
93
93
|
|
|
94
94
|
const BARE_GOAL_FIELD_LABELS = ['intent', 'workCategory', 'riskFlags', 'acceptanceCriteria'];
|
|
95
95
|
|
|
96
|
+
const RESEARCHER_PROBE_MISSING = [
|
|
97
|
+
'artifact missing required field: question',
|
|
98
|
+
'artifact missing required field: method',
|
|
99
|
+
'artifact missing required field: sources',
|
|
100
|
+
'artifact missing required field: findings',
|
|
101
|
+
'artifact missing required field: confidence',
|
|
102
|
+
];
|
|
103
|
+
|
|
104
|
+
const A11Y_PROBE_MISSING = [
|
|
105
|
+
'artifact missing required field: findings',
|
|
106
|
+
'artifact missing required field: wcagCriterion',
|
|
107
|
+
'artifact missing required field: userImpact',
|
|
108
|
+
];
|
|
109
|
+
|
|
96
110
|
function missingBareGoalConstructFields(missing) {
|
|
97
111
|
if (!Array.isArray(missing) || missing.length !== BARE_GOAL_FIELD_LABELS.length) return false;
|
|
98
112
|
return BARE_GOAL_FIELD_LABELS.every((field) =>
|
|
@@ -107,6 +121,19 @@ function isBareGoalConstructViolation(row) {
|
|
|
107
121
|
return Array.isArray(keys) && keys.length === 1 && keys[0] === 'goal';
|
|
108
122
|
}
|
|
109
123
|
|
|
124
|
+
function isEmptyProbeViolation(row, contractId, expectedMissing) {
|
|
125
|
+
if (row?.contractId !== contractId) return false;
|
|
126
|
+
const keys = row.packet_keys ?? row.packetKeys;
|
|
127
|
+
if (!Array.isArray(keys) || keys.length !== 0) return false;
|
|
128
|
+
return JSON.stringify(row.missing) === JSON.stringify(expectedMissing);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function isDevSessionContractNoise(row) {
|
|
132
|
+
return isBareGoalConstructViolation(row)
|
|
133
|
+
|| isEmptyProbeViolation(row, 'researcher-to-architect', RESEARCHER_PROBE_MISSING)
|
|
134
|
+
|| isEmptyProbeViolation(row, 'accessibility-to-qa', A11Y_PROBE_MISSING);
|
|
135
|
+
}
|
|
136
|
+
|
|
110
137
|
/**
|
|
111
138
|
* @param {string} projectDir
|
|
112
139
|
* @returns {{ shouldSupersede: boolean, recentCount: number, reason: string }}
|
|
@@ -116,18 +143,18 @@ export function planContractViolationSupersede(projectDir) {
|
|
|
116
143
|
if (!recent.length) {
|
|
117
144
|
return { shouldSupersede: false, recentCount: 0, reason: 'no recent contract violations' };
|
|
118
145
|
}
|
|
119
|
-
const
|
|
120
|
-
if (!
|
|
146
|
+
const allDevSessionNoise = recent.every(isDevSessionContractNoise);
|
|
147
|
+
if (!allDevSessionNoise) {
|
|
121
148
|
return {
|
|
122
149
|
shouldSupersede: false,
|
|
123
150
|
recentCount: recent.length,
|
|
124
|
-
reason: 'recent violations include non-
|
|
151
|
+
reason: 'recent violations include non-probe contract failures',
|
|
125
152
|
};
|
|
126
153
|
}
|
|
127
154
|
return {
|
|
128
155
|
shouldSupersede: true,
|
|
129
156
|
recentCount: recent.length,
|
|
130
|
-
reason: '
|
|
157
|
+
reason: 'dev-session contract probes superseded (bare-goal construct, empty researcher/a11y packets)',
|
|
131
158
|
};
|
|
132
159
|
}
|
|
133
160
|
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lib/oracle/remediation-dispatch.mjs — static vs swarm dispatch for Oracle remediation.
|
|
3
|
+
*
|
|
4
|
+
* Seeds orchestration-policy teamRouting with gap/action remediation specialists.
|
|
5
|
+
* Swarm when involvedTeams.length > 1; static when a single team owns the work.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { classifyIntent, teamRoutingForSpecialists } from '../orchestration-policy.mjs';
|
|
9
|
+
import { routeGap, routeAction } from './routing.mjs';
|
|
10
|
+
|
|
11
|
+
function remediationText(item) {
|
|
12
|
+
return String(item.detail ?? item.summary ?? item.id ?? 'Oracle remediation');
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function seededSpecialists(item) {
|
|
16
|
+
const route = item.remediationRoute ?? (item.kind ? routeAction(item.kind) : routeGap(item));
|
|
17
|
+
return [route.primary, route.secondary].filter(Boolean);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @param {object} item — gap or recommended action with optional remediationRoute
|
|
22
|
+
* @param {{ projectDir?: string, cwd?: string }} [opts]
|
|
23
|
+
* @returns {{ mode: 'static'|'swarm', primary: string, specialists: string[], teamRouting: object }}
|
|
24
|
+
*/
|
|
25
|
+
export function resolveRemediationDispatch(item, { projectDir, cwd } = {}) {
|
|
26
|
+
const route = item.remediationRoute ?? (item.kind ? routeAction(item.kind) : routeGap(item));
|
|
27
|
+
const primary = route.primary;
|
|
28
|
+
const specialists = seededSpecialists(item);
|
|
29
|
+
const request = remediationText(item);
|
|
30
|
+
const intent = classifyIntent(request);
|
|
31
|
+
const teamRouting = teamRoutingForSpecialists(specialists, {
|
|
32
|
+
intent,
|
|
33
|
+
request,
|
|
34
|
+
cwd: cwd ?? projectDir ?? null,
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const involvedTeams = teamRouting.involvedTeams ?? [];
|
|
38
|
+
if (involvedTeams.length <= 1) {
|
|
39
|
+
return {
|
|
40
|
+
mode: 'static',
|
|
41
|
+
primary,
|
|
42
|
+
specialists: [primary],
|
|
43
|
+
teamRouting,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
mode: 'swarm',
|
|
49
|
+
primary,
|
|
50
|
+
specialists: Array.from(new Set(specialists)),
|
|
51
|
+
teamRouting,
|
|
52
|
+
};
|
|
53
|
+
}
|
package/lib/oracle/routing.mjs
CHANGED
|
@@ -34,6 +34,11 @@ const GAP_ROUTES = {
|
|
|
34
34
|
'dependency-graph-stale': { primary: 'cx-platform-engineer', secondary: null },
|
|
35
35
|
'matrix-coverage-gap': { primary: 'cx-architect', secondary: 'cx-qa' },
|
|
36
36
|
'impact-untested': { primary: 'cx-qa', secondary: 'cx-engineer' },
|
|
37
|
+
// Team governance signals — route to rd-lead for strategic resolution
|
|
38
|
+
'team-understaffed': { primary: 'cx-rd-lead', secondary: 'cx-orchestrator' },
|
|
39
|
+
'escalation-path-broken': { primary: 'cx-rd-lead', secondary: 'cx-architect' },
|
|
40
|
+
'team-decision-violation': { primary: 'cx-rd-lead', secondary: 'cx-orchestrator' },
|
|
41
|
+
'cross-team-handoff-blocked': { primary: 'cx-rd-lead', secondary: null },
|
|
37
42
|
};
|
|
38
43
|
|
|
39
44
|
const ACTION_ROUTES = {
|
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
|
|
6
6
|
import { orgGraphToGapHints } from './org-graph.mjs';
|
|
7
7
|
import { routeAction, routeGap, signOffMetadata } from './routing.mjs';
|
|
8
|
+
import { resolveRemediationDispatch } from './remediation-dispatch.mjs';
|
|
9
|
+
import { isConstructPackageRepo } from '../host-disposition.mjs';
|
|
8
10
|
|
|
9
11
|
const LOW_SUCCESS_RATE = 0.6;
|
|
10
12
|
|
|
@@ -224,7 +226,8 @@ export function synthesizeVerdict(readModel) {
|
|
|
224
226
|
}
|
|
225
227
|
|
|
226
228
|
const dupLanes = readModel.structure?.duplicateLanes ?? [];
|
|
227
|
-
|
|
229
|
+
const skipStructureSprawl = isConstructPackageRepo(readModel.projectDir);
|
|
230
|
+
if (dupLanes.length > 0 && !skipStructureSprawl) {
|
|
228
231
|
gaps.push(gap(
|
|
229
232
|
'structure-sprawl',
|
|
230
233
|
'medium',
|
|
@@ -259,11 +262,13 @@ export function synthesizeVerdict(readModel) {
|
|
|
259
262
|
|
|
260
263
|
const artifactGate = readModel.artifactGate ?? {};
|
|
261
264
|
if (artifactGate.specialistAudit?.present && !artifactGate.specialistAudit.pass) {
|
|
265
|
+
const auditDetail = artifactGate.specialistAudit.error
|
|
266
|
+
?? `${artifactGate.specialistAudit.crossCheckCount} issue(s)`;
|
|
262
267
|
gaps.push(gap(
|
|
263
268
|
'specialist-audit-drift',
|
|
264
269
|
'high',
|
|
265
270
|
'artifact-manifest',
|
|
266
|
-
`Specialist audit cross-check failed (${
|
|
271
|
+
`Specialist audit cross-check failed (${auditDetail})`,
|
|
267
272
|
));
|
|
268
273
|
recommendedActions.push(action(
|
|
269
274
|
'registry-validate',
|
|
@@ -285,7 +290,7 @@ export function synthesizeVerdict(readModel) {
|
|
|
285
290
|
));
|
|
286
291
|
}
|
|
287
292
|
|
|
288
|
-
if ((artifactGate.reviewerGapCount ?? 0) > 0) {
|
|
293
|
+
if ((artifactGate.reviewerGapCount ?? 0) > 0 && artifactGate.reviewerGateArmed !== false) {
|
|
289
294
|
gaps.push(gap(
|
|
290
295
|
'artifact-reviewer-gap',
|
|
291
296
|
'medium',
|
|
@@ -340,6 +345,70 @@ export function synthesizeVerdict(readModel) {
|
|
|
340
345
|
}
|
|
341
346
|
}
|
|
342
347
|
|
|
348
|
+
// Team governance signals from unified registry
|
|
349
|
+
const teamGov = readModel.teamGovernance ?? { present: false, teams: {} };
|
|
350
|
+
if (teamGov.present) {
|
|
351
|
+
const understaffedTeams = Object.values(teamGov.teams ?? {}).filter((t) => t.understaffed);
|
|
352
|
+
if (understaffedTeams.length > 0) {
|
|
353
|
+
gaps.push(gap(
|
|
354
|
+
'team-understaffed',
|
|
355
|
+
'high',
|
|
356
|
+
'team-governance',
|
|
357
|
+
`${understaffedTeams.length} team(s) understaffed: ${understaffedTeams.map((t) => t.id).join(', ')}`,
|
|
358
|
+
));
|
|
359
|
+
recommendedActions.push(action(
|
|
360
|
+
'specialist-review',
|
|
361
|
+
'Review team staffing gaps and escalate to rd-lead for resolution',
|
|
362
|
+
{ teams: understaffedTeams.map((t) => ({ id: t.id, name: t.name })) },
|
|
363
|
+
));
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
const brokenEscalations = Object.values(teamGov.teams ?? {}).filter((t) => t.escalationPathBroken);
|
|
367
|
+
if (brokenEscalations.length > 0) {
|
|
368
|
+
gaps.push(gap(
|
|
369
|
+
'escalation-path-broken',
|
|
370
|
+
'high',
|
|
371
|
+
'team-governance',
|
|
372
|
+
`${brokenEscalations.length} team(s) have broken escalation path: ${brokenEscalations.map((t) => t.id).join(', ')}`,
|
|
373
|
+
));
|
|
374
|
+
recommendedActions.push(action(
|
|
375
|
+
'registry-validate',
|
|
376
|
+
'Validate and repair team escalation paths in unified registry',
|
|
377
|
+
{ teams: brokenEscalations.map((t) => t.id) },
|
|
378
|
+
));
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
const ownerlessTeams = Object.values(teamGov.teams ?? {}).filter((t) => !t.ownerExists);
|
|
382
|
+
if (ownerlessTeams.length > 0) {
|
|
383
|
+
gaps.push(gap(
|
|
384
|
+
'team-decision-violation',
|
|
385
|
+
'high',
|
|
386
|
+
'team-governance',
|
|
387
|
+
`${ownerlessTeams.length} team(s) missing owner specialist: ${ownerlessTeams.map((t) => `${t.id} (owner: ${t.owner})`).join(', ')}`,
|
|
388
|
+
));
|
|
389
|
+
recommendedActions.push(action(
|
|
390
|
+
'specialist-review',
|
|
391
|
+
'Assign specialists to team owner roles or update registry',
|
|
392
|
+
{ teams: ownerlessTeams.map((t) => ({ id: t.id, missingOwner: t.owner })) },
|
|
393
|
+
));
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
const blockedHandoffs = teamGov.crossTeamHandoffsBlocked ?? [];
|
|
397
|
+
if (blockedHandoffs.length > 0) {
|
|
398
|
+
gaps.push(gap(
|
|
399
|
+
'cross-team-handoff-blocked',
|
|
400
|
+
'high',
|
|
401
|
+
'team-governance',
|
|
402
|
+
`${blockedHandoffs.length} cross-team handoff(s) blocked on an unstaffed approver team: ${blockedHandoffs.map((h) => `${h.contract} (needs ${h.blockedBy.join(', ')})`).join('; ')}`,
|
|
403
|
+
));
|
|
404
|
+
recommendedActions.push(action(
|
|
405
|
+
'specialist-review',
|
|
406
|
+
'Staff the required approver team(s) or relax the cross-team approval requirement so the handoff can complete',
|
|
407
|
+
{ handoffs: blockedHandoffs },
|
|
408
|
+
));
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
343
412
|
for (const hint of orgGraphToGapHints(readModel.orgGraph ?? {})) {
|
|
344
413
|
if (!gaps.some((g) => g.id === hint.id)) gaps.push(hint);
|
|
345
414
|
if (hint.id === 'workflow-misaligned') {
|
|
@@ -365,6 +434,10 @@ export function synthesizeVerdict(readModel) {
|
|
|
365
434
|
secondary: route.secondary ?? null,
|
|
366
435
|
gateType: route.gateType ?? null,
|
|
367
436
|
};
|
|
437
|
+
const dispatch = resolveRemediationDispatch(g, { projectDir: readModel.projectDir });
|
|
438
|
+
g.remediationRoute.mode = dispatch.mode;
|
|
439
|
+
g.remediationRoute.specialists = dispatch.specialists;
|
|
440
|
+
g.remediationRoute.teamRouting = dispatch.teamRouting;
|
|
368
441
|
}
|
|
369
442
|
for (const a of recommendedActions) {
|
|
370
443
|
const route = routeAction(a.kind);
|
|
@@ -372,6 +445,10 @@ export function synthesizeVerdict(readModel) {
|
|
|
372
445
|
primary: route.primary,
|
|
373
446
|
gateType: route.gateType ?? null,
|
|
374
447
|
};
|
|
448
|
+
const dispatch = resolveRemediationDispatch(a, { projectDir: readModel.projectDir });
|
|
449
|
+
a.remediationRoute.mode = dispatch.mode;
|
|
450
|
+
a.remediationRoute.specialists = dispatch.specialists;
|
|
451
|
+
a.remediationRoute.teamRouting = dispatch.teamRouting;
|
|
375
452
|
}
|
|
376
453
|
|
|
377
454
|
let verdict = 'healthy';
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* lib/orchestration/routing-tables.mjs — declarative routing resolver.
|
|
3
3
|
*
|
|
4
4
|
* Reads specialist subscriptions, doc-artifact ownership, and watch-condition
|
|
5
|
-
* references from specialists/
|
|
5
|
+
* references from specialists/org (with optional .cx/specialists/
|
|
6
6
|
* overlays) and exposes the forward lookups the orchestration layer needs.
|
|
7
7
|
*
|
|
8
8
|
* The resolver is the single source of truth for event/doc/watch routing.
|
|
@@ -19,10 +19,8 @@
|
|
|
19
19
|
|
|
20
20
|
import { readFileSync, existsSync, readdirSync } from 'node:fs';
|
|
21
21
|
import { join } from 'node:path';
|
|
22
|
-
import { fileURLToPath } from 'node:url';
|
|
23
22
|
import { findProjectRoot } from '../project-root.mjs';
|
|
24
|
-
|
|
25
|
-
const REGISTRY_PATH = fileURLToPath(new URL('../../specialists/registry.json', import.meta.url));
|
|
23
|
+
import { loadRegistry, clearCache } from '../registry/loader.mjs';
|
|
26
24
|
|
|
27
25
|
// Watch-condition predicates. Each is a pure function from requestSignals
|
|
28
26
|
// (see orchestration-policy.requestSignals) to boolean. Registry entries
|
|
@@ -65,9 +63,10 @@ function loadOverlays() {
|
|
|
65
63
|
}
|
|
66
64
|
|
|
67
65
|
function buildTables() {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
66
|
+
clearCache();
|
|
67
|
+
const registry = loadRegistry();
|
|
68
|
+
if (!registry || typeof registry.specialists !== 'object') {
|
|
69
|
+
throw new Error('routing-tables: assembled registry missing or malformed');
|
|
71
70
|
}
|
|
72
71
|
|
|
73
72
|
// Forward maps. Last writer wins for overlays; the resolver validates
|
|
@@ -83,8 +82,8 @@ function buildTables() {
|
|
|
83
82
|
|
|
84
83
|
function apply(entry, source) {
|
|
85
84
|
const cxId = entry.name?.startsWith('cx-') ? entry.name : `cx-${entry.name}`;
|
|
86
|
-
if (Array.isArray(entry.subscriptions)) {
|
|
87
|
-
for (const event of entry.subscriptions) {
|
|
85
|
+
if (Array.isArray(entry.events || entry.subscriptions)) {
|
|
86
|
+
for (const event of (entry.events || entry.subscriptions)) {
|
|
88
87
|
if (eventToOwner.has(event) && eventToOwner.get(event) !== cxId && source === 'registry') {
|
|
89
88
|
errors.push(`duplicate event ownership: ${event} → ${eventToOwner.get(event)} vs ${cxId}`);
|
|
90
89
|
}
|
|
@@ -113,7 +112,7 @@ function buildTables() {
|
|
|
113
112
|
}
|
|
114
113
|
}
|
|
115
114
|
|
|
116
|
-
for (const entry of registry.specialists) apply(entry, 'registry');
|
|
115
|
+
for (const entry of Object.values(registry.specialists)) apply(entry, 'registry');
|
|
117
116
|
for (const overlay of loadOverlays()) apply(overlay, 'overlay');
|
|
118
117
|
|
|
119
118
|
if (errors.length > 0) {
|
|
@@ -171,6 +170,41 @@ export function knownWatchers() {
|
|
|
171
170
|
return Object.keys(WATCHERS);
|
|
172
171
|
}
|
|
173
172
|
|
|
173
|
+
/**
|
|
174
|
+
* Get the team id for a specialist.
|
|
175
|
+
* Returns the team id or null if specialist not found.
|
|
176
|
+
*/
|
|
177
|
+
export function teamForSpecialist(specialistId) {
|
|
178
|
+
if (!specialistId) return null;
|
|
179
|
+
const registry = loadRegistry();
|
|
180
|
+
if (!registry?.specialists) return null;
|
|
181
|
+
const cxId = specialistId.startsWith('cx-') ? specialistId : `cx-${specialistId}`;
|
|
182
|
+
return registry.specialists[cxId]?.team || null;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Get all specialists in a team.
|
|
187
|
+
* Returns array of specialist ids (with cx- prefix).
|
|
188
|
+
*/
|
|
189
|
+
export function specialistsInTeam(teamId) {
|
|
190
|
+
if (!teamId) return [];
|
|
191
|
+
const registry = loadRegistry();
|
|
192
|
+
if (!registry?.specialists) return [];
|
|
193
|
+
return Object.entries(registry.specialists)
|
|
194
|
+
.filter(([, s]) => s.team === teamId)
|
|
195
|
+
.map(([id]) => id);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Get team definition by id.
|
|
200
|
+
* Returns team object or null if not found.
|
|
201
|
+
*/
|
|
202
|
+
export function getTeamById(teamId) {
|
|
203
|
+
if (!teamId) return null;
|
|
204
|
+
const registry = loadRegistry();
|
|
205
|
+
return registry?.teams?.[teamId] || null;
|
|
206
|
+
}
|
|
207
|
+
|
|
174
208
|
export function _resetCache() {
|
|
175
209
|
cache = null;
|
|
176
210
|
}
|
|
@@ -185,6 +185,8 @@ export async function planRun(request = {}, { env = process.env, cwd = process.c
|
|
|
185
185
|
intent: route.intent,
|
|
186
186
|
track: route.track,
|
|
187
187
|
specialists: route.specialists || [],
|
|
188
|
+
suggestedWorkflowType: route.suggestedWorkflowType || null,
|
|
189
|
+
researchExecutionPolicy: route.researchExecutionPolicy || null,
|
|
188
190
|
dispatchPlan: route.dispatchPlan,
|
|
189
191
|
contractChain: (route.contractChain || []).map((e) => ({ id: e.contract?.id, producer: e.contract?.producer, consumer: e.contract?.consumer, stage: e.stage })),
|
|
190
192
|
},
|
|
@@ -95,7 +95,7 @@ function anthropicThinkingConfig(model) {
|
|
|
95
95
|
|
|
96
96
|
// Key resolution delegates to the shared secret resolver so env, the dotenv
|
|
97
97
|
// files, shell rc exports, and 1Password op:// references all behave identically
|
|
98
|
-
// across the worker
|
|
98
|
+
// across the worker and router. allowAmbient stays the
|
|
99
99
|
// hermetic switch: a caller that injects its own env (embedded callers, tests)
|
|
100
100
|
// suppresses file/rc discovery so a developer's real key never bleeds into a run.
|
|
101
101
|
|