@geraldmaron/construct 1.2.3 → 1.3.1
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 +235 -209
- 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 +55 -54
- package/lib/comment-lint.mjs +1 -5
- package/lib/completions.mjs +20 -2
- package/lib/config/legacy-config-migration.mjs +90 -24
- 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/cli.mjs +12 -2
- package/lib/doctor/source-checkout.mjs +3 -4
- package/lib/doctor/watchers/consistency.mjs +148 -43
- 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/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 +6 -26
- 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 -8
- 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 +269 -51
- 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/apps/chat/engine/ai-sdk-agent.mjs +0 -183
- package/apps/chat/engine/loop-driver.mjs +0 -211
- package/apps/chat/engine/models.mjs +0 -122
- package/apps/chat/engine/provider-adapters.mjs +0 -171
- package/apps/chat/engine/tools/permission.mjs +0 -54
- package/apps/chat/engine/tools/primitives.mjs +0 -180
- package/apps/chat/engine/tools/registry.mjs +0 -122
- package/apps/chat/engine/turn-controls.mjs +0 -70
- 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
|
@@ -153,7 +153,7 @@ export function detectActiveSessions() {
|
|
|
153
153
|
// dispatch or config-driven agents): Claude Code, OpenCode.
|
|
154
154
|
// mcp-orchestrated — no native subagent primitive, but the host calls the
|
|
155
155
|
// `orchestration_run` MCP tool to reach the same orchestrated
|
|
156
|
-
// outcome
|
|
156
|
+
// outcome in-process: Codex, VS Code, Cursor, Copilot.
|
|
157
157
|
// prompt-only — neither native dispatch nor MCP; instruction files only.
|
|
158
158
|
// No supported 2026 host is prompt-only.
|
|
159
159
|
|
|
@@ -211,7 +211,7 @@ export function detectHostCapabilities() {
|
|
|
211
211
|
sharedTaskRuntime: "tracker-plus-plan",
|
|
212
212
|
lifecycleHooks: [],
|
|
213
213
|
notes: [
|
|
214
|
-
"Run a full multi-specialist chain via the `orchestration_run` MCP tool (
|
|
214
|
+
"Run a full multi-specialist chain via the `orchestration_run` MCP tool (in-process; no daemon needed).",
|
|
215
215
|
"Use Construct profiles, MCP project/memory tools, and the active session for single-pass work.",
|
|
216
216
|
],
|
|
217
217
|
},
|
|
@@ -225,7 +225,7 @@ export function detectHostCapabilities() {
|
|
|
225
225
|
sharedTaskRuntime: "editor-session",
|
|
226
226
|
lifecycleHooks: [],
|
|
227
227
|
notes: [
|
|
228
|
-
"Run a full multi-specialist chain via the `orchestration_run` MCP tool in Copilot agent mode (
|
|
228
|
+
"Run a full multi-specialist chain via the `orchestration_run` MCP tool in Copilot agent mode (in-process; no daemon needed).",
|
|
229
229
|
"Construct's MCP servers load from `.vscode/mcp.json` (project) and the user-profile `mcp.json` (global, only when it already exists).",
|
|
230
230
|
],
|
|
231
231
|
},
|
|
@@ -239,7 +239,7 @@ export function detectHostCapabilities() {
|
|
|
239
239
|
sharedTaskRuntime: "editor-session",
|
|
240
240
|
lifecycleHooks: [],
|
|
241
241
|
notes: [
|
|
242
|
-
"Run a full multi-specialist chain via the `orchestration_run` MCP tool (
|
|
242
|
+
"Run a full multi-specialist chain via the `orchestration_run` MCP tool (in-process; no daemon needed).",
|
|
243
243
|
"Construct manages Cursor MCP registrations in `.cursor/mcp.json` (project) and `~/.cursor/mcp.json` (global, when it already exists).",
|
|
244
244
|
],
|
|
245
245
|
},
|
|
@@ -253,7 +253,7 @@ export function detectHostCapabilities() {
|
|
|
253
253
|
sharedTaskRuntime: "editor-session",
|
|
254
254
|
lifecycleHooks: [],
|
|
255
255
|
notes: [
|
|
256
|
-
"Copilot agent mode runs Construct's MCP tools — use `orchestration_run` for a real multi-specialist chain (
|
|
256
|
+
"Copilot agent mode runs Construct's MCP tools — use `orchestration_run` for a real multi-specialist chain (in-process; no daemon needed).",
|
|
257
257
|
"Construct also writes reusable prompt profiles under `.github/prompts/` for single-pass role work.",
|
|
258
258
|
],
|
|
259
259
|
},
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* The controller is the mutation boundary for the governed loop. It admits only
|
|
6
6
|
* versioned artifacts — proposal objects, dataset items, and evaluation reports,
|
|
7
|
-
* never raw
|
|
7
|
+
* never raw unversioned session history — and refuses any candidate that lacks provenance,
|
|
8
8
|
* lacks held-out evaluation evidence, failed a deterministic gate, names an unknown
|
|
9
9
|
* approver, or has an unresolved dependency. Promotability is re-derived from the
|
|
10
10
|
* report's own gate results rather than a precomputed flag, so a tampered decision
|
|
@@ -22,7 +22,7 @@ function isVersioned(artifact) {
|
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
24
|
* Admit the input artifacts. Only versioned proposal/dataset/evaluation objects are
|
|
25
|
-
* accepted; an unversioned blob (such as raw
|
|
25
|
+
* accepted; an unversioned blob (such as raw session history) is refused
|
|
26
26
|
* (construct-6zga.1.5 AC1).
|
|
27
27
|
*/
|
|
28
28
|
export function admitArtifacts({ proposal = null, dataset = null, evaluationReport = null } = {}) {
|
package/lib/init-unified.mjs
CHANGED
|
@@ -69,11 +69,11 @@ const commitBootstrap = args.includes("--commit-bootstrap");
|
|
|
69
69
|
const withHostFlags = new Set(HOST_KEYS.filter((k) => args.includes(`--with-${k}`)));
|
|
70
70
|
const allHosts = args.includes("--all-hosts");
|
|
71
71
|
|
|
72
|
-
// Active
|
|
73
|
-
// project's construct.config.json so
|
|
72
|
+
// Active scope selector. `--scope=<id>` writes the field into the
|
|
73
|
+
// project's construct.config.json so resolveActiveScope picks it up
|
|
74
74
|
// on first run. Unknown ids are rejected with the available catalog.
|
|
75
|
-
const
|
|
76
|
-
const
|
|
75
|
+
const scopeArg = args.find((arg) => arg.startsWith("--scope="));
|
|
76
|
+
const scopeId = scopeArg ? scopeArg.split("=")[1] : null;
|
|
77
77
|
|
|
78
78
|
const created = [];
|
|
79
79
|
const skipped = [];
|
|
@@ -745,10 +745,10 @@ async function main() {
|
|
|
745
745
|
const { findProjectConfigPath, loadProjectConfig, writeProjectConfig, PROJECT_CONFIG_FILENAME } = await import('./config/project-config.mjs');
|
|
746
746
|
const { DEFAULT_PROJECT_CONFIG } = await import('./config/schema.mjs');
|
|
747
747
|
|
|
748
|
-
if (
|
|
749
|
-
const {
|
|
750
|
-
if (!
|
|
751
|
-
console.error(`Unknown
|
|
748
|
+
if (scopeId) {
|
|
749
|
+
const { loadScope, listScopes } = await import('./scopes/loader.mjs');
|
|
750
|
+
if (!loadScope(scopeId)) {
|
|
751
|
+
console.error(`Unknown scope: ${scopeId}. Available: ${listScopes().join(', ')}`);
|
|
752
752
|
process.exit(1);
|
|
753
753
|
}
|
|
754
754
|
}
|
|
@@ -763,29 +763,29 @@ async function main() {
|
|
|
763
763
|
const cfg = {
|
|
764
764
|
$schema: "./node_modules/@geraldmaron/construct/schemas/project-config.schema.json",
|
|
765
765
|
...DEFAULT_PROJECT_CONFIG,
|
|
766
|
-
|
|
766
|
+
scope: scopeId || 'rnd',
|
|
767
767
|
};
|
|
768
768
|
// Explicitly write the full default config object so all options are
|
|
769
769
|
// visible and discoverable to the user in the file. The $schema property
|
|
770
770
|
// provides inline documentation and validation in supported editors.
|
|
771
771
|
writeProjectConfig(cfgPath, cfg, { validate: true, silent: true });
|
|
772
772
|
created.push(PROJECT_CONFIG_FILENAME);
|
|
773
|
-
if (!quiet &&
|
|
774
|
-
} else if (
|
|
773
|
+
if (!quiet && scopeId) console.log(`Scope set to ${scopeId}.`);
|
|
774
|
+
} else if (scopeId) {
|
|
775
775
|
const loaded = loadProjectConfig(target);
|
|
776
776
|
const cfg = loaded?.raw ? { ...loaded.raw } : { version: 1 };
|
|
777
|
-
cfg.
|
|
777
|
+
cfg.scope = scopeId;
|
|
778
778
|
writeProjectConfig(cfgPath, cfg, { validate: true, silent: true });
|
|
779
|
-
if (!quiet) console.log(`
|
|
779
|
+
if (!quiet) console.log(`Scope set to ${scopeId}.`);
|
|
780
780
|
}
|
|
781
781
|
}
|
|
782
782
|
|
|
783
|
-
// Resolve active
|
|
784
|
-
// archetype, attribution stamping). Falls back to rnd when no
|
|
785
|
-
// configured — matches
|
|
783
|
+
// Resolve active scope to drive capability-gated scaffolding (intake
|
|
784
|
+
// archetype, attribution stamping). Falls back to rnd when no scope is
|
|
785
|
+
// configured — matches resolveActiveScope semantics elsewhere.
|
|
786
786
|
|
|
787
|
-
const {
|
|
788
|
-
const activeProfile =
|
|
787
|
+
const { resolveActiveScope } = await import('./scopes/loader.mjs');
|
|
788
|
+
const activeProfile = resolveActiveScope(target, scopeId) ?? null;
|
|
789
789
|
const intakeCap = activeProfile?.capabilities?.intake ?? null;
|
|
790
790
|
const { gatherAttribution } = await import('./intake/attribution.mjs');
|
|
791
791
|
const attribution = intakeCap?.attribution ? gatherAttribution() : null;
|
|
@@ -1228,12 +1228,10 @@ async function main() {
|
|
|
1228
1228
|
|
|
1229
1229
|
if (!quiet) {
|
|
1230
1230
|
console.log('\nServices:');
|
|
1231
|
-
let dashboardUrl = null;
|
|
1232
1231
|
for (const svc of results) {
|
|
1233
1232
|
if (svc.status === 'started' || svc.status === 'reused') {
|
|
1234
1233
|
const status = svc.status === 'reused' ? ' (running)' : '';
|
|
1235
1234
|
console.log(` ${svc.name}${status}${svc.url ? ` ${svc.url}` : ''}`);
|
|
1236
|
-
if (svc.name === 'Dashboard' && svc.url) dashboardUrl = svc.url;
|
|
1237
1235
|
} else if (svc.status === 'failed') {
|
|
1238
1236
|
console.log(` ${svc.name} — failed${svc.note ? ` (${svc.note})` : ''}`);
|
|
1239
1237
|
}
|
|
@@ -1241,7 +1239,7 @@ async function main() {
|
|
|
1241
1239
|
|
|
1242
1240
|
const telemetrySvc = results.find(r => r.name === 'Telemetry' && r.url?.includes('localhost'));
|
|
1243
1241
|
if (telemetrySvc) console.log(`\nTelemetry: ${telemetrySvc.url}`);
|
|
1244
|
-
|
|
1242
|
+
console.log('\nStop services with `construct stop`');
|
|
1245
1243
|
}
|
|
1246
1244
|
} catch (error) {
|
|
1247
1245
|
console.error(`Services could not be started: ${error.message}`);
|
package/lib/intake/classify.mjs
CHANGED
|
@@ -34,6 +34,11 @@
|
|
|
34
34
|
*/
|
|
35
35
|
|
|
36
36
|
import path from 'node:path';
|
|
37
|
+
import { createRequire } from 'node:module';
|
|
38
|
+
import { fileURLToPath } from 'node:url';
|
|
39
|
+
|
|
40
|
+
const require = createRequire(import.meta.url);
|
|
41
|
+
const REPO_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..');
|
|
37
42
|
|
|
38
43
|
// Backward-compatible exports. RND defaults preserve the symbol surface
|
|
39
44
|
// referenced by intake-config, prepare, and existing tests.
|
|
@@ -72,6 +77,22 @@ const TABLES = {
|
|
|
72
77
|
research: researchTable,
|
|
73
78
|
};
|
|
74
79
|
|
|
80
|
+
const dynamicTableCache = new Map();
|
|
81
|
+
|
|
82
|
+
function loadClassificationTable(tableRef) {
|
|
83
|
+
if (!tableRef || typeof tableRef !== 'string') return null;
|
|
84
|
+
if (dynamicTableCache.has(tableRef)) return dynamicTableCache.get(tableRef);
|
|
85
|
+
const abs = path.isAbsolute(tableRef) ? tableRef : path.join(REPO_ROOT, tableRef);
|
|
86
|
+
try {
|
|
87
|
+
const mod = require(abs);
|
|
88
|
+
const table = mod.default ?? mod;
|
|
89
|
+
dynamicTableCache.set(tableRef, table);
|
|
90
|
+
return table;
|
|
91
|
+
} catch {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
75
96
|
// Filename patterns are explicit author-intent signals. The boost remains
|
|
76
97
|
// at +0.4 so a clear keyword majority can still override (a postmortem
|
|
77
98
|
// genuinely about a CVE escalation routes to security, not incident).
|
|
@@ -167,6 +188,11 @@ function matcherFor(entry) {
|
|
|
167
188
|
function resolveTable(profile) {
|
|
168
189
|
if (!profile) return rndTable;
|
|
169
190
|
const id = typeof profile === 'string' ? profile : profile.id;
|
|
191
|
+
const tableRef = typeof profile === 'object' ? profile?.intake?.classificationTable : null;
|
|
192
|
+
if (typeof tableRef === 'string') {
|
|
193
|
+
const fromPath = loadClassificationTable(tableRef);
|
|
194
|
+
if (fromPath) return fromPath;
|
|
195
|
+
}
|
|
170
196
|
return TABLES[id] || rndTable;
|
|
171
197
|
}
|
|
172
198
|
|
package/lib/intake/daemon.mjs
CHANGED
|
@@ -19,14 +19,13 @@ import { join, basename } from 'node:path';
|
|
|
19
19
|
|
|
20
20
|
import { createDaemon, classifyPacket } from '../daemons/contract.mjs';
|
|
21
21
|
import { memoryCapMbFor } from '../resources/process-budget.mjs';
|
|
22
|
-
import { stateDir } from '../config/xdg.mjs';
|
|
23
22
|
|
|
24
23
|
const KILLSWITCH_ENV = 'CONSTRUCT_INTAKE_DAEMON';
|
|
25
24
|
|
|
26
25
|
function inboxDir(cwd) { return join(cwd, 'inbox'); }
|
|
27
26
|
function pendingDir(cwd) { return join(cwd, '.cx', 'intake', 'pending'); }
|
|
28
27
|
function deadLetterDir(cwd) { return join(cwd, '.cx', 'intake', 'dead-letter'); }
|
|
29
|
-
function heartbeatPath() { return join(
|
|
28
|
+
function heartbeatPath(cwd) { return join(cwd, '.cx', 'runtime', 'intake-daemon.heartbeat'); }
|
|
30
29
|
|
|
31
30
|
function ensureDir(dir) {
|
|
32
31
|
try { mkdirSync(dir, { recursive: true }); } catch { /* ignore */ }
|
|
@@ -128,7 +127,7 @@ export function buildIntakeDaemon({ cwd = process.cwd(), intervalMs = 60_000, cl
|
|
|
128
127
|
name: 'intake',
|
|
129
128
|
intervalMs,
|
|
130
129
|
killswitchEnv: KILLSWITCH_ENV,
|
|
131
|
-
heartbeatPath: heartbeatPath(),
|
|
130
|
+
heartbeatPath: heartbeatPath(cwd),
|
|
132
131
|
maxRuntimeMs: 24 * 60 * 60 * 1000,
|
|
133
132
|
maxIdleTicks: 6,
|
|
134
133
|
memoryCapMb: memoryCapMbFor('intake', cwd),
|
package/lib/intake/prepare.mjs
CHANGED
|
@@ -34,7 +34,8 @@ import { suggestDocsLaneForFile } from '../docs-routing.mjs';
|
|
|
34
34
|
import { createIntakeQueue } from './queue.mjs';
|
|
35
35
|
import { classifyRdIntake, suggestTags } from './classify.mjs';
|
|
36
36
|
import { detectCustomerMentions, linkSignalToCustomer, updateCustomerProfile } from '../embed/customer-profiles.mjs';
|
|
37
|
-
import {
|
|
37
|
+
import { resolveActiveScope } from '../scopes/loader.mjs';
|
|
38
|
+
import { resolveResearchProfile } from '../scopes/research-profile.mjs';
|
|
38
39
|
import { emitBestEffort as emitRoleEvent } from '../roles/event-bus.mjs';
|
|
39
40
|
import { gatherAttribution, stampAttribution } from './attribution.mjs';
|
|
40
41
|
import { MANIFEST_REL_PATH } from './manifest.mjs';
|
|
@@ -91,13 +92,19 @@ export async function prepareIntakeForIngestedFile({
|
|
|
91
92
|
// Resolve the active profile so non-RND projects route to their own table.
|
|
92
93
|
// Falls back to rnd for any project without explicit configuration, which
|
|
93
94
|
// preserves prior behavior for every existing user.
|
|
94
|
-
const activeProfile =
|
|
95
|
-
const
|
|
95
|
+
const activeProfile = resolveActiveScope(rootDir);
|
|
96
|
+
const classified = classifyFn({
|
|
96
97
|
sourcePath: ingestedFile.sourcePath,
|
|
97
98
|
extractedText: extracted,
|
|
98
99
|
related,
|
|
99
100
|
profile: activeProfile?.id,
|
|
100
101
|
});
|
|
102
|
+
const researchProfile = resolveResearchProfile({
|
|
103
|
+
intakeType: classified?.intakeType,
|
|
104
|
+
artifactType: lane,
|
|
105
|
+
scope: activeProfile,
|
|
106
|
+
});
|
|
107
|
+
const triage = researchProfile ? { ...classified, researchProfile } : classified;
|
|
101
108
|
|
|
102
109
|
// Detect customer mentions and update profiles
|
|
103
110
|
const customerMentions = detectCustomerMentions(extracted.slice(0, 2000));
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
import { createIntakeQueue } from './queue.mjs';
|
|
14
14
|
import { formatTriageLine } from './classify.mjs';
|
|
15
15
|
import { isBrokered } from '../mcp/broker.mjs';
|
|
16
|
-
import { getRebrand } from '../
|
|
16
|
+
import { getRebrand } from '../scopes/rebrand.mjs';
|
|
17
17
|
import { homedir as osHomedir } from 'node:os';
|
|
18
18
|
import { readLastTick } from '../oracle/index.mjs';
|
|
19
19
|
import { listPending } from '../oracle/actions.mjs';
|
|
@@ -11,8 +11,8 @@ export const STAGES = ['brief', 'research', 'draft', 'review', 'publish', 'measu
|
|
|
11
11
|
export const UNKNOWN_TRIAGE = {
|
|
12
12
|
intakeType: 'unknown',
|
|
13
13
|
rdStage: 'unknown',
|
|
14
|
-
primaryOwner: '
|
|
15
|
-
recommendedChain: ['
|
|
14
|
+
primaryOwner: 'operations',
|
|
15
|
+
recommendedChain: ['operations'],
|
|
16
16
|
recommendedAction: 'summarize',
|
|
17
17
|
risk: 'low',
|
|
18
18
|
requiresApproval: false,
|
|
@@ -33,8 +33,8 @@ export const CLASSIFICATION_TABLE = [
|
|
|
33
33
|
intakeType: 'brief',
|
|
34
34
|
keywords: ['brief', 'campaign', 'launch plan', 'go-to-market', 'gtm', 'positioning', 'narrative', 'audience'],
|
|
35
35
|
rdStage: 'brief',
|
|
36
|
-
primaryOwner: 'product-
|
|
37
|
-
recommendedChain: ['product-
|
|
36
|
+
primaryOwner: 'product-manager',
|
|
37
|
+
recommendedChain: ['product-manager', 'researcher', 'docs-keeper'],
|
|
38
38
|
recommendedAction: 'draft-prd',
|
|
39
39
|
risk: 'medium',
|
|
40
40
|
requiresApproval: false,
|
|
@@ -43,8 +43,8 @@ export const CLASSIFICATION_TABLE = [
|
|
|
43
43
|
intakeType: 'content-request',
|
|
44
44
|
keywords: ['blog', 'article', 'landing page', 'social post', 'newsletter', 'email copy', 'video script', 'headline', 'post', 'content'],
|
|
45
45
|
rdStage: 'draft',
|
|
46
|
-
primaryOwner: '
|
|
47
|
-
recommendedChain: ['
|
|
46
|
+
primaryOwner: 'docs-keeper',
|
|
47
|
+
recommendedChain: ['docs-keeper', 'reviewer'],
|
|
48
48
|
recommendedAction: 'draft-rfc',
|
|
49
49
|
risk: 'low',
|
|
50
50
|
requiresApproval: false,
|
|
@@ -74,7 +74,7 @@ export const CLASSIFICATION_TABLE = [
|
|
|
74
74
|
keywords: ['report', 'dashboard', 'attribution', 'ctr', 'cpa', 'roas', 'conversion', 'funnel', 'engagement'],
|
|
75
75
|
rdStage: 'measure',
|
|
76
76
|
primaryOwner: 'data-analyst',
|
|
77
|
-
recommendedChain: ['data-analyst', 'product-
|
|
77
|
+
recommendedChain: ['data-analyst', 'product-manager'],
|
|
78
78
|
recommendedAction: 'evaluate',
|
|
79
79
|
risk: 'low',
|
|
80
80
|
requiresApproval: false,
|
|
@@ -83,8 +83,8 @@ export const CLASSIFICATION_TABLE = [
|
|
|
83
83
|
intakeType: 'ops',
|
|
84
84
|
keywords: ['process', 'workflow', 'template', 'sla', 'calendar', 'planning', 'editorial calendar'],
|
|
85
85
|
rdStage: 'review',
|
|
86
|
-
primaryOwner: '
|
|
87
|
-
recommendedChain: ['
|
|
86
|
+
primaryOwner: 'operations',
|
|
87
|
+
recommendedChain: ['operations', 'product-manager'],
|
|
88
88
|
recommendedAction: 'create-runbook',
|
|
89
89
|
risk: 'low',
|
|
90
90
|
requiresApproval: false,
|
|
@@ -12,8 +12,8 @@ export const STAGES = ['request', 'triage', 'resolve', 'document', 'improve'];
|
|
|
12
12
|
export const UNKNOWN_TRIAGE = {
|
|
13
13
|
intakeType: 'unknown',
|
|
14
14
|
rdStage: 'unknown',
|
|
15
|
-
primaryOwner: '
|
|
16
|
-
recommendedChain: ['
|
|
15
|
+
primaryOwner: 'operations',
|
|
16
|
+
recommendedChain: ['operations'],
|
|
17
17
|
recommendedAction: 'summarize',
|
|
18
18
|
risk: 'low',
|
|
19
19
|
requiresApproval: false,
|
|
@@ -74,8 +74,8 @@ export const CLASSIFICATION_TABLE = [
|
|
|
74
74
|
intakeType: 'request',
|
|
75
75
|
keywords: ['request', 'access', 'feature request', 'integration', 'new tool', 'change request', 'how do i', 'can someone'],
|
|
76
76
|
rdStage: 'triage',
|
|
77
|
-
primaryOwner: '
|
|
78
|
-
recommendedChain: ['
|
|
77
|
+
primaryOwner: 'operations',
|
|
78
|
+
recommendedChain: ['operations', 'engineer'],
|
|
79
79
|
recommendedAction: 'clarify',
|
|
80
80
|
risk: 'low',
|
|
81
81
|
requiresApproval: false,
|
|
@@ -74,8 +74,8 @@ export const CLASSIFICATION_TABLE = [
|
|
|
74
74
|
intakeType: 'ops',
|
|
75
75
|
keywords: ['process', 'methodology', 'template', 'protocol', 'consent form', 'data handling'],
|
|
76
76
|
rdStage: 'gather',
|
|
77
|
-
primaryOwner: '
|
|
78
|
-
recommendedChain: ['
|
|
77
|
+
primaryOwner: 'operations',
|
|
78
|
+
recommendedChain: ['operations', 'researcher'],
|
|
79
79
|
recommendedAction: 'create-runbook',
|
|
80
80
|
risk: 'low',
|
|
81
81
|
requiresApproval: false,
|
|
@@ -19,6 +19,7 @@ import { join } from 'node:path';
|
|
|
19
19
|
import { homedir } from 'node:os';
|
|
20
20
|
import { spawnSync } from 'node:child_process';
|
|
21
21
|
import { configDir } from '../config/xdg.mjs';
|
|
22
|
+
import { resolveOpRef } from '../providers/secret-resolver.mjs';
|
|
22
23
|
|
|
23
24
|
// ── Multi-method auth helpers ────────────────────────────────────────────
|
|
24
25
|
|
|
@@ -628,8 +629,7 @@ function resolveCredentialSync(varName, homeDir) {
|
|
|
628
629
|
const opMatch = content.match(opRe);
|
|
629
630
|
if (opMatch) {
|
|
630
631
|
try {
|
|
631
|
-
|
|
632
|
-
if (result.status === 0) return result.stdout.trim();
|
|
632
|
+
return resolveOpRef(opMatch[1]);
|
|
633
633
|
} catch { /* op read failed */ }
|
|
634
634
|
}
|
|
635
635
|
}
|
|
@@ -730,16 +730,15 @@ function resolveCredential(varName, homeDir) {
|
|
|
730
730
|
const opRe = new RegExp(`export\\s+${varName}=["']?\\$\\(op read '([^']+)'\\)["']?`, 'm');
|
|
731
731
|
const opMatch = content.match(opRe);
|
|
732
732
|
if (opMatch) {
|
|
733
|
+
// op read failures often mean the rc-file field name doesn't match the
|
|
734
|
+
// actual 1Password item field; surface them under the debug flag.
|
|
733
735
|
try {
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
const errMsg = (result.stderr || '').trim().slice(0, 200);
|
|
739
|
-
if (errMsg && process.env.CONSTRUCT_DEBUG_CREDENTIALS === '1') {
|
|
740
|
-
process.stderr.write(`[credentials] op read failed for ${varName}: ${errMsg}\n`);
|
|
736
|
+
return resolveOpRef(opMatch[1]);
|
|
737
|
+
} catch (err) {
|
|
738
|
+
if (process.env.CONSTRUCT_DEBUG_CREDENTIALS === '1') {
|
|
739
|
+
process.stderr.write(`[credentials] op read failed for ${varName}: ${String(err.message).slice(0, 200)}\n`);
|
|
741
740
|
}
|
|
742
|
-
}
|
|
741
|
+
}
|
|
743
742
|
}
|
|
744
743
|
|
|
745
744
|
// If the value uses command substitution ($(...)), try evaluating via
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
19
19
|
import { dirname, join } from 'node:path';
|
|
20
20
|
import { syncFileStateToSql } from '../storage/sync.mjs';
|
|
21
|
-
import {
|
|
21
|
+
import { resolveActiveScope } from '../scopes/loader.mjs';
|
|
22
22
|
import { ensureCxDir } from '../project-init-shared.mjs';
|
|
23
23
|
|
|
24
24
|
const ROOT = '.cx/knowledge/external/research';
|
|
@@ -64,7 +64,7 @@ export async function addResearchFinding({
|
|
|
64
64
|
throw new Error('addResearchFinding: confidence=confirmed requires at least one source');
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
const profile =
|
|
67
|
+
const profile = resolveActiveScope(cwd);
|
|
68
68
|
const now = new Date();
|
|
69
69
|
const expiresAt = new Date(now.getTime() + ttlDays * 24 * 60 * 60 * 1000).toISOString();
|
|
70
70
|
|