@geraldmaron/construct 1.0.0 → 1.0.2
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/.env.example +9 -6
- package/LICENSE +201 -21
- package/README.md +132 -257
- package/agents/contracts.json +387 -0
- package/agents/prompts/cx-accessibility.md +8 -0
- package/agents/prompts/cx-ai-engineer.md +92 -0
- package/agents/prompts/cx-architect.md +10 -2
- package/agents/prompts/cx-business-strategist.md +13 -0
- package/agents/prompts/cx-data-analyst.md +80 -0
- package/agents/prompts/cx-data-engineer.md +4 -0
- package/agents/prompts/cx-debugger.md +8 -0
- package/agents/prompts/cx-designer.md +19 -0
- package/agents/prompts/cx-devil-advocate.md +4 -0
- package/agents/prompts/cx-docs-keeper.md +128 -0
- package/agents/prompts/cx-engineer.md +13 -0
- package/agents/prompts/cx-evaluator.md +4 -0
- package/agents/prompts/cx-explorer.md +12 -0
- package/agents/prompts/cx-legal-compliance.md +13 -0
- package/agents/prompts/cx-operations.md +13 -0
- package/agents/prompts/cx-orchestrator.md +107 -4
- package/agents/prompts/cx-platform-engineer.md +75 -0
- package/agents/prompts/cx-product-manager.md +8 -0
- package/agents/prompts/cx-qa.md +100 -0
- package/agents/prompts/cx-rd-lead.md +13 -0
- package/agents/prompts/cx-release-manager.md +8 -0
- package/agents/prompts/cx-researcher.md +21 -1
- package/agents/prompts/cx-reviewer.md +8 -0
- package/agents/prompts/cx-security.md +104 -0
- package/agents/prompts/cx-sre.md +104 -0
- package/agents/prompts/cx-test-automation.md +4 -0
- package/agents/prompts/cx-trace-reviewer.md +7 -3
- package/agents/prompts/cx-ux-researcher.md +4 -0
- package/agents/registry.json +365 -90
- package/agents/role-manifests.json +217 -0
- package/bin/construct +3345 -141
- package/bin/construct-postinstall.mjs +87 -0
- package/commands/build/feature.md +6 -6
- package/commands/plan/feature.md +6 -5
- package/commands/plan/requirements.md +1 -1
- package/commands/ship/status.md +1 -1
- package/commands/work/drive.md +3 -3
- package/commands/work/optimize-prompts.md +3 -3
- package/db/{migrations → schema}/001_init.sql +2 -0
- package/db/schema/002_pgvector.sql +182 -0
- package/db/schema/003_intake.sql +47 -0
- package/examples/README.md +85 -0
- package/examples/internal/roles/architect/bad/clever-plan-without-contracts.md +30 -0
- package/examples/internal/roles/architect/golden/explicit-tradeoff-before-plan.md +23 -0
- package/examples/internal/roles/engineer/bad/speculative-abstraction.md +30 -0
- package/examples/internal/roles/engineer/golden/read-before-write.md +28 -0
- package/examples/internal/roles/orchestrator/bad/everything-becomes-multi-agent.md +29 -0
- package/examples/internal/roles/orchestrator/golden/minimal-dispatch.md +22 -0
- package/examples/internal/roles/qa/bad/coverage-theater.md +30 -0
- package/examples/internal/roles/qa/golden/regression-gate.md +23 -0
- package/examples/internal/roles/reviewer/bad/lgtm-without-verification.md +29 -0
- package/examples/internal/roles/reviewer/golden/find-structural-risk-first.md +28 -0
- package/examples/personas/construct/adversarial/ignore-instruction-to-skip-approval.md +22 -0
- package/examples/personas/construct/bad/commit-without-approval.md +30 -0
- package/examples/personas/construct/boundary/blocked-needs-main-input.md +29 -0
- package/examples/personas/construct/golden/branch-approval-before-mutation.md +36 -0
- package/examples/personas/construct/golden/focused-direct-answer.md +28 -0
- package/examples/provider-plugin/README.md +34 -0
- package/examples/provider-plugin/index.mjs +74 -0
- package/examples/provider-plugin/package.json +15 -0
- package/examples/seed-observations/README.md +38 -0
- package/examples/seed-observations/anti-patterns.md +44 -0
- package/examples/seed-observations/decisions.md +36 -0
- package/examples/seed-observations/patterns.md +42 -0
- package/lib/agent-contracts-enforce.mjs +158 -0
- package/lib/agent-contracts.mjs +231 -0
- package/lib/agents/postconditions.mjs +126 -0
- package/lib/agents/schema.mjs +124 -0
- package/lib/artifact-capture.mjs +183 -0
- package/lib/audit-trail.mjs +149 -0
- package/lib/auto-docs.mjs +245 -65
- package/lib/beads/auto-close.mjs +126 -0
- package/lib/beads/drift.mjs +171 -0
- package/lib/beads-automation.mjs +542 -0
- package/lib/beads-client.mjs +518 -0
- package/lib/beads-lock.mjs +377 -0
- package/lib/beads-optimistic.mjs +365 -0
- package/lib/bootstrap/built-ins.mjs +136 -0
- package/lib/bootstrap/lazy-install.mjs +161 -0
- package/lib/bootstrap/resources.mjs +120 -0
- package/lib/bootstrap.mjs +105 -0
- package/lib/cache-governor.js +213 -0
- package/lib/cache-strategy-anthropic.js +62 -0
- package/lib/cache-strategy-google.js +79 -0
- package/lib/cache-strategy-none.js +30 -0
- package/lib/cache-strategy-openai.js +48 -0
- package/lib/cache-strategy.js +91 -0
- package/lib/claude-allow.mjs +149 -0
- package/lib/cli-commands.mjs +413 -258
- package/lib/codex-config.mjs +3 -1
- package/lib/comment-lint.mjs +55 -6
- package/lib/completions.mjs +21 -6
- package/lib/config/alias.mjs +56 -0
- package/lib/config/project-config.mjs +335 -0
- package/lib/config/schema.mjs +159 -0
- package/lib/context-router.mjs +308 -0
- package/lib/cost-ledger.mjs +177 -0
- package/lib/cost.mjs +171 -10
- package/lib/dashboard-static.mjs +158 -0
- package/lib/deployment-mode.mjs +86 -0
- package/lib/deprecate.mjs +49 -0
- package/lib/dispatch-batch.js +183 -0
- package/lib/distill.mjs +21 -8
- package/lib/doc-stamp.mjs +164 -0
- package/lib/doc-verify.mjs +119 -0
- package/lib/docs-routing.mjs +89 -0
- package/lib/docs-verify.mjs +417 -0
- package/lib/doctor/audit.mjs +71 -0
- package/lib/doctor/cli.mjs +99 -0
- package/lib/doctor/escalate.mjs +29 -0
- package/lib/doctor/index.mjs +140 -0
- package/lib/doctor/report.mjs +170 -0
- package/lib/doctor/watchers/bd-watch.mjs +117 -0
- package/lib/doctor/watchers/cost.mjs +130 -0
- package/lib/doctor/watchers/disk.mjs +122 -0
- package/lib/doctor/watchers/handoffs.mjs +33 -0
- package/lib/doctor/watchers/process-pressure.mjs +60 -0
- package/lib/doctor/watchers/service-health.mjs +188 -0
- package/lib/document-extract.mjs +288 -0
- package/lib/document-ingest.mjs +230 -0
- package/lib/drop.mjs +282 -0
- package/lib/embed/approval-queue.mjs +176 -0
- package/lib/embed/artifact.mjs +349 -0
- package/lib/embed/authority-guard.mjs +155 -0
- package/lib/embed/cli.mjs +408 -0
- package/lib/embed/config.mjs +355 -0
- package/lib/embed/conflict-detection.mjs +264 -0
- package/lib/embed/customer-profiles.mjs +480 -0
- package/lib/embed/daemon.mjs +1309 -0
- package/lib/embed/demand-fetch.mjs +449 -0
- package/lib/embed/docs-lifecycle.mjs +349 -0
- package/lib/embed/inbox-live-watcher.mjs +119 -0
- package/lib/embed/inbox.mjs +343 -0
- package/lib/embed/intake-metrics.mjs +190 -0
- package/lib/embed/jobs/vector-sync.mjs +198 -0
- package/lib/embed/notifications.mjs +75 -0
- package/lib/embed/output.mjs +79 -0
- package/lib/embed/providers/github.mjs +295 -0
- package/lib/embed/providers/jira.mjs +192 -0
- package/lib/embed/providers/linear.mjs +186 -0
- package/lib/embed/providers/registry.mjs +115 -0
- package/lib/embed/providers/slack.mjs +203 -0
- package/lib/embed/recommendation-store.mjs +378 -0
- package/lib/embed/roadmap.mjs +374 -0
- package/lib/embed/role-framing.mjs +110 -0
- package/lib/embed/scheduler.mjs +99 -0
- package/lib/embed/semantic.mjs +325 -0
- package/lib/embed/snapshot.mjs +191 -0
- package/lib/embed/supervision.mjs +235 -0
- package/lib/embed/target-resolver.mjs +186 -0
- package/lib/embed/worker.mjs +62 -0
- package/lib/embed/workspaces.mjs +297 -0
- package/lib/engine/chunker-headings.mjs +110 -0
- package/lib/engine/compressor-heuristic.mjs +100 -0
- package/lib/engine/consolidate.mjs +287 -0
- package/lib/engine/contracts.mjs +126 -0
- package/lib/engine/defaults.mjs +129 -0
- package/lib/engine/eval-retrieval.mjs +148 -0
- package/lib/engine/fuser-rrf.mjs +62 -0
- package/lib/engine/index.mjs +37 -0
- package/lib/engine/registry.mjs +146 -0
- package/lib/engine/reranker-mmr.mjs +90 -0
- package/lib/engine/tokens.mjs +77 -0
- package/lib/entity-store.mjs +280 -0
- package/lib/env-config.mjs +69 -4
- package/lib/evals/retrieval-bench.mjs +159 -0
- package/lib/evaluator-optimizer.mjs +317 -0
- package/lib/features.mjs +159 -29
- package/lib/gates-audit.mjs +236 -0
- package/lib/git-hooks/prepare-commit-msg +58 -0
- package/lib/handoffs/cleanup.mjs +159 -0
- package/lib/handoffs/contract.mjs +162 -0
- package/lib/handoffs/inventory.mjs +120 -0
- package/lib/headhunt.mjs +28 -47
- package/lib/health-check.mjs +399 -0
- package/lib/hook-health.mjs +442 -0
- package/lib/hooks/_lib/log.mjs +82 -0
- package/lib/hooks/adaptive-lint.mjs +26 -2
- package/lib/hooks/agent-tracker.mjs +171 -14
- package/lib/hooks/audit-reads.mjs +109 -0
- package/lib/hooks/audit-trail.mjs +153 -0
- package/lib/hooks/bash-output-logger.mjs +71 -0
- package/lib/hooks/block-no-verify.mjs +41 -0
- package/lib/hooks/ci-status-check.mjs +82 -0
- package/lib/hooks/comment-lint.mjs +29 -7
- package/lib/hooks/config-protection.mjs +39 -18
- package/lib/hooks/context-watch.mjs +137 -0
- package/lib/hooks/context-window-recovery.mjs +4 -20
- package/lib/hooks/dep-audit.mjs +16 -0
- package/lib/hooks/doc-coupling-check.mjs +80 -0
- package/lib/hooks/edit-accumulator.mjs +3 -0
- package/lib/hooks/edit-error-recovery.mjs +3 -0
- package/lib/hooks/edit-guard.mjs +45 -4
- package/lib/hooks/env-check.mjs +3 -0
- package/lib/hooks/guard-bash.mjs +58 -1
- package/lib/hooks/mcp-audit.mjs +18 -20
- package/lib/hooks/mcp-health-check.mjs +36 -0
- package/lib/hooks/model-fallback.mjs +42 -56
- package/lib/hooks/policy-engine.mjs +209 -0
- package/lib/hooks/post-merge-docs-check.mjs +63 -0
- package/lib/hooks/pre-compact.mjs +4 -24
- package/lib/hooks/pre-push-gate.mjs +200 -37
- package/lib/hooks/proactive-activation.mjs +284 -0
- package/lib/hooks/read-tracker.mjs +27 -4
- package/lib/hooks/readme-age-check.mjs +77 -0
- package/lib/hooks/registry-sync.mjs +12 -5
- package/lib/hooks/scan-secrets.mjs +50 -7
- package/lib/hooks/session-optimize.mjs +311 -0
- package/lib/hooks/session-start.mjs +287 -28
- package/lib/hooks/stop-notify.mjs +236 -96
- package/lib/hooks/stop-typecheck.mjs +13 -1
- package/lib/hooks/test-watch.mjs +68 -0
- package/lib/host-capabilities.mjs +31 -10
- package/lib/init-docs.mjs +731 -291
- package/lib/init-unified.mjs +1000 -0
- package/lib/init-update.mjs +168 -0
- package/lib/init.mjs +107 -0
- package/lib/install/first-invocation.mjs +119 -0
- package/lib/install/stage-project.mjs +69 -0
- package/lib/intake/classify.mjs +278 -0
- package/lib/intake/feedback.mjs +273 -0
- package/lib/intake/filesystem-queue.mjs +158 -0
- package/lib/intake/intake-config.mjs +132 -0
- package/lib/intake/postgres-queue.mjs +198 -0
- package/lib/intake/prepare.mjs +139 -0
- package/lib/intake/queue.mjs +83 -0
- package/lib/intake/session-prelude.mjs +50 -0
- package/lib/integrations/intake-integrations.mjs +740 -0
- package/lib/intent-classifier.mjs +253 -0
- package/lib/knowledge/layout.mjs +72 -0
- package/lib/knowledge/rag.mjs +331 -0
- package/lib/knowledge/search.mjs +315 -0
- package/lib/knowledge/trends.mjs +261 -0
- package/lib/logger.mjs +85 -0
- package/lib/mcp/broker.mjs +124 -0
- package/lib/mcp/server.mjs +554 -854
- package/lib/mcp/tools/document.mjs +132 -0
- package/lib/mcp/tools/memory.mjs +209 -0
- package/lib/mcp/tools/project.mjs +349 -0
- package/lib/mcp/tools/skills.mjs +409 -0
- package/lib/mcp/tools/storage.mjs +60 -0
- package/lib/mcp/tools/telemetry.mjs +315 -0
- package/lib/mcp/tools/workflow.mjs +112 -0
- package/lib/mcp-catalog.json +54 -3
- package/lib/mcp-manager.mjs +96 -48
- package/lib/mcp-platform-config.mjs +22 -22
- package/lib/memory-stats.mjs +121 -0
- package/lib/mode-commands.mjs +124 -0
- package/lib/model-free-selector.mjs +184 -0
- package/lib/model-pricing.mjs +152 -0
- package/lib/model-registry.mjs +226 -0
- package/lib/model-router.mjs +362 -386
- package/lib/observation-store.mjs +391 -0
- package/lib/ollama-manager.mjs +428 -0
- package/lib/opencode-config.mjs +13 -3
- package/lib/opencode-runtime-plugin.mjs +70 -38
- package/lib/opencode-telemetry.mjs +64 -6
- package/lib/orchestration-policy.mjs +509 -6
- package/lib/overrides/resolver.mjs +207 -0
- package/lib/parity.mjs +147 -0
- package/lib/paths.mjs +33 -0
- package/lib/performance/generate.mjs +212 -0
- package/lib/plugin-registry.mjs +268 -0
- package/lib/policy/engine.mjs +130 -0
- package/lib/policy/unified-gates.mjs +96 -0
- package/lib/project-detection.mjs +129 -0
- package/lib/project-init-shared.mjs +272 -0
- package/lib/project-profile.mjs +447 -0
- package/lib/prompt-composer.js +434 -0
- package/lib/prompt-metadata.mjs +1 -1
- package/lib/provider-capabilities-anthropic.js +44 -0
- package/lib/provider-capabilities-deepseek.js +37 -0
- package/lib/provider-capabilities-generic.js +26 -0
- package/lib/provider-capabilities-google.js +47 -0
- package/lib/provider-capabilities-openai.js +45 -0
- package/lib/provider-capabilities.js +142 -0
- package/lib/providers/atlassian-confluence/index.mjs +103 -0
- package/lib/providers/atlassian-jira/index.mjs +100 -0
- package/lib/providers/auth-manager.mjs +126 -0
- package/lib/providers/circuit-breaker.mjs +124 -0
- package/lib/providers/contract.mjs +93 -0
- package/lib/providers/github/index.mjs +126 -0
- package/lib/providers/registry.mjs +184 -0
- package/lib/providers/salesforce/index.mjs +100 -0
- package/lib/providers/slack/index.mjs +80 -0
- package/lib/reflect.mjs +137 -0
- package/lib/research-lint.mjs +164 -0
- package/lib/resources/budget.mjs +259 -0
- package/lib/role-preload.mjs +21 -6
- package/lib/roles/approval-surface.mjs +54 -0
- package/lib/roles/cli.mjs +118 -0
- package/lib/roles/event-bus.mjs +79 -0
- package/lib/roles/fence.mjs +84 -0
- package/lib/roles/gateway.mjs +260 -0
- package/lib/roles/hook-emit.mjs +37 -0
- package/lib/roles/manifest.mjs +48 -0
- package/lib/roles/router.mjs +27 -0
- package/lib/runtime-pressure.mjs +360 -0
- package/lib/schema-artifact.mjs +134 -0
- package/lib/schema-infer.mjs +551 -0
- package/lib/server/auth.mjs +168 -0
- package/lib/server/chat.mjs +336 -0
- package/lib/server/cors.mjs +77 -0
- package/lib/server/csrf.mjs +91 -0
- package/lib/server/index.mjs +1927 -78
- package/lib/server/insights.mjs +765 -0
- package/lib/server/rate-limit.mjs +91 -0
- package/lib/server/static/assets/index-ab25c707.js +70 -0
- package/lib/server/static/assets/index-f0c80a2b.css +1 -0
- package/lib/server/static/index.html +12 -817
- package/lib/server/telemetry-login.mjs +108 -0
- package/lib/server/webhook.mjs +510 -0
- package/lib/service-manager.mjs +522 -58
- package/lib/services/pattern-promotion-service.mjs +167 -0
- package/lib/services/telemetry-backend.mjs +178 -0
- package/lib/session-store.mjs +374 -0
- package/lib/setup-prompts.mjs +96 -0
- package/lib/setup.mjs +523 -36
- package/lib/skills-apply.mjs +280 -0
- package/lib/skills-scope.mjs +118 -0
- package/lib/status.mjs +261 -70
- package/lib/storage/admin.mjs +355 -0
- package/lib/storage/backend.mjs +2 -1
- package/lib/storage/backup.mjs +347 -0
- package/lib/storage/embeddings-engine.mjs +133 -0
- package/lib/storage/embeddings-legacy.mjs +85 -0
- package/lib/storage/embeddings-local.mjs +108 -0
- package/lib/storage/embeddings-ollama.mjs +78 -0
- package/lib/storage/embeddings-openai.mjs +85 -0
- package/lib/storage/embeddings.mjs +92 -33
- package/lib/storage/file-lock.mjs +130 -0
- package/lib/storage/fusion.mjs +95 -0
- package/lib/storage/hybrid-query.mjs +34 -27
- package/lib/storage/migrations.mjs +187 -0
- package/lib/storage/postgres-backup.mjs +124 -0
- package/lib/storage/sql-store.mjs +5 -15
- package/lib/storage/state-source.mjs +12 -13
- package/lib/storage/store-version.mjs +115 -0
- package/lib/storage/sync.mjs +144 -35
- package/lib/storage/unified-storage.mjs +550 -0
- package/lib/storage/vector-client.mjs +286 -0
- package/lib/storage/vector-store.mjs +71 -30
- package/lib/task-graph/generate.mjs +135 -0
- package/lib/task-graph/schema.mjs +81 -0
- package/lib/task-graph/store.mjs +71 -0
- package/lib/telemetry/backends/local.mjs +62 -0
- package/lib/telemetry/backends/{langfuse.mjs → remote.mjs} +27 -14
- package/lib/telemetry/backfill.mjs +180 -0
- package/lib/telemetry/eval-datasets.mjs +203 -0
- package/lib/telemetry/{langfuse-ingest.mjs → ingest.mjs} +26 -20
- package/lib/telemetry/intent-verifications.mjs +86 -0
- package/lib/telemetry/llm-judge.mjs +350 -0
- package/lib/telemetry/model-pricing-catalog.mjs +557 -0
- package/lib/telemetry/setup.mjs +151 -0
- package/lib/telemetry/skill-calls.mjs +78 -0
- package/lib/telemetry/team-rollup.mjs +4 -4
- package/lib/token-engine.js +117 -0
- package/lib/token-estimator-anthropic.js +15 -0
- package/lib/token-estimator-deepseek.js +13 -0
- package/lib/token-estimator-default.js +13 -0
- package/lib/token-estimator-google.js +13 -0
- package/lib/token-estimator-openai.js +13 -0
- package/lib/toolkit-env.mjs +1 -1
- package/lib/tty-prompts.mjs +211 -0
- package/lib/uninstall/uninstall.mjs +423 -0
- package/lib/update.mjs +115 -0
- package/lib/upgrade.mjs +141 -0
- package/lib/validator.mjs +51 -2
- package/lib/validators/skills.mjs +142 -0
- package/lib/wireframe.mjs +422 -0
- package/lib/worker/entrypoint.mjs +241 -0
- package/lib/worker/evidence.mjs +107 -0
- package/lib/worker/run.mjs +154 -0
- package/lib/worker/trace.mjs +182 -0
- package/lib/workflow-state.mjs +14 -18
- package/package.json +21 -8
- package/personas/construct.md +53 -51
- package/platforms/claude/CLAUDE.md +1 -1
- package/platforms/claude/settings.template.json +115 -68
- package/platforms/opencode/config.template.json +3 -7
- package/rules/common/agents.md +11 -38
- package/rules/common/beads-hygiene.md +75 -0
- package/rules/common/code-review.md +11 -100
- package/rules/common/coding-style.md +5 -3
- package/rules/common/comments.md +30 -111
- package/rules/common/commit-approval.md +53 -0
- package/rules/common/cx-agent-routing.md +1 -0
- package/rules/common/development-workflow.md +23 -41
- package/rules/common/doc-ownership.md +54 -0
- package/rules/common/efficiency.md +57 -0
- package/rules/common/framing.md +76 -0
- package/rules/common/git-workflow.md +2 -4
- package/rules/common/patterns.md +3 -7
- package/rules/common/performance.md +15 -31
- package/rules/common/release-gates.md +69 -0
- package/rules/common/research.md +107 -0
- package/rules/common/security.md +6 -6
- package/rules/common/skill-composition.md +67 -0
- package/rules/common/testing.md +15 -27
- package/rules/golang/hooks.md +0 -4
- package/rules/policy/bootstrap.yaml +11 -0
- package/rules/policy/drive.yaml +8 -0
- package/rules/policy/task.yaml +9 -0
- package/rules/policy/workflow.yaml +9 -0
- package/rules/python/hooks.md +0 -4
- package/rules/swift/hooks.md +0 -4
- package/rules/typescript/hooks.md +0 -4
- package/rules/web/hooks.md +0 -2
- package/{sync-agents.mjs → scripts/sync-agents.mjs} +306 -61
- package/skills/ai/prompt-optimizer.md +7 -7
- package/skills/compliance/ai-disclosure.md +58 -0
- package/skills/compliance/data-privacy.md +46 -0
- package/skills/compliance/license-audit.md +40 -0
- package/skills/compliance/regulatory-review.md +61 -0
- package/skills/docs/document-ingest-workflow.md +52 -0
- package/skills/docs/evidence-ingest-workflow.md +9 -0
- package/skills/docs/init-docs.md +51 -18
- package/skills/docs/product-intelligence-workflow.md +12 -0
- package/skills/docs/product-signal-workflow.md +4 -0
- package/skills/docs/research-workflow.md +23 -8
- package/skills/docs/runbook-workflow.md +1 -1
- package/skills/operating/orchestration-reference.md +151 -0
- package/skills/roles/architect.md +5 -0
- package/skills/roles/engineer.md +32 -0
- package/skills/roles/operator.md +12 -0
- package/skills/roles/reviewer.md +23 -0
- package/skills/routing.md +1 -1
- package/templates/devcontainer/Dockerfile.devcontainer +38 -0
- package/templates/devcontainer/devcontainer.json +31 -0
- package/templates/distribution/bootstrap.ps1 +142 -0
- package/templates/distribution/bootstrap.sh +196 -0
- package/templates/distribution/run.mjs +187 -0
- package/templates/docs/adr.md +44 -8
- package/templates/docs/changelog-entry.md +43 -0
- package/templates/docs/construct_guide.md +149 -0
- package/templates/docs/evidence-brief.md +2 -2
- package/templates/docs/meta-prd.md +140 -19
- package/templates/docs/onboarding.md +57 -0
- package/templates/docs/prd.md +159 -15
- package/templates/docs/research-brief.md +4 -4
- package/templates/homebrew/construct.rb +67 -0
- package/langfuse/docker-compose.yml +0 -82
- package/lib/eval-harness.mjs +0 -59
- package/lib/hooks/bootstrap-guard.mjs +0 -90
- package/lib/hooks/console-warn.mjs +0 -43
- package/lib/hooks/continuation-enforcer.mjs +0 -72
- package/lib/hooks/drive-guard.mjs +0 -89
- package/lib/hooks/mcp-task-scope.mjs +0 -47
- package/lib/hooks/task-completed-guard.mjs +0 -43
- package/lib/hooks/teammate-idle-guard.mjs +0 -54
- package/lib/hooks/workflow-guard.mjs +0 -62
- package/lib/prompt-composer.mjs +0 -196
- package/lib/review.mjs +0 -429
- package/lib/server/static/app.js +0 -841
- package/lib/telemetry/langfuse-model-sync.mjs +0 -270
- package/rules/common/hooks.md +0 -35
- package/rules/zh/README.md +0 -113
- package/rules/zh/agents.md +0 -55
- package/rules/zh/code-review.md +0 -129
- package/rules/zh/coding-style.md +0 -53
- package/rules/zh/development-workflow.md +0 -49
- package/rules/zh/git-workflow.md +0 -29
- package/rules/zh/hooks.md +0 -35
- package/rules/zh/patterns.md +0 -36
- package/rules/zh/performance.md +0 -60
- package/rules/zh/security.md +0 -34
- package/rules/zh/testing.md +0 -34
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lib/skills-apply.mjs — writes per-host skill filter configs from the
|
|
3
|
+
* project profile.
|
|
4
|
+
*
|
|
5
|
+
* The detection layer (lib/project-profile.mjs) is host-agnostic. This layer
|
|
6
|
+
* consumes a profile and writes host-specific configuration that scopes which
|
|
7
|
+
* skills/plugins auto-inject in the current project.
|
|
8
|
+
*
|
|
9
|
+
* Safety guarantees (org-in-a-box):
|
|
10
|
+
* 1. isProtectedSkill() from project-profile.mjs defines a NEVER-FILTER set
|
|
11
|
+
* covering construct personas, cx-* specialists, cross-cutting skills,
|
|
12
|
+
* role-domain namespaces (engineering:, product-management:, etc.), and
|
|
13
|
+
* Claude Code dev infrastructure. These are always kept enabled.
|
|
14
|
+
* 2. The filter is *additive recommendation* — disabled plugins remain on
|
|
15
|
+
* disk and can be called explicitly. We only remove them from automatic
|
|
16
|
+
* per-turn injection.
|
|
17
|
+
* 3. A construct-native manifest (.cx/skills-profile.json) records the
|
|
18
|
+
* decision so construct-mcp can read it at session start and surface
|
|
19
|
+
* what was filtered.
|
|
20
|
+
* 4. Never overwrite an existing `.claude/settings.json` key the user set
|
|
21
|
+
* manually — merge into disabledPlugins with de-dup.
|
|
22
|
+
*/
|
|
23
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
24
|
+
import { homedir } from 'node:os';
|
|
25
|
+
import { dirname, join, resolve } from 'node:path';
|
|
26
|
+
import {
|
|
27
|
+
classifySkillRelevance,
|
|
28
|
+
detectProjectProfile,
|
|
29
|
+
enumerateInstalledSkills,
|
|
30
|
+
writeProfile,
|
|
31
|
+
} from './project-profile.mjs';
|
|
32
|
+
|
|
33
|
+
const SUPPORTED_HOSTS = new Set(['claude', 'opencode', 'codex', 'all']);
|
|
34
|
+
|
|
35
|
+
function readJsonSafe(path) {
|
|
36
|
+
try { return JSON.parse(readFileSync(path, 'utf8')); } catch { return null; }
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function writeJsonPretty(path, data) {
|
|
40
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
41
|
+
writeFileSync(path, JSON.stringify(data, null, 2) + '\n', 'utf8');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function unionArrays(existing, incoming) {
|
|
45
|
+
const seen = new Set();
|
|
46
|
+
const result = [];
|
|
47
|
+
for (const arr of [existing, incoming]) {
|
|
48
|
+
for (const item of arr || []) {
|
|
49
|
+
if (seen.has(item)) continue;
|
|
50
|
+
seen.add(item);
|
|
51
|
+
result.push(item);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return result.sort();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Writes the construct-native project manifest to `<cwd>/.cx/skills-profile.json`.
|
|
59
|
+
* The authoritative record consumed by construct-mcp and any future per-host
|
|
60
|
+
* writers that want to re-derive the decision.
|
|
61
|
+
*/
|
|
62
|
+
export function writeConstructManifest(cwd, profile, classification) {
|
|
63
|
+
const path = join(cwd, '.cx', 'skills-profile.json');
|
|
64
|
+
const payload = {
|
|
65
|
+
version: 1,
|
|
66
|
+
generatedAt: new Date().toISOString(),
|
|
67
|
+
profile: {
|
|
68
|
+
tags: profile.tags,
|
|
69
|
+
signals: profile.signals,
|
|
70
|
+
},
|
|
71
|
+
decision: {
|
|
72
|
+
relevant: classification.relevant,
|
|
73
|
+
irrelevant: classification.irrelevant,
|
|
74
|
+
unknown: classification.unknown,
|
|
75
|
+
protected: classification.protected || [],
|
|
76
|
+
},
|
|
77
|
+
// The "recommended disabled" list. Never includes protected skills.
|
|
78
|
+
// Hosts are expected to honor this as a scoping recommendation.
|
|
79
|
+
recommendedDisable: classification.irrelevant,
|
|
80
|
+
};
|
|
81
|
+
writeJsonPretty(path, payload);
|
|
82
|
+
return path;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Writes `<cwd>/.claude/construct-skills.json` — a construct-owned sidecar
|
|
87
|
+
* that records the recommended per-project scoping for Claude Code.
|
|
88
|
+
*
|
|
89
|
+
* Why a sidecar and not `settings.json`? Claude Code today only reads
|
|
90
|
+
* `permissions`, `hooks`, and `mcpServers` from settings.json. A
|
|
91
|
+
* `disabledPlugins` key would be ignored silently. Writing a sidecar is
|
|
92
|
+
* honest — it documents the recommendation without pretending the harness
|
|
93
|
+
* enforces it. The construct-mcp session-start path can read this sidecar
|
|
94
|
+
* and inject a "skills out of scope for this project" note.
|
|
95
|
+
*
|
|
96
|
+
* If Claude Code adds per-project plugin scoping in the future, the
|
|
97
|
+
* adapter will flip to writing the supported key(s) directly.
|
|
98
|
+
*/
|
|
99
|
+
export function writeClaudeHostConfig(cwd, classification) {
|
|
100
|
+
const path = join(cwd, '.claude', 'construct-skills.json');
|
|
101
|
+
writeJsonPretty(path, {
|
|
102
|
+
$comment: 'Construct-owned sidecar. Claude Code does not currently honor project-level skill scoping; this is advisory. construct-mcp can read this to surface out-of-scope skills at session start.',
|
|
103
|
+
version: 1,
|
|
104
|
+
generatedAt: new Date().toISOString(),
|
|
105
|
+
source: '.cx/skills-profile.json',
|
|
106
|
+
recommendedDisable: classification.irrelevant,
|
|
107
|
+
protected: classification.protected || [],
|
|
108
|
+
});
|
|
109
|
+
return path;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Writes a Construct-owned OpenCode sidecar at `<cwd>/.opencode/construct-skills.json`.
|
|
114
|
+
*
|
|
115
|
+
* OpenCode will eagerly parse `<cwd>/opencode.json` as first-party config, so
|
|
116
|
+
* Construct must not write custom top-level keys there. The session-start
|
|
117
|
+
* adapter can read this sidecar and surface skill-scoping guidance without
|
|
118
|
+
* breaking OpenCode's schema validation.
|
|
119
|
+
*/
|
|
120
|
+
export function writeOpenCodeHostConfig(cwd, classification) {
|
|
121
|
+
const path = join(cwd, '.opencode', 'construct-skills.json');
|
|
122
|
+
const existing = readJsonSafe(path) || {};
|
|
123
|
+
const currentDisabled = existing?.recommendedDisable || existing?.disabledSkills || [];
|
|
124
|
+
const disabledSkills = unionArrays(currentDisabled, classification.irrelevant);
|
|
125
|
+
writeJsonPretty(path, {
|
|
126
|
+
$comment: 'Construct-owned sidecar. OpenCode rejects unknown top-level opencode.json keys; construct-mcp reads .cx/skills-profile.json at session start.',
|
|
127
|
+
version: 1,
|
|
128
|
+
generatedAt: new Date().toISOString(),
|
|
129
|
+
source: '.cx/skills-profile.json',
|
|
130
|
+
recommendedDisable: disabledSkills,
|
|
131
|
+
disabledSkills,
|
|
132
|
+
protected: classification.protected || [],
|
|
133
|
+
});
|
|
134
|
+
return path;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Writes per-project Codex config hints. Codex config is TOML; to avoid a TOML
|
|
139
|
+
* dependency we write a sidecar JSON file instead — `.codex/skills-profile.json` —
|
|
140
|
+
* that the Codex adapter can read at session start. Users who want the filter
|
|
141
|
+
* baked into codex config itself can run `construct sync` after this.
|
|
142
|
+
*/
|
|
143
|
+
export function writeCodexHostConfig(cwd, classification) {
|
|
144
|
+
const path = join(cwd, '.codex', 'skills-profile.json');
|
|
145
|
+
writeJsonPretty(path, {
|
|
146
|
+
version: 1,
|
|
147
|
+
generatedAt: new Date().toISOString(),
|
|
148
|
+
disabledSkills: classification.irrelevant,
|
|
149
|
+
});
|
|
150
|
+
return path;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const HOST_WRITERS = {
|
|
154
|
+
claude: writeClaudeHostConfig,
|
|
155
|
+
opencode: writeOpenCodeHostConfig,
|
|
156
|
+
codex: writeCodexHostConfig,
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
function parseArgs(args) {
|
|
160
|
+
const options = { host: null, dryRun: false, cwd: process.cwd(), yes: false };
|
|
161
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
162
|
+
const arg = args[i];
|
|
163
|
+
if (arg === '--dry-run' || arg === '-n') options.dryRun = true;
|
|
164
|
+
else if (arg === '--yes' || arg === '-y') options.yes = true;
|
|
165
|
+
else if (arg === '--help' || arg === '-h') options.help = true;
|
|
166
|
+
else if (arg === '--host') options.host = args[++i];
|
|
167
|
+
else if (arg.startsWith('--host=')) options.host = arg.slice(7);
|
|
168
|
+
else if (arg === '--cwd') options.cwd = args[++i];
|
|
169
|
+
else if (arg.startsWith('--cwd=')) options.cwd = arg.slice(6);
|
|
170
|
+
}
|
|
171
|
+
return options;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export async function runSkillsApplyCli(args = []) {
|
|
175
|
+
const options = parseArgs(args);
|
|
176
|
+
|
|
177
|
+
if (options.help) {
|
|
178
|
+
console.log(`Usage: construct skills apply --host <name> [options]
|
|
179
|
+
|
|
180
|
+
Applies a per-project skill filter based on the detected project profile.
|
|
181
|
+
Writes host-specific config that scopes which skills auto-inject for this
|
|
182
|
+
project, reducing per-turn context bloat without affecting other repos.
|
|
183
|
+
|
|
184
|
+
Options:
|
|
185
|
+
--host <name> claude | opencode | codex | all (required)
|
|
186
|
+
--cwd <path> Target directory (default: CWD)
|
|
187
|
+
--dry-run, -n Preview the filter without writing any files
|
|
188
|
+
--yes, -y Skip confirmation prompt
|
|
189
|
+
-h, --help Show this message
|
|
190
|
+
|
|
191
|
+
Safety: skills protected by rules/common/doc-ownership.md and Construct's
|
|
192
|
+
cx-* specialist infrastructure are NEVER filtered. The filter is an
|
|
193
|
+
auto-injection scope — disabled skills remain callable via get_skill.
|
|
194
|
+
|
|
195
|
+
The .cx/skills-profile.json manifest records the decision for audit.
|
|
196
|
+
`);
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (!options.host) {
|
|
201
|
+
console.error('Error: --host <claude|opencode|codex|all> is required.');
|
|
202
|
+
console.error('Run with --help for usage.');
|
|
203
|
+
process.exit(1);
|
|
204
|
+
}
|
|
205
|
+
if (!SUPPORTED_HOSTS.has(options.host)) {
|
|
206
|
+
console.error(`Error: unknown host "${options.host}". Supported: claude, opencode, codex, all.`);
|
|
207
|
+
process.exit(1);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const cwd = resolve(options.cwd);
|
|
211
|
+
const profile = detectProjectProfile(cwd);
|
|
212
|
+
|
|
213
|
+
if (profile.tags.length === 0) {
|
|
214
|
+
console.log('No tech-stack signals detected in this directory.');
|
|
215
|
+
console.log('Skipping filter generation — an empty profile would disable nothing useful.');
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
const installed = enumerateInstalledSkills(homedir());
|
|
220
|
+
const classification = classifySkillRelevance(profile, installed);
|
|
221
|
+
|
|
222
|
+
console.log('Project profile');
|
|
223
|
+
console.log('═══════════════');
|
|
224
|
+
console.log(` Detected: ${profile.tags.join(', ')}`);
|
|
225
|
+
console.log(` Host: ${options.host}`);
|
|
226
|
+
console.log('');
|
|
227
|
+
console.log(` Installed skills: ${installed.length}`);
|
|
228
|
+
console.log(` Protected: ${classification.protected.length} (never filtered)`);
|
|
229
|
+
console.log(` Relevant: ${classification.relevant.length}`);
|
|
230
|
+
console.log(` Unmapped: ${classification.unknown.length}`);
|
|
231
|
+
console.log(` Will be disabled: ${classification.irrelevant.length}`);
|
|
232
|
+
console.log('');
|
|
233
|
+
|
|
234
|
+
if (classification.irrelevant.length === 0) {
|
|
235
|
+
console.log('Nothing to disable — exiting.');
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
console.log('Skills that will be disabled for this project:');
|
|
240
|
+
console.log(classification.irrelevant.map((s) => ` - ${s}`).join('\n'));
|
|
241
|
+
console.log('');
|
|
242
|
+
console.log('Safeguards applied:');
|
|
243
|
+
console.log(` - ${classification.protected.length} skills protected by construct safeguards`);
|
|
244
|
+
console.log(` - ${classification.unknown.length} unmapped skills kept as relevant by default`);
|
|
245
|
+
console.log(` - Disabled skills remain on disk; callable via get_skill on demand`);
|
|
246
|
+
console.log(` - cx-* specialists use construct-mcp get_skill (never host injection)`);
|
|
247
|
+
console.log('');
|
|
248
|
+
|
|
249
|
+
if (options.dryRun) {
|
|
250
|
+
console.log('Dry run — no files written. Use without --dry-run to apply.');
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Always write the construct manifest first — it's the authoritative record.
|
|
255
|
+
const manifestPath = writeConstructManifest(cwd, profile, classification);
|
|
256
|
+
writeProfile(profile, cwd);
|
|
257
|
+
console.log(`✓ Manifest: ${manifestPath}`);
|
|
258
|
+
|
|
259
|
+
const hostsToWrite = options.host === 'all' ? ['claude', 'opencode', 'codex'] : [options.host];
|
|
260
|
+
for (const host of hostsToWrite) {
|
|
261
|
+
const writer = HOST_WRITERS[host];
|
|
262
|
+
if (!writer) continue;
|
|
263
|
+
try {
|
|
264
|
+
const path = writer(cwd, classification);
|
|
265
|
+
console.log(`✓ ${host.padEnd(8)}: ${path}`);
|
|
266
|
+
} catch (err) {
|
|
267
|
+
console.error(`✗ ${host.padEnd(8)}: ${err?.message || 'write failed'}`);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
console.log('');
|
|
271
|
+
console.log('Manifest + per-host sidecars written. Host support varies:');
|
|
272
|
+
console.log(' - Claude Code: sidecar at .claude/construct-skills.json (advisory today;');
|
|
273
|
+
console.log(' construct-mcp can read it at session start).');
|
|
274
|
+
console.log(' - OpenCode: sidecar at .opencode/construct-skills.json');
|
|
275
|
+
console.log(' (construct-owned metadata; avoids invalid opencode.json keys).');
|
|
276
|
+
console.log(' - Codex: sidecar at .codex/skills-profile.json (adapter reads at startup).');
|
|
277
|
+
console.log('');
|
|
278
|
+
console.log('The authoritative record is .cx/skills-profile.json (version-controllable).');
|
|
279
|
+
console.log('To revert: delete the files under .claude/, .opencode/, or .codex/ as appropriate.');
|
|
280
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* lib/skills-scope.mjs — CLI surface for project-profile-driven skill scoping.
|
|
3
|
+
*
|
|
4
|
+
* Powers `construct skills scope` (and, later, auto-generation of per-host
|
|
5
|
+
* skill filters). The detection layer is in lib/project-profile.mjs and is
|
|
6
|
+
* host-agnostic by design — this file composes it into a reportable workflow
|
|
7
|
+
* and will later wire per-host filter writers.
|
|
8
|
+
*/
|
|
9
|
+
import { homedir } from 'node:os';
|
|
10
|
+
import {
|
|
11
|
+
classifySkillRelevance,
|
|
12
|
+
detectProjectProfile,
|
|
13
|
+
enumerateInstalledSkills,
|
|
14
|
+
writeProfile,
|
|
15
|
+
} from './project-profile.mjs';
|
|
16
|
+
|
|
17
|
+
function formatList(list, { limit = 20 } = {}) {
|
|
18
|
+
if (list.length === 0) return ' (none)';
|
|
19
|
+
const shown = list.slice(0, limit);
|
|
20
|
+
const rest = list.length > limit ? `\n ... and ${list.length - limit} more` : '';
|
|
21
|
+
return shown.map((name) => ` - ${name}`).join('\n') + rest;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export async function runSkillsScopeCli(args = []) {
|
|
25
|
+
const flags = new Set();
|
|
26
|
+
const options = { cwd: process.cwd() };
|
|
27
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
28
|
+
const arg = args[i];
|
|
29
|
+
if (arg === '--json') flags.add('json');
|
|
30
|
+
else if (arg === '--write') flags.add('write');
|
|
31
|
+
else if (arg === '--no-write') flags.add('no-write');
|
|
32
|
+
else if (arg === '--help' || arg === '-h') flags.add('help');
|
|
33
|
+
else if (arg === '--cwd') options.cwd = args[++i];
|
|
34
|
+
else if (arg.startsWith('--cwd=')) options.cwd = arg.slice(6);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (flags.has('help')) {
|
|
38
|
+
console.log(`Usage: construct skills scope [options]
|
|
39
|
+
|
|
40
|
+
Detects the project's tech stack from filesystem signals (package.json,
|
|
41
|
+
pyproject.toml, go.mod, Cargo.toml, etc.) and reports which installed
|
|
42
|
+
skills are relevant vs irrelevant to the current repo.
|
|
43
|
+
|
|
44
|
+
Writes .cx/project-profile.json by default (disable with --no-write).
|
|
45
|
+
|
|
46
|
+
Options:
|
|
47
|
+
--cwd <path> Target directory (defaults to CWD)
|
|
48
|
+
--json Emit the profile + classification as JSON
|
|
49
|
+
--no-write Skip writing .cx/project-profile.json
|
|
50
|
+
--write Force write (default behavior)
|
|
51
|
+
-h, --help Show this message
|
|
52
|
+
|
|
53
|
+
The detection layer is host-agnostic. A future pass can use the profile to
|
|
54
|
+
generate per-host skill filters (.claude/ sidecars, .opencode/ sidecars, etc.).
|
|
55
|
+
`);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const profile = detectProjectProfile(options.cwd);
|
|
60
|
+
const installed = enumerateInstalledSkills(homedir());
|
|
61
|
+
const classification = classifySkillRelevance(profile, installed);
|
|
62
|
+
|
|
63
|
+
let profilePath = null;
|
|
64
|
+
if (!flags.has('no-write')) {
|
|
65
|
+
try { profilePath = writeProfile(profile, options.cwd); } catch { /* best effort */ }
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (flags.has('json')) {
|
|
69
|
+
console.log(JSON.stringify({
|
|
70
|
+
profile,
|
|
71
|
+
classification,
|
|
72
|
+
installedCount: installed.length,
|
|
73
|
+
profilePath,
|
|
74
|
+
}, null, 2));
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const irrelevantRatio = installed.length === 0 ? 0 :
|
|
79
|
+
Math.round((classification.irrelevant.length / installed.length) * 100);
|
|
80
|
+
|
|
81
|
+
console.log('Project profile');
|
|
82
|
+
console.log('═══════════════');
|
|
83
|
+
console.log(` Root ${profile.root}`);
|
|
84
|
+
console.log(` Detected ${profile.tags.length ? profile.tags.join(', ') : '(no signals matched)'}`);
|
|
85
|
+
console.log(` Signals ${profile.signals.length ? profile.signals.join(', ') : '(none)'}`);
|
|
86
|
+
if (profilePath) console.log(` Saved ${profilePath}`);
|
|
87
|
+
console.log('');
|
|
88
|
+
|
|
89
|
+
console.log('Installed skills classification');
|
|
90
|
+
console.log('───────────────────────────────');
|
|
91
|
+
console.log(` Total installed: ${installed.length}`);
|
|
92
|
+
console.log(` Relevant: ${classification.relevant.length}`);
|
|
93
|
+
console.log(` Irrelevant: ${classification.irrelevant.length} (${irrelevantRatio}% of total)`);
|
|
94
|
+
console.log(` Unmapped: ${classification.unknown.length} (default: treat as relevant)`);
|
|
95
|
+
console.log('');
|
|
96
|
+
|
|
97
|
+
if (classification.irrelevant.length > 0) {
|
|
98
|
+
console.log('Irrelevant skills for this project:');
|
|
99
|
+
console.log(formatList(classification.irrelevant));
|
|
100
|
+
console.log('');
|
|
101
|
+
console.log('These are loaded on every turn by the host but do not match this');
|
|
102
|
+
console.log('project\'s tech stack. To reduce per-turn context footprint:');
|
|
103
|
+
console.log('');
|
|
104
|
+
console.log(' - Claude Code: edit ~/.claude/settings.json or per-project .claude/');
|
|
105
|
+
console.log(' plugins.json to disable plugins you don\'t need in this repo.');
|
|
106
|
+
console.log(' - OpenCode: edit ~/.config/opencode/opencode.json');
|
|
107
|
+
console.log(' - Codex: edit ~/.codex/agents/ filters');
|
|
108
|
+
console.log('');
|
|
109
|
+
console.log('Future: `construct skills apply --host <name>` will generate these');
|
|
110
|
+
console.log('filter configs automatically from the profile above.');
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (classification.unknown.length > 0 && classification.unknown.length < 40) {
|
|
114
|
+
console.log('');
|
|
115
|
+
console.log(`Unmapped skills (no relevance rule — default kept):`);
|
|
116
|
+
console.log(formatList(classification.unknown, { limit: 10 }));
|
|
117
|
+
}
|
|
118
|
+
}
|