@event4u/agent-config 3.3.0 → 4.2.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/.agent-src/README.md +2 -2
- package/.agent-src/commands/agent-handoff.md +31 -2
- package/.agent-src/commands/agent-status.md +5 -5
- package/.agent-src/commands/agents/audit.md +8 -8
- package/.agent-src/commands/agents/init.md +25 -1
- package/.agent-src/commands/agents/optimize.md +3 -3
- package/.agent-src/commands/agents/user.md +1 -1
- package/.agent-src/commands/agents.md +1 -1
- package/.agent-src/commands/analyze-reference-repo.md +1 -1
- package/.agent-src/commands/check-current-md.md +8 -8
- package/.agent-src/commands/{compress.md → condense.md} +55 -55
- package/.agent-src/commands/context/create.md +7 -4
- package/.agent-src/commands/context/refactor.md +3 -1
- package/.agent-src/commands/feature/dev.md +1 -1
- package/.agent-src/commands/feature/explore.md +1 -1
- package/.agent-src/commands/feature/plan.md +10 -8
- package/.agent-src/commands/feature/refactor.md +3 -1
- package/.agent-src/commands/feature/roadmap.md +7 -4
- package/.agent-src/commands/fix/portability.md +3 -3
- package/.agent-src/commands/fix/refs.md +4 -4
- package/.agent-src/commands/ghostwriter.md +2 -2
- package/.agent-src/commands/memory/learn-low-impact.md +3 -3
- package/.agent-src/commands/module/explore.md +34 -8
- package/.agent-src/commands/optimize/agents-dir.md +9 -7
- package/.agent-src/commands/optimize/augmentignore.md +2 -2
- package/.agent-src/commands/optimize/skills.md +9 -9
- package/.agent-src/commands/post-as.md +1 -1
- package/.agent-src/commands/project-analyze.md +2 -2
- package/.agent-src/commands/project-health.md +3 -2
- package/.agent-src/commands/research/deep.md +1 -1
- package/.agent-src/commands/research/report.md +1 -1
- package/.agent-src/commands/research.md +1 -1
- package/.agent-src/commands/roadmap/ai-council.md +1 -1
- package/.agent-src/commands/roadmap/create.md +9 -4
- package/.agent-src/commands/rule-compliance-audit.md +1 -1
- package/.agent-src/commands/upstream-contribute.md +14 -14
- package/.agent-src/commands/video/from-script.md +1 -1
- package/.agent-src/commands/video/scene.md +1 -1
- package/.agent-src/commands/video/stitch.md +1 -1
- package/.agent-src/commands/video/storyboard.md +1 -1
- package/.agent-src/commands/video.md +1 -1
- package/.agent-src/contexts/augment-infrastructure.md +1 -1
- package/.agent-src/contexts/authority/commit-mechanics.md +15 -0
- package/.agent-src/contexts/authority/kernel-rule-edits.md +3 -3
- package/.agent-src/contexts/authority/scope-mechanics.md +1 -1
- package/.agent-src/contexts/communication/rules-auto/augment-source-of-truth-mechanics.md +28 -28
- package/.agent-src/contexts/communication/rules-auto/skill-quality-mechanics.md +4 -4
- package/.agent-src/contexts/communication/rules-auto/think-before-action-mechanics.md +2 -2
- package/.agent-src/contexts/contracts/artifact-engagement-flow.md +6 -6
- package/.agent-src/contexts/contracts/command-suggestion-flow.md +3 -3
- package/.agent-src/contexts/contracts/emergency-triage-block.md +4 -4
- package/.agent-src/contexts/contracts/frugality-charter.md +3 -3
- package/.agent-src/contexts/documentation-hierarchy.md +14 -7
- package/.agent-src/contexts/execution/autonomy-examples.md +1 -1
- package/.agent-src/contexts/execution/cheap-question-mechanics.md +39 -2
- package/.agent-src/contexts/execution/roadmap-process-loop.md +28 -5
- package/.agent-src/contexts/override-system.md +5 -5
- package/.agent-src/ghostwriter/fictional-fixture-v1.md +1 -1
- package/.agent-src/personas/advisors/first-principles.md +1 -1
- package/.agent-src/personas/hollywood-director.md +1 -1
- package/.agent-src/rules/architecture.md +5 -1
- package/.agent-src/rules/augment-edit-discipline.md +5 -5
- package/.agent-src/rules/augment-source-of-truth.md +15 -15
- package/.agent-src/rules/commit-conventions.md +1 -1
- package/.agent-src/rules/commit-policy.md +10 -0
- package/.agent-src/rules/domain-adoption-policy.md +3 -3
- package/.agent-src/rules/fast-path-marker-visibility.md +3 -3
- package/.agent-src/rules/finance-safety-floor.md +1 -1
- package/.agent-src/rules/framework-neutrality-in-generic-skills.md +8 -8
- package/.agent-src/rules/git-history-discipline.md +1 -1
- package/.agent-src/rules/improve-before-implement.md +2 -2
- package/.agent-src/rules/language-and-tone.md +2 -2
- package/.agent-src/rules/media-governance-routing.md +5 -5
- package/.agent-src/rules/no-attribution-footers.md +1 -0
- package/.agent-src/rules/no-cheap-questions.md +3 -0
- package/.agent-src/rules/no-decorative-emojis-in-git-surfaces.md +111 -0
- package/.agent-src/rules/no-pr-progress-comments.md +118 -0
- package/.agent-src/rules/no-roadmap-references.md +3 -3
- package/.agent-src/rules/non-destructive-by-default.md +1 -1
- package/.agent-src/rules/persona-governance.md +3 -3
- package/.agent-src/rules/preservation-guard.md +15 -15
- package/.agent-src/rules/roadmap-ci-steps-policy.md +7 -3
- package/.agent-src/rules/rule-type-governance.md +1 -1
- package/.agent-src/rules/skill-quality.md +1 -1
- package/.agent-src/rules/{caveman-speak.md → telegraph-speak.md} +15 -15
- package/.agent-src/rules/token-optimizer-maintenance.md +6 -6
- package/.agent-src/skills/agent-docs-writing/SKILL.md +17 -11
- package/.agent-src/skills/agents-md-thin-root/SKILL.md +9 -9
- package/.agent-src/skills/check-refs/SKILL.md +2 -2
- package/.agent-src/skills/code-refactoring/SKILL.md +2 -2
- package/.agent-src/skills/command-writing/SKILL.md +19 -19
- package/.agent-src/skills/comp-banding/SKILL.md +1 -1
- package/.agent-src/skills/condense-memory/SKILL.md +131 -0
- package/.agent-src/skills/context-authoring/SKILL.md +2 -2
- package/.agent-src/skills/context-document/SKILL.md +5 -3
- package/.agent-src/skills/copilot-agents-optimization/SKILL.md +3 -3
- package/.agent-src/skills/description-assist/SKILL.md +2 -2
- package/.agent-src/skills/git-workflow/SKILL.md +1 -1
- package/.agent-src/skills/guideline-writing/SKILL.md +5 -5
- package/.agent-src/skills/learning-to-rule-or-skill/SKILL.md +4 -4
- package/.agent-src/skills/lint-skills/SKILL.md +3 -3
- package/.agent-src/skills/md-language-check/SKILL.md +2 -2
- package/.agent-src/skills/module-detect-on-the-fly/SKILL.md +138 -0
- package/.agent-src/skills/module-management/SKILL.md +166 -94
- package/.agent-src/skills/override-management/SKILL.md +1 -1
- package/.agent-src/skills/persona-writing/SKILL.md +5 -5
- package/.agent-src/skills/positioning-strategy/SKILL.md +1 -1
- package/.agent-src/skills/project-docs/SKILL.md +6 -4
- package/.agent-src/skills/readme-reviewer/SKILL.md +2 -2
- package/.agent-src/skills/roadmap-management/SKILL.md +13 -1
- package/.agent-src/skills/roadmap-writing/SKILL.md +4 -2
- package/.agent-src/skills/rule-refactor/SKILL.md +5 -5
- package/.agent-src/skills/rule-writing/SKILL.md +18 -18
- package/.agent-src/skills/script-writing/SKILL.md +1 -1
- package/.agent-src/skills/skill-improvement-pipeline/SKILL.md +6 -6
- package/.agent-src/skills/skill-management/SKILL.md +21 -21
- package/.agent-src/skills/skill-reviewer/SKILL.md +2 -2
- package/.agent-src/skills/skill-writing/SKILL.md +8 -8
- package/.agent-src/skills/skill-writing/evals/triggers.json +1 -1
- package/.agent-src/skills/token-optimizer/SKILL.md +4 -4
- package/.agent-src/skills/unit-economics-modeling/SKILL.md +1 -1
- package/.agent-src/skills/upstream-contribute/SKILL.md +17 -17
- package/.agent-src/templates/AGENTS.md +1 -0
- package/.agent-src/templates/agent-settings.md +24 -13
- package/.agent-src/templates/agents/agent-project-settings.example.yml +61 -2
- package/.agent-src/templates/command.md +5 -5
- package/.agent-src/templates/contexts.md +1 -1
- package/.agent-src/templates/copilot-instructions.md +8 -8
- package/.agent-src/templates/features.md +1 -1
- package/.agent-src/templates/hooks/pre-commit-frontmatter +2 -2
- package/.agent-src/templates/hooks/pre-commit-roadmap-progress +3 -3
- package/.agent-src/templates/persona.md +2 -2
- package/.agent-src/templates/roadmaps.md +1 -1
- package/.agent-src/templates/rule.md +13 -13
- package/.agent-src/templates/scripts/memory_lookup.py +1 -1
- package/.agent-src/templates/scripts/memory_status.py +2 -2
- package/.agent-src/templates/scripts/work_engine/_lib/agent_settings.py +195 -1
- package/.agent-src/templates/scripts/work_engine/orchestration.py +1 -1
- package/.agent-src/templates/skill-archive-note.md +5 -5
- package/.agent-src/templates/skill.md +1 -1
- package/.claude-plugin/marketplace.json +4 -4
- package/AGENTS.md +16 -17
- package/CHANGELOG.md +216 -3
- package/CONTRIBUTING.md +31 -12
- package/README.md +21 -12
- package/config/agent-settings.template.yml +22 -2
- package/config/discovery/unassigned-artefacts.yml +24 -24
- package/config/profiles/full.ini +1 -1
- package/dist/cli/agent-config.js +52 -3
- package/dist/cli/agent-config.js.map +1 -1
- package/dist/cli/commands/uiServe.js +9 -0
- package/dist/cli/commands/uiServe.js.map +1 -1
- package/dist/cli/registry.js +2 -1
- package/dist/cli/registry.js.map +1 -1
- package/dist/discovery/deprecation-report.md +1 -1
- package/dist/discovery/discovery-manifest.json +649 -606
- package/dist/discovery/discovery-manifest.json.sha256 +1 -1
- package/dist/discovery/discovery-manifest.summary.md +4 -4
- package/dist/discovery/orphan-report.md +1 -1
- package/dist/discovery/packs.json +439 -437
- package/dist/discovery/trust-report.md +5 -5
- package/dist/discovery/workspaces.json +450 -448
- package/dist/install/atomic.js +92 -0
- package/dist/install/atomic.js.map +1 -0
- package/dist/install/conflict.js +196 -0
- package/dist/install/conflict.js.map +1 -0
- package/dist/install/detect.js +218 -0
- package/dist/install/detect.js.map +1 -0
- package/dist/install/paths.js +82 -0
- package/dist/install/paths.js.map +1 -0
- package/dist/install/plan.js +157 -0
- package/dist/install/plan.js.map +1 -0
- package/dist/install/txlog.js +140 -0
- package/dist/install/txlog.js.map +1 -0
- package/dist/install/types.js +19 -0
- package/dist/install/types.js.map +1 -0
- package/dist/install/wizard-plan.js +184 -0
- package/dist/install/wizard-plan.js.map +1 -0
- package/dist/mcp/registry-manifest.json +4 -4
- package/dist/router.json +67 -19
- package/dist/server/app.js +6 -0
- package/dist/server/app.js.map +1 -1
- package/dist/server/routes/install.js +358 -0
- package/dist/server/routes/install.js.map +1 -0
- package/dist/server/routes/wizard.js +468 -32
- package/dist/server/routes/wizard.js.map +1 -1
- package/dist/server/routes/workspace.js +396 -0
- package/dist/server/routes/workspace.js.map +1 -0
- package/dist/server/schemas/settings.js +5 -3
- package/dist/server/schemas/settings.js.map +1 -1
- package/dist/ui/assets/index-BDAhhpDV.js +40 -0
- package/dist/ui/assets/index-BDAhhpDV.js.map +1 -0
- package/dist/ui/assets/index-BXZILUxe.css +1 -0
- package/dist/ui/index.html +2 -2
- package/docs/MIGRATION.md +1 -1
- package/docs/adrs/cost/0001-hard-stop-hook.md +1 -1
- package/docs/adrs/router/0001-three-tier-routing.md +4 -4
- package/docs/adrs/schema/0001-json-schema-frontmatter.md +1 -1
- package/docs/adrs/smoke/0001-per-tier-smoke-scripts.md +4 -4
- package/docs/adrs/{caveman → telegraph}/0001-default-off-until-bench.md +9 -9
- package/docs/adrs/telegraph/README.md +9 -0
- package/docs/architecture/augment-projection.md +4 -4
- package/docs/architecture/claude-bundle.md +1 -1
- package/docs/architecture/current-onboard-baseline.md +3 -3
- package/docs/architecture/multi-tool-projection.md +10 -10
- package/docs/architecture/source-projection.md +27 -27
- package/docs/architecture.md +19 -15
- package/docs/archive/CHANGELOG-pre-2.11.0.md +2 -2
- package/docs/archive/CHANGELOG-pre-2.15.0.md +3 -3
- package/docs/archive/CHANGELOG-pre-2.16.0.md +1 -1
- package/docs/archive/CHANGELOG-pre-2.2.0.md +70 -70
- package/docs/archive/CHANGELOG-pre-2.20.0.md +2 -2
- package/docs/archive/CHANGELOG-pre-2.25.0.md +15 -15
- package/docs/archive/CHANGELOG-pre-3.0.0.md +4 -4
- package/docs/archive/CHANGELOG-pre-3.1.0.md +2 -2
- package/docs/archive/CHANGELOG-pre-3.2.0.md +3 -3
- package/docs/benchmark.md +65 -0
- package/docs/benchmarks.md +16 -16
- package/docs/catalog.md +17 -15
- package/docs/contracts/CHANGELOG-conventions.md +1 -1
- package/docs/contracts/STABILITY.md +2 -2
- package/docs/contracts/adoption-signal-floor.md +110 -0
- package/docs/contracts/adr-chat-history-split.md +4 -4
- package/docs/contracts/adr-command-suggestion.md +4 -4
- package/docs/contracts/adr-gtm-context-spine.md +1 -1
- package/docs/contracts/adr-implement-ticket-runtime.md +4 -4
- package/docs/contracts/adr-install-user-type-axis.md +1 -1
- package/docs/contracts/adr-layout.md +2 -2
- package/docs/contracts/adr-product-ui-track.md +10 -10
- package/docs/contracts/adr-user-types-axis.md +3 -3
- package/docs/contracts/adr-wing4-context-spine.md +1 -1
- package/docs/contracts/agent-memory-contract.md +3 -3
- package/docs/contracts/agents-md-tech-stack.md +2 -2
- package/docs/contracts/ai-council-config.md +2 -2
- package/docs/contracts/at-rest-encryption.md +4 -0
- package/docs/contracts/audit-log-v1.md +1 -1
- package/docs/contracts/benchmark-ab-contract.md +101 -0
- package/docs/contracts/benchmark-corpus-spec.md +1 -1
- package/docs/contracts/branch-protection-policy.md +98 -0
- package/docs/contracts/ci-cost-budget.md +106 -0
- package/docs/contracts/ci-green-floor.md +141 -0
- package/docs/contracts/command-clusters.md +6 -6
- package/docs/contracts/command-surface-tiers.md +2 -2
- package/docs/contracts/command-taxonomy.md +2 -2
- package/docs/contracts/{compression-default-kill-criterion.md → condensation-default-kill-criterion.md} +29 -29
- package/docs/contracts/config-presets.md +1 -1
- package/docs/contracts/context-paths.md +3 -3
- package/docs/contracts/context-spine.md +1 -1
- package/docs/contracts/cost-summary-schema.md +12 -12
- package/docs/contracts/cross-wing-handoff.md +4 -4
- package/docs/contracts/daily-workspace.md +4 -0
- package/docs/contracts/decision-trace-v1.md +2 -2
- package/docs/contracts/discovery-manifest.md +4 -4
- package/docs/contracts/explain-modes.md +4 -0
- package/docs/contracts/file-ownership-matrix.json +3493 -3318
- package/docs/contracts/file-ownership-matrix.md +3 -3
- package/docs/contracts/frontmatter-contract.md +4 -4
- package/docs/contracts/ghostwriter-schema.md +3 -3
- package/docs/contracts/gui-wizard.md +110 -97
- package/docs/contracts/harness-expectations.md +123 -0
- package/docs/contracts/host-agent-protocol.md +4 -0
- package/docs/contracts/implement-ticket-flow.md +9 -9
- package/docs/contracts/install-scopes.md +77 -0
- package/docs/contracts/iron-law-overrides.txt +1 -1
- package/docs/contracts/kernel-membership.md +26 -26
- package/docs/contracts/linear-ai-rules-inclusion.md +1 -1
- package/docs/contracts/linter-structural-model.md +2 -2
- package/docs/contracts/load-context-budget-model.md +4 -4
- package/docs/contracts/load-context-schema.md +13 -13
- package/docs/contracts/local-analytics.md +4 -0
- package/docs/contracts/local-knowledge-ingestion.md +1 -1
- package/docs/contracts/mcp-cloud-scope.md +2 -2
- package/docs/contracts/mcp-phase-1-scope.md +3 -3
- package/docs/contracts/measurement-baseline.md +5 -5
- package/docs/contracts/mental-models.md +30 -30
- package/docs/contracts/multi-tool-projection-fidelity.md +4 -4
- package/docs/contracts/namespace.md +4 -4
- package/docs/contracts/orchestration-dsl-v1.md +7 -7
- package/docs/contracts/package-self-orientation.md +12 -12
- package/docs/contracts/persona-schema.md +6 -6
- package/docs/contracts/pilot/language-and-tone.md +1 -1
- package/docs/contracts/plain-language-surface.md +117 -0
- package/docs/contracts/profile-system.md +3 -3
- package/docs/contracts/release-pr-gating.md +103 -0
- package/docs/contracts/role-experience.md +3 -3
- package/docs/contracts/rule-classification.md +13 -13
- package/docs/contracts/rule-interactions.md +4 -4
- package/docs/contracts/rule-interactions.yml +30 -30
- package/docs/contracts/rule-priority-hierarchy.md +13 -13
- package/docs/contracts/rule-router.md +2 -2
- package/docs/contracts/safety-model.md +1 -1
- package/docs/contracts/skill-distribution-channels.md +61 -0
- package/docs/contracts/skill-domains.md +2 -2
- package/docs/contracts/smoke-contracts.md +5 -5
- package/docs/contracts/telegraph-telemetry.md +83 -0
- package/docs/contracts/trust-and-safety.md +5 -5
- package/docs/contracts/ui-stack-extension.md +7 -7
- package/docs/contracts/ui-track-flow.md +9 -9
- package/docs/contracts/user-type-schema.md +4 -4
- package/docs/contracts/workflow-packs.md +4 -4
- package/docs/contracts/workspace-documents.md +4 -0
- package/docs/customization.md +28 -8
- package/docs/decisions/ADR-001-kernel-swap-deferred.md +6 -6
- package/docs/decisions/ADR-002-kernel-bucket-overrides.md +11 -11
- package/docs/decisions/ADR-003-flat-cluster-subs-and-colon-syntax.md +2 -2
- package/docs/decisions/ADR-004-rule-governance-pruning.md +4 -4
- package/docs/decisions/ADR-005-subagent-worktrees.md +7 -7
- package/docs/decisions/ADR-011-domain-pack-readiness.md +6 -6
- package/docs/decisions/ADR-013-discovery-frontmatter-contract.md +3 -3
- package/docs/decisions/ADR-015-discovery-manifest-contract.md +3 -3
- package/docs/decisions/ADR-017-monorepo-physical-layout.md +10 -10
- package/docs/decisions/ADR-018-trust-and-safety-layer.md +6 -6
- package/docs/decisions/ADR-019-router-json-dist-location.md +2 -2
- package/docs/decisions/ADR-020-global-only-consumer-scope.md +2 -2
- package/docs/decisions/ADR-021-deployment-shape.md +3 -3
- package/docs/decisions/ADR-022-daily-workspace-decomposition.md +1 -1
- package/docs/decisions/ADR-027-changelog-machine-vs-manual.md +2 -2
- package/docs/decisions/ADR-028-root-layout.md +7 -7
- package/docs/decisions/ADR-029-multi-workspace-deferred.md +2 -2
- package/docs/decisions/ADR-rule-kernel-and-router.md +5 -5
- package/docs/deploy/connector-setup.md +2 -2
- package/docs/deploy/policy-cookbook.md +2 -2
- package/docs/deploy/team-deployment-posture.md +20 -0
- package/docs/development.md +17 -17
- package/docs/distribution/registries.md +32 -0
- package/docs/distribution/registry-submissions.md +85 -0
- package/docs/distribution/telemetry-schema.md +1 -1
- package/docs/getting-started-by-role.md +45 -3
- package/docs/getting-started.md +2 -2
- package/docs/guidelines/agent-infra/5w2h-analysis.md +3 -3
- package/docs/guidelines/agent-infra/ask-when-uncertain-demos.md +1 -1
- package/docs/guidelines/agent-infra/asking-and-brevity-examples.md +3 -3
- package/docs/guidelines/agent-infra/carve-out-predicates.md +3 -3
- package/docs/guidelines/agent-infra/critical-thinking.md +4 -4
- package/docs/guidelines/agent-infra/direct-answers-demos.md +1 -1
- package/docs/guidelines/agent-infra/first-principles.md +2 -2
- package/docs/guidelines/agent-infra/inversion-thinking.md +5 -5
- package/docs/guidelines/agent-infra/layered-settings.md +56 -2
- package/docs/guidelines/agent-infra/mental-models.md +3 -3
- package/docs/guidelines/agent-infra/roadmap-progress-mechanics.md +2 -2
- package/docs/guidelines/agent-infra/rule-type-governance.md +1 -1
- package/docs/guidelines/agent-infra/scqa-framework.md +5 -5
- package/docs/guidelines/agent-infra/self-improvement-pipeline.md +2 -2
- package/docs/guidelines/agent-infra/six-hats.md +3 -3
- package/docs/guidelines/agent-infra/skill-quality-checklist.md +5 -5
- package/docs/guidelines/agent-infra/systems-thinking.md +1 -1
- package/docs/guidelines/agent-infra/verify-before-complete-demos.md +1 -1
- package/docs/guidelines/augment-portability-patterns.md +4 -4
- package/docs/guidelines/cross-role-handoff.md +2 -2
- package/docs/guidelines/php/php-coding-patterns.md +1 -1
- package/docs/guidelines/prompt-templates.md +6 -6
- package/docs/maintainers/dev-mode.md +1 -1
- package/docs/mcp.md +1 -1
- package/docs/parity/bench.json +3 -3
- package/docs/parity/ruflo.md +2 -2
- package/docs/profiles.md +11 -11
- package/docs/quality.md +11 -11
- package/docs/safety.md +3 -3
- package/docs/setup/mcp-client-config.md +1 -1
- package/docs/setup/mcp-r2-bootstrap.md +1 -1
- package/docs/setup/mcp-server-docker.md +3 -3
- package/docs/setup/per-ide/windsurf.md +1 -1
- package/docs/skills-catalog.md +8 -7
- package/docs/troubleshooting.md +1 -1
- package/docs/walkthroughs/daily-workspace-a11y.md +87 -0
- package/llms.txt +7 -6
- package/package.json +1 -1
- package/scripts/__pycache__/validate_frontmatter.cpython-312.pyc +0 -0
- package/scripts/_archive/README.md +2 -2
- package/scripts/_archive/_backfill_skill_domains.py +3 -3
- package/scripts/_archive/_bootstrap_tier_frontmatter.py +3 -3
- package/scripts/_archive/_p43_bodies.py +10 -10
- package/scripts/_archive/{_p43_compress.py → _p43_condense.py} +5 -5
- package/scripts/_archive/_p4_migrate.py +7 -7
- package/scripts/_archive/_phase2_shim_helper.py +1 -1
- package/scripts/_archive/_pilot_council_question.py +5 -5
- package/scripts/_cli/explain_last/inputs.py +1 -1
- package/scripts/_lib/__pycache__/__init__.cpython-312.pyc +0 -0
- package/scripts/_lib/__pycache__/agent_src.cpython-312.pyc +0 -0
- package/scripts/_lib/agent_settings.py +195 -1
- package/scripts/_lib/agent_src.py +19 -19
- package/scripts/_lib/bench_ab_cache.py +162 -0
- package/scripts/_lib/bench_ab_scoring.py +209 -0
- package/scripts/_lib/{bench_caveman.py → bench_telegraph.py} +21 -21
- package/scripts/_lib/{bench_caveman_report.py → bench_telegraph_report.py} +21 -21
- package/scripts/_lib/claude_desktop_bundler.py +5 -5
- package/scripts/_lib/module_detection.py +223 -0
- package/scripts/_lib/scope_guard.sh +162 -0
- package/scripts/_phase4_bucket.py +3 -3
- package/scripts/_pilot_measure.py +4 -4
- package/scripts/_tmp_scan_framework_leakage.py +1 -1
- package/scripts/adoption_report.py +195 -0
- package/scripts/adoption_snapshot.py +219 -0
- package/scripts/adoption_status.py +166 -0
- package/scripts/ai-video/lib/parse-blueprint.sh +1 -1
- package/scripts/ai_council/advisors.py +5 -5
- package/scripts/ai_council/compile_corpus.py +1 -1
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_budget_v2_audit.py +3 -3
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_context_layer_v1_review.py +2 -2
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_inject_quiet_flag.py +1 -1
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_measure_v2.sh +1 -1
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_measure_verbosity.sh +1 -1
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_nondestructive_inline_audit.py +3 -3
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_per_task.sh +1 -1
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_phase6_trigger_jaccard.py +1 -1
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_phase_2a_budget_rebalance.py +6 -6
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_rebalancing_audit.py +1 -1
- package/scripts/ai_council/one_off_archive/2026-05/_one_off_tier_retrofit.py +6 -6
- package/scripts/annotate_discovery.py +13 -13
- package/scripts/apply_modules_config.py +290 -0
- package/scripts/audit_adr_coverage.py +2 -2
- package/scripts/audit_auto_rules.py +2 -2
- package/scripts/audit_cloud_compatibility.py +3 -3
- package/scripts/audit_command_surface.py +9 -9
- package/scripts/audit_likelihood.py +2 -2
- package/scripts/audit_user_type_axis.py +2 -2
- package/scripts/bench_ab_cache_dispatch.py +68 -0
- package/scripts/bench_ab_clone.py +170 -0
- package/scripts/bench_ab_diff.py +227 -0
- package/scripts/bench_ab_integrity.py +143 -0
- package/scripts/bench_ab_run.py +235 -0
- package/scripts/bench_ab_task_runner.py +369 -0
- package/scripts/bench_ab_tracka_run.py +202 -0
- package/scripts/{bench_compress_memory.py → bench_condense_memory.py} +16 -16
- package/scripts/bench_run.py +33 -33
- package/scripts/bench_runner.py +2 -2
- package/scripts/bootstrap.sh +99 -0
- package/scripts/build_cloud_bundle.py +6 -6
- package/scripts/build_discovery_manifest.py +7 -7
- package/scripts/build_linear_digest.py +3 -3
- package/scripts/build_rule_trigger_matrix.py +8 -8
- package/scripts/chat_history.py +5 -5
- package/scripts/check_always_budget.py +11 -5
- package/scripts/check_augment_description_cap.py +3 -3
- package/scripts/check_cluster_patterns.py +2 -2
- package/scripts/check_command_count_messaging.py +3 -3
- package/scripts/{check_compression.py → check_condensation.py} +34 -34
- package/scripts/{check_compressed_paths.py → check_condensed_paths.py} +8 -8
- package/scripts/check_context_paths.py +7 -7
- package/scripts/check_council_layout.py +2 -2
- package/scripts/check_council_references.py +9 -9
- package/scripts/check_iron_law_prominence.py +2 -2
- package/scripts/check_kernel_rule_bundle.py +2 -2
- package/scripts/check_module_management_neutral.py +149 -0
- package/scripts/check_no_roadmap_refs.py +9 -9
- package/scripts/check_portability.py +3 -3
- package/scripts/check_public_catalog_links.py +4 -4
- package/scripts/check_references.py +7 -6
- package/scripts/check_release_pr_shape.py +112 -0
- package/scripts/check_reply_consistency.py +3 -3
- package/scripts/check_safety_floor_untouched.py +1 -1
- package/scripts/check_template_pin_drift.py +5 -5
- package/scripts/check_token_optimizer_freshness.py +3 -3
- package/scripts/ci_status.py +301 -0
- package/scripts/ci_time_ratio.py +1 -1
- package/scripts/cleanup_other_scope.sh +146 -0
- package/scripts/compile_router.py +10 -10
- package/scripts/{compress.py → condense.py} +64 -64
- package/scripts/condense.sh +18 -0
- package/scripts/{compress_memory.py → condense_memory.py} +33 -33
- package/scripts/config/presets.py +2 -2
- package/scripts/config/profiles.py +1 -1
- package/scripts/cost_by_conversation.py +3 -3
- package/scripts/cost_summary.py +7 -7
- package/scripts/count_token_optimizer_usage.sh +1 -1
- package/scripts/gen_discovery_baseline.py +5 -5
- package/scripts/generate_index.py +6 -6
- package/scripts/generate_ownership_matrix.py +10 -10
- package/scripts/generate_pack_manifests.py +1 -1
- package/scripts/ghostwriter_fixture_allowlist.txt +1 -1
- package/scripts/install +3 -3
- package/scripts/install-hooks.sh +6 -6
- package/scripts/install.py +273 -45
- package/scripts/install.sh +187 -1
- package/scripts/inventory_frontmatter.py +2 -2
- package/scripts/iron_law_sha.py +3 -3
- package/scripts/lint_agents_layout.py +14 -7
- package/scripts/lint_agents_md.py +4 -4
- package/scripts/lint_archived_skills.py +3 -3
- package/scripts/lint_artefact_frontmatter.py +2 -2
- package/scripts/lint_bench_ab.py +172 -0
- package/scripts/lint_bench_corpus.py +1 -1
- package/scripts/lint_command_tiers.py +5 -5
- package/scripts/lint_context_spine_usage.py +1 -1
- package/scripts/lint_framework_leakage.py +7 -7
- package/scripts/lint_framework_leakage_allowlist.json +152 -84
- package/scripts/lint_ghostwriter_source.py +3 -3
- package/scripts/lint_handoffs.py +1 -1
- package/scripts/lint_load_context.py +11 -11
- package/scripts/lint_media_policy_linkage.py +5 -5
- package/scripts/lint_namespace.py +1 -1
- package/scripts/lint_no_new_atomic_commands.py +2 -2
- package/scripts/lint_orchestration_dsl.py +1 -1
- package/scripts/lint_pack_boundaries.py +2 -2
- package/scripts/lint_persona_governance.py +4 -4
- package/scripts/lint_role_experiences.py +237 -0
- package/scripts/lint_rule_interactions.py +2 -2
- package/scripts/lint_rule_tiers.py +1 -1
- package/scripts/lint_trust_coherence.py +2 -2
- package/scripts/mcp_registry_submit.sh +187 -0
- package/scripts/mcp_server/tools.py +1 -1
- package/scripts/measure_frugality_savings.py +10 -10
- package/scripts/measure_patterns.py +1 -1
- package/scripts/measure_projection_bytes.py +5 -5
- package/scripts/measure_rule_budget.py +3 -3
- package/scripts/measure_skill_reduction.py +1 -1
- package/scripts/memory_lookup.py +1 -1
- package/scripts/memory_status.py +2 -2
- package/scripts/migrate_command_suggestions.py +3 -3
- package/scripts/mine_session.py +1 -1
- package/scripts/move_artefact.py +3 -3
- package/scripts/new_skill.py +2 -2
- package/scripts/pack_mcp_content.py +9 -9
- package/scripts/plan_physical_move.py +6 -6
- package/scripts/print_required_checks.py +196 -0
- package/scripts/probe_skill_registration.py +413 -0
- package/scripts/propose_modules_config.py +145 -0
- package/scripts/prototype_lint_contradictions.py +1 -1
- package/scripts/recruit_preflight.sh +152 -0
- package/scripts/refine_ticket_detect.py +3 -3
- package/scripts/release.py +20 -0
- package/scripts/render_benchmark_md.py +308 -0
- package/scripts/roadmap_progress_hook.py +1 -1
- package/scripts/run_skill_evals.py +2 -2
- package/scripts/runtime_registry.py +4 -4
- package/scripts/schemas/command.schema.json +4 -4
- package/scripts/schemas/rule.schema.json +5 -5
- package/scripts/schemas/skill.schema.json +3 -3
- package/scripts/schemas/user-type.schema.json +1 -1
- package/scripts/score_skill_selection.py +1 -1
- package/scripts/skill_collision_clusters.py +2 -2
- package/scripts/skill_linter.py +81 -81
- package/scripts/skill_overlap.py +5 -5
- package/scripts/skill_tools/audit_persona_coverage.py +2 -2
- package/scripts/skill_tools/audit_user_type_coverage.py +2 -2
- package/scripts/skill_tools/run_block_d_eval.py +1 -1
- package/scripts/skill_tools/score_skill_relevance.py +1 -1
- package/scripts/skill_tools/suggest_skill_for_task.py +1 -1
- package/scripts/skill_trigger_eval.py +3 -3
- package/scripts/smoke/kernel.sh +7 -1
- package/scripts/smoke/router.sh +5 -5
- package/scripts/smoke/skills.sh +1 -1
- package/scripts/smoke_quickstart.py +1 -1
- package/scripts/snapshot_agent_outputs.py +3 -3
- package/scripts/spotcheck_thin_root.py +1 -1
- package/scripts/{caveman_stats.py → telegraph_stats.py} +18 -18
- package/scripts/update_counts.py +1 -1
- package/scripts/validate_decision_engine.py +1 -1
- package/scripts/validate_frontmatter.py +1 -1
- package/scripts/validate_safe_paths.py +3 -3
- package/scripts/{validate_caveman_carveouts.py → validate_telegraph_carveouts.py} +7 -7
- package/scripts/verify_roadmap_closure.py +6 -6
- package/templates/consumer-settings/ONBOARDING.md +41 -0
- package/.agent-src/commands/install-via-agent.md +0 -129
- package/.agent-src/skills/compress-memory/SKILL.md +0 -131
- package/dist/ui/assets/index-D-DY1ywI.js +0 -35
- package/dist/ui/assets/index-D-DY1ywI.js.map +0 -1
- package/dist/ui/assets/index-Dqfhmg-d.css +0 -1
- package/docs/adrs/caveman/README.md +0 -9
- package/docs/contracts/caveman-telemetry.md +0 -83
- package/scripts/compress.sh +0 -18
|
@@ -18,10 +18,10 @@ const LEGACY_USER_MD_REL = '.agent-user.md';
|
|
|
18
18
|
const LEGACY_SETTINGS_REL = '.agent-settings.yml';
|
|
19
19
|
// Step count mirrors the UI's `WIZARD_STEPS` array in `src/ui/wizard/steps.ts`
|
|
20
20
|
// and the chat-side `~/.claude/skills/onboard/SKILL.md`. Bump in lockstep.
|
|
21
|
-
// Extended mode (road-to-global-only-install § Phase 1) prepends
|
|
22
|
-
// steps (ai-tools + packs) to ship the unified
|
|
21
|
+
// Extended mode (road-to-global-only-install § Phase 1) prepends three
|
|
22
|
+
// steps (ai-tools + packs + modules) to ship the unified 10-step flow.
|
|
23
23
|
const DEFAULT_TOTAL_STEPS = 7;
|
|
24
|
-
const EXTENDED_TOTAL_STEPS =
|
|
24
|
+
const EXTENDED_TOTAL_STEPS = 10;
|
|
25
25
|
/**
|
|
26
26
|
* Discovery-manifest path. Resolved from the package root the server
|
|
27
27
|
* was booted with — same artefact the installer reads (ADR-015 locks
|
|
@@ -35,7 +35,7 @@ const wizardStateSchema = z.object({
|
|
|
35
35
|
startedAt: z.string().nullable().default(null),
|
|
36
36
|
});
|
|
37
37
|
// road-to-global-only-install § Phase 1.5 — WizardApplyPayload shape.
|
|
38
|
-
// Mirrors `schemas/wizard-apply-payload.schema.json`; the discriminator
|
|
38
|
+
// Mirrors `internal/schemas/wizard-apply-payload.schema.json`; the discriminator
|
|
39
39
|
// (`schema_version`) selects the variant. Real schema validation lives
|
|
40
40
|
// in install.py — the route only enforces the outer envelope so the
|
|
41
41
|
// bridge spawn surface stays tight.
|
|
@@ -149,9 +149,136 @@ async function spawnInstaller(scriptPath, args) {
|
|
|
149
149
|
});
|
|
150
150
|
});
|
|
151
151
|
}
|
|
152
|
+
/** SSE frame writer — one event per `data:` line, blank-line terminator. */
|
|
153
|
+
function writeFrame(reply, payload) {
|
|
154
|
+
reply.raw.write(`data: ${JSON.stringify(payload)}\n\n`);
|
|
155
|
+
}
|
|
156
|
+
function streamInstaller(scriptPath, args, onLine, signal) {
|
|
157
|
+
return new Promise((resolve, reject) => {
|
|
158
|
+
const child = spawn('python3', [scriptPath, ...args], {
|
|
159
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
160
|
+
env: { ...process.env, AGENT_CONFIG_NO_UPDATE_CHECK: '1' },
|
|
161
|
+
});
|
|
162
|
+
const onAbort = () => {
|
|
163
|
+
child.kill('SIGTERM');
|
|
164
|
+
};
|
|
165
|
+
if (signal !== undefined) {
|
|
166
|
+
if (signal.aborted)
|
|
167
|
+
onAbort();
|
|
168
|
+
else
|
|
169
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
170
|
+
}
|
|
171
|
+
const stderrChunks = [];
|
|
172
|
+
let buf = '';
|
|
173
|
+
const handleLine = (line) => {
|
|
174
|
+
const trimmed = line.trim();
|
|
175
|
+
if (trimmed.length === 0)
|
|
176
|
+
return;
|
|
177
|
+
try {
|
|
178
|
+
onLine(JSON.parse(trimmed));
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
// Non-JSON stdout (defensive — real-apply runs with QUIET so
|
|
182
|
+
// only NDJSON reaches stdout). Drop it rather than corrupt the
|
|
183
|
+
// SSE stream.
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
child.stdout?.on('data', (chunk) => {
|
|
187
|
+
buf += chunk.toString('utf8');
|
|
188
|
+
let nl = buf.indexOf('\n');
|
|
189
|
+
while (nl !== -1) {
|
|
190
|
+
handleLine(buf.slice(0, nl));
|
|
191
|
+
buf = buf.slice(nl + 1);
|
|
192
|
+
nl = buf.indexOf('\n');
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
child.stderr?.on('data', (chunk) => stderrChunks.push(chunk));
|
|
196
|
+
child.once('error', (err) => {
|
|
197
|
+
if (signal !== undefined)
|
|
198
|
+
signal.removeEventListener('abort', onAbort);
|
|
199
|
+
reject(err);
|
|
200
|
+
});
|
|
201
|
+
child.once('close', (code) => {
|
|
202
|
+
if (buf.trim().length > 0)
|
|
203
|
+
handleLine(buf);
|
|
204
|
+
if (signal !== undefined)
|
|
205
|
+
signal.removeEventListener('abort', onAbort);
|
|
206
|
+
resolve({ exitCode: code ?? 1, stderr: Buffer.concat(stderrChunks).toString('utf8') });
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
async function spawnBash(scriptPath, args) {
|
|
211
|
+
return new Promise((resolve, reject) => {
|
|
212
|
+
const child = spawn('bash', [scriptPath, ...args], {
|
|
213
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
214
|
+
env: { ...process.env, AGENT_CONFIG_NO_UPDATE_CHECK: '1' },
|
|
215
|
+
});
|
|
216
|
+
const stdoutChunks = [];
|
|
217
|
+
const stderrChunks = [];
|
|
218
|
+
child.stdout?.on('data', (chunk) => stdoutChunks.push(chunk));
|
|
219
|
+
child.stderr?.on('data', (chunk) => stderrChunks.push(chunk));
|
|
220
|
+
child.once('error', reject);
|
|
221
|
+
child.once('close', (code) => {
|
|
222
|
+
resolve({
|
|
223
|
+
exitCode: code ?? 1,
|
|
224
|
+
stdout: Buffer.concat(stdoutChunks).toString('utf8'),
|
|
225
|
+
stderr: Buffer.concat(stderrChunks).toString('utf8'),
|
|
226
|
+
});
|
|
227
|
+
});
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
function parseScopeGuardOutput(stdout) {
|
|
231
|
+
const findings = [];
|
|
232
|
+
let overall = 'OK';
|
|
233
|
+
let countOk = 0;
|
|
234
|
+
let countWarn = 0;
|
|
235
|
+
let countDrift = 0;
|
|
236
|
+
for (const line of stdout.split('\n')) {
|
|
237
|
+
if (!line.trim())
|
|
238
|
+
continue;
|
|
239
|
+
const parts = line.split('\t');
|
|
240
|
+
if (parts[0] === 'SUMMARY') {
|
|
241
|
+
overall = parts[1] ?? 'OK';
|
|
242
|
+
countOk = Number.parseInt(parts[2] ?? '0', 10);
|
|
243
|
+
countWarn = Number.parseInt(parts[3] ?? '0', 10);
|
|
244
|
+
countDrift = Number.parseInt(parts[4] ?? '0', 10);
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
const [verdict, tool, otherScopePath, otherVersion, thisVersion] = parts;
|
|
248
|
+
if (verdict !== 'OK' && verdict !== 'WARN' && verdict !== 'DRIFT')
|
|
249
|
+
continue;
|
|
250
|
+
findings.push({
|
|
251
|
+
verdict: verdict,
|
|
252
|
+
tool: tool ?? '?',
|
|
253
|
+
otherScopePath: otherScopePath ?? '-',
|
|
254
|
+
otherVersion: otherVersion ?? '-',
|
|
255
|
+
thisVersion: thisVersion ?? '-',
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
return { overall, countOk, countWarn, countDrift, findings };
|
|
259
|
+
}
|
|
260
|
+
// road-to-configurable-modules § Phase E — wire shape of the
|
|
261
|
+
// `modulesConfig` field on `POST /api/v1/wizard/finish`. Matches the
|
|
262
|
+
// `proposed_block` JSON emitted by `propose_modules_config.py --json`
|
|
263
|
+
// so the wizard can round-trip the detection output untouched. Extra
|
|
264
|
+
// fields are rejected — the persistence helper has its own coercion
|
|
265
|
+
// for older payload shapes, but the wizard always sends the strict
|
|
266
|
+
// shape.
|
|
267
|
+
const modulesConfigSchema = z.object({
|
|
268
|
+
enabled: z.boolean(),
|
|
269
|
+
root_paths: z.array(z.string()),
|
|
270
|
+
namespace_template: z.string().optional(),
|
|
271
|
+
agent_folder: z.string().optional(),
|
|
272
|
+
skip_dirs: z.array(z.string()).optional(),
|
|
273
|
+
}).strict();
|
|
152
274
|
export function wizardRoute(opts) {
|
|
153
275
|
const extended = opts.extendedSteps === true;
|
|
154
276
|
const totalSteps = opts.totalSteps ?? (extended ? EXTENDED_TOTAL_STEPS : DEFAULT_TOTAL_STEPS);
|
|
277
|
+
// Clamp the CLI-provided initial step to the active step range so a
|
|
278
|
+
// stale `--initial-step=99` cannot shove the UI past the last screen.
|
|
279
|
+
const rawInitial = opts.initialStep ?? 0;
|
|
280
|
+
const initialStep = Math.max(0, Math.min(totalSteps - 1, Math.trunc(rawInitial)));
|
|
281
|
+
const wizardMode = opts.wizardMode ?? null;
|
|
155
282
|
const dryRun = opts.dryRun === true;
|
|
156
283
|
const legacyReadRoot = opts.legacyReadRoot ?? null;
|
|
157
284
|
const projectScopeRoot = opts.projectScopeRoot ?? null;
|
|
@@ -166,9 +293,21 @@ export function wizardRoute(opts) {
|
|
|
166
293
|
// in-progress real run can be previewed.
|
|
167
294
|
const existing = dryRun ? (memState ?? await readState(opts.writeRoot)) : await readState(opts.writeRoot);
|
|
168
295
|
if (existing === null) {
|
|
169
|
-
return {
|
|
296
|
+
return {
|
|
297
|
+
step: initialStep,
|
|
298
|
+
totalSteps,
|
|
299
|
+
partial: {},
|
|
300
|
+
startedAt: null,
|
|
301
|
+
extendedSteps: extended,
|
|
302
|
+
wizardMode,
|
|
303
|
+
};
|
|
170
304
|
}
|
|
171
|
-
return {
|
|
305
|
+
return {
|
|
306
|
+
...existing,
|
|
307
|
+
totalSteps: existing.totalSteps ?? totalSteps,
|
|
308
|
+
extendedSteps: extended,
|
|
309
|
+
wizardMode,
|
|
310
|
+
};
|
|
172
311
|
});
|
|
173
312
|
// road-to-global-only-install § Phase 1.2 — Auto-detect endpoint.
|
|
174
313
|
// Reads package signals from the maintainer's CWD (the consumer
|
|
@@ -183,6 +322,44 @@ export function wizardRoute(opts) {
|
|
|
183
322
|
const signals = detectProjectSignals(root);
|
|
184
323
|
return { root, signals };
|
|
185
324
|
});
|
|
325
|
+
// road-to-configurable-modules § Phase E — Modules detect endpoint.
|
|
326
|
+
// Read-only scan: spawns `scripts/propose_modules_config.py --json`
|
|
327
|
+
// against the consumer project so the wizard's modules step can
|
|
328
|
+
// surface candidate root_paths + a prefilled `modules:` block.
|
|
329
|
+
// Same root-resolution rule as `/auto-detect` (legacyReadRoot ??
|
|
330
|
+
// cwd) — the consumer repo the maintainer is running the wizard
|
|
331
|
+
// against. Gated by extended-mode so the canonical 7-step flow
|
|
332
|
+
// stays clean.
|
|
333
|
+
app.get('/api/v1/modules/detect', async (_request, reply) => {
|
|
334
|
+
if (!extended) {
|
|
335
|
+
await reply.code(404).send({ error: { code: 'NOT_FOUND', message: 'extended-mode endpoint disabled' } });
|
|
336
|
+
return reply;
|
|
337
|
+
}
|
|
338
|
+
const root = legacyReadRoot ?? process.cwd();
|
|
339
|
+
const scriptPath = join(opts.packageRoot, 'scripts', 'propose_modules_config.py');
|
|
340
|
+
try {
|
|
341
|
+
const result = await spawnInstaller(scriptPath, ['--json', '--project', root]);
|
|
342
|
+
if (result.exitCode !== 0) {
|
|
343
|
+
await reply.code(500).send({
|
|
344
|
+
error: { code: 'DETECT_FAILED', message: result.stderr || 'module detect bridge exited non-zero', exitCode: result.exitCode },
|
|
345
|
+
});
|
|
346
|
+
return reply;
|
|
347
|
+
}
|
|
348
|
+
try {
|
|
349
|
+
return JSON.parse(result.stdout);
|
|
350
|
+
}
|
|
351
|
+
catch (err) {
|
|
352
|
+
const message = err instanceof Error ? err.message : 'invalid JSON from module detect bridge';
|
|
353
|
+
await reply.code(500).send({ error: { code: 'DETECT_PARSE_FAILED', message } });
|
|
354
|
+
return reply;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
catch (err) {
|
|
358
|
+
const message = err instanceof Error ? err.message : 'module detect bridge failed';
|
|
359
|
+
await reply.code(500).send({ error: { code: 'DETECT_FAILED', message } });
|
|
360
|
+
return reply;
|
|
361
|
+
}
|
|
362
|
+
});
|
|
186
363
|
// road-to-global-only-install § Phase 1.3 — Manifest endpoint.
|
|
187
364
|
// Surfaces the locked discovery-manifest (ADR-015) so the UI can
|
|
188
365
|
// render the supported AI IDs + every pack the manifest exposes.
|
|
@@ -202,6 +379,123 @@ export function wizardRoute(opts) {
|
|
|
202
379
|
return reply;
|
|
203
380
|
}
|
|
204
381
|
});
|
|
382
|
+
// road-to-clean-skill-distribution-channels § Phase D Step 3 —
|
|
383
|
+
// harness-expectations endpoint. Returns the three classes the
|
|
384
|
+
// wizard's final review step renders after install completes.
|
|
385
|
+
// Content is static + sourced from docs/contracts/harness-expectations.md
|
|
386
|
+
// (the doc is the long form; this endpoint is the wizard-shaped
|
|
387
|
+
// short form so the UI does not have to parse markdown).
|
|
388
|
+
app.get('/api/v1/wizard/harness-expectations', async (_request, reply) => {
|
|
389
|
+
if (!extended) {
|
|
390
|
+
await reply.code(404).send({ error: { code: 'NOT_FOUND', message: 'extended-mode endpoint disabled' } });
|
|
391
|
+
return reply;
|
|
392
|
+
}
|
|
393
|
+
return {
|
|
394
|
+
contractPath: 'docs/contracts/harness-expectations.md',
|
|
395
|
+
classes: [
|
|
396
|
+
{
|
|
397
|
+
id: 'sibling-plugins',
|
|
398
|
+
title: 'Plugin-namespaced peer skills',
|
|
399
|
+
symptom: 'Skills appear under namespaces like codex:* or cc-gemini-plugin:*.',
|
|
400
|
+
cause: 'Sibling AI-tool plugins loaded by the harness; not owned by this package.',
|
|
401
|
+
action: 'Use the harness’s plugin-list command to identify the source.',
|
|
402
|
+
},
|
|
403
|
+
{
|
|
404
|
+
id: 'deferred-tools',
|
|
405
|
+
title: 'Tools deferred behind ToolSearch',
|
|
406
|
+
symptom: 'system-reminder mentions “deferred tools … available via ToolSearch”.',
|
|
407
|
+
cause: 'Harness defers schema load until needed to protect context budget.',
|
|
408
|
+
action: 'Run ToolSearch with select:<name> to load the schema before calling.',
|
|
409
|
+
},
|
|
410
|
+
{
|
|
411
|
+
id: 'duplicate-registration',
|
|
412
|
+
title: 'Duplicate skill registration',
|
|
413
|
+
symptom: 'Same skill name appears twice in the available-skills list.',
|
|
414
|
+
cause: 'Cross-scope install drift (~/.claude/skills/ + ./.claude/skills/ at different versions).',
|
|
415
|
+
action: 'Run `task probe:skills` — if findings show DUPLICATE/DRIFT, clean with `bash scripts/cleanup_other_scope.sh --confirm`.',
|
|
416
|
+
},
|
|
417
|
+
],
|
|
418
|
+
triage: [
|
|
419
|
+
'Run `task probe:skills` first — confirms or rules out class 3.',
|
|
420
|
+
'If a vendor: prefix shows, check the harness’s plugin list.',
|
|
421
|
+
'deferred-tools reminder = expected; the skill must call ToolSearch.',
|
|
422
|
+
],
|
|
423
|
+
};
|
|
424
|
+
});
|
|
425
|
+
// road-to-clean-skill-distribution-channels § Phase C Step 6 —
|
|
426
|
+
// probe endpoint. Spawns scripts/probe_skill_registration.py with
|
|
427
|
+
// --format=json so the wizard's final step can surface DUPLICATE /
|
|
428
|
+
// DRIFT findings before the operator closes the install. Read-only.
|
|
429
|
+
app.get('/api/v1/wizard/probe', async (_request, reply) => {
|
|
430
|
+
if (!extended) {
|
|
431
|
+
await reply.code(404).send({ error: { code: 'NOT_FOUND', message: 'extended-mode endpoint disabled' } });
|
|
432
|
+
return reply;
|
|
433
|
+
}
|
|
434
|
+
const probePath = join(opts.packageRoot, 'scripts', 'probe_skill_registration.py');
|
|
435
|
+
if (!existsSync(probePath)) {
|
|
436
|
+
await reply.code(500).send({ error: { code: 'PROBE_MISSING', message: `probe script not found at ${probePath}` } });
|
|
437
|
+
return reply;
|
|
438
|
+
}
|
|
439
|
+
const projectRoot = legacyReadRoot ?? process.cwd();
|
|
440
|
+
try {
|
|
441
|
+
const result = await spawnInstaller(probePath, ['--project', projectRoot, '--format=json']);
|
|
442
|
+
// Default mode exits 0 regardless of findings; --strict (not
|
|
443
|
+
// passed here) is the only path with a non-zero exit.
|
|
444
|
+
if (result.exitCode !== 0) {
|
|
445
|
+
await reply.code(500).send({
|
|
446
|
+
error: { code: 'PROBE_FAILED', message: result.stderr || `probe exited ${result.exitCode}`, exitCode: result.exitCode },
|
|
447
|
+
});
|
|
448
|
+
return reply;
|
|
449
|
+
}
|
|
450
|
+
try {
|
|
451
|
+
return JSON.parse(result.stdout);
|
|
452
|
+
}
|
|
453
|
+
catch (err) {
|
|
454
|
+
const message = err instanceof Error ? err.message : 'invalid JSON from probe';
|
|
455
|
+
await reply.code(500).send({ error: { code: 'PROBE_PARSE_FAILED', message } });
|
|
456
|
+
return reply;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
catch (err) {
|
|
460
|
+
const message = err instanceof Error ? err.message : 'probe failed to spawn';
|
|
461
|
+
await reply.code(500).send({ error: { code: 'PROBE_FAILED', message } });
|
|
462
|
+
return reply;
|
|
463
|
+
}
|
|
464
|
+
});
|
|
465
|
+
// road-to-clean-skill-distribution-channels § Phase B Step 4 —
|
|
466
|
+
// scope-guard endpoint. Spawns scripts/_lib/scope_guard.sh against
|
|
467
|
+
// the target project root and the user's $HOME, returns a
|
|
468
|
+
// structured verdict the wizard's first step renders before the
|
|
469
|
+
// operator picks an install scope. Read-only — no file writes.
|
|
470
|
+
app.get('/api/v1/wizard/scope-guard', async (_request, reply) => {
|
|
471
|
+
if (!extended) {
|
|
472
|
+
await reply.code(404).send({ error: { code: 'NOT_FOUND', message: 'extended-mode endpoint disabled' } });
|
|
473
|
+
return reply;
|
|
474
|
+
}
|
|
475
|
+
const guardPath = join(opts.packageRoot, 'scripts', '_lib', 'scope_guard.sh');
|
|
476
|
+
if (!existsSync(guardPath)) {
|
|
477
|
+
await reply.code(500).send({ error: { code: 'GUARD_MISSING', message: `scope_guard.sh not found at ${guardPath}` } });
|
|
478
|
+
return reply;
|
|
479
|
+
}
|
|
480
|
+
const projectRoot = legacyReadRoot ?? process.cwd();
|
|
481
|
+
try {
|
|
482
|
+
const result = await spawnBash(guardPath, ['project', opts.packageRoot, projectRoot]);
|
|
483
|
+
// The script always exits 0; we still pass through stderr
|
|
484
|
+
// on a non-zero so the UI can surface platform issues.
|
|
485
|
+
if (result.exitCode !== 0) {
|
|
486
|
+
await reply.code(500).send({
|
|
487
|
+
error: { code: 'GUARD_FAILED', message: result.stderr || `scope_guard.sh exited ${result.exitCode}`, exitCode: result.exitCode },
|
|
488
|
+
});
|
|
489
|
+
return reply;
|
|
490
|
+
}
|
|
491
|
+
return parseScopeGuardOutput(result.stdout);
|
|
492
|
+
}
|
|
493
|
+
catch (err) {
|
|
494
|
+
const message = err instanceof Error ? err.message : 'scope_guard.sh failed to spawn';
|
|
495
|
+
await reply.code(500).send({ error: { code: 'GUARD_FAILED', message } });
|
|
496
|
+
return reply;
|
|
497
|
+
}
|
|
498
|
+
});
|
|
205
499
|
app.post('/api/v1/wizard/state', async (request, reply) => {
|
|
206
500
|
const body = (request.body ?? {});
|
|
207
501
|
const parsed = wizardStateSchema.safeParse({
|
|
@@ -223,13 +517,17 @@ export function wizardRoute(opts) {
|
|
|
223
517
|
await writeState(opts.writeRoot, parsed.data);
|
|
224
518
|
return { ok: true };
|
|
225
519
|
});
|
|
226
|
-
// road-to-
|
|
227
|
-
// Validates the WizardApplyPayload envelope
|
|
228
|
-
//
|
|
229
|
-
//
|
|
230
|
-
//
|
|
231
|
-
//
|
|
232
|
-
//
|
|
520
|
+
// road-to-single-install-source-of-truth § Phase 2 — Wizard Apply bridge.
|
|
521
|
+
// Validates the WizardApplyPayload envelope and spills it to a temp file,
|
|
522
|
+
// then dispatches `scripts/install.py --apply-payload <tmp>` — the single
|
|
523
|
+
// installer (D12 / ADR-020). Two modes on the SAME endpoint:
|
|
524
|
+
// • dry_run:true → buffered plan-summary preview (JSON), used by the
|
|
525
|
+
// Review step. Adds `--dry-run`.
|
|
526
|
+
// • dry_run:false → REAL apply, streamed as SSE. install.py emits NDJSON
|
|
527
|
+
// (`{type:"file"|"done"|"error"}`); we map each line to the SSE frame
|
|
528
|
+
// vocabulary the UI consumes (`progress`/`done`/`error`) and abort the
|
|
529
|
+
// child on client disconnect (Finding #24). CSRF + Host/Origin
|
|
530
|
+
// allow-list are enforced by the app-level onRequest hooks.
|
|
233
531
|
app.post('/api/v1/wizard/apply', async (request, reply) => {
|
|
234
532
|
if (!extended) {
|
|
235
533
|
await reply.code(404).send({ error: { code: 'NOT_FOUND', message: 'extended-mode endpoint disabled' } });
|
|
@@ -242,35 +540,114 @@ export function wizardRoute(opts) {
|
|
|
242
540
|
});
|
|
243
541
|
return reply;
|
|
244
542
|
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
const payload = { ...parsed.data, dry_run: true };
|
|
543
|
+
const isDryRun = parsed.data.dry_run === true;
|
|
544
|
+
const payload = parsed.data;
|
|
248
545
|
const tmpPath = join(tmpdir(), `agent-config-apply-${randomBytes(8).toString('hex')}.json`);
|
|
546
|
+
const scriptPath = join(opts.packageRoot, 'scripts', 'install.py');
|
|
547
|
+
if (isDryRun) {
|
|
548
|
+
// Plan-summary preview — buffered JSON (Review step).
|
|
549
|
+
try {
|
|
550
|
+
await fs.writeFile(tmpPath, JSON.stringify(payload), { mode: 0o600 });
|
|
551
|
+
const result = await spawnInstaller(scriptPath, ['--apply-payload', tmpPath, '--dry-run']);
|
|
552
|
+
if (result.exitCode !== 0) {
|
|
553
|
+
await reply.code(500).send({
|
|
554
|
+
error: { code: 'BRIDGE_FAILED', message: result.stderr || 'installer bridge exited non-zero', exitCode: result.exitCode },
|
|
555
|
+
});
|
|
556
|
+
return reply;
|
|
557
|
+
}
|
|
558
|
+
return {
|
|
559
|
+
ok: true,
|
|
560
|
+
dryRun: true,
|
|
561
|
+
schemaVersion: payload.schema_version,
|
|
562
|
+
preview: result.stdout,
|
|
563
|
+
};
|
|
564
|
+
}
|
|
565
|
+
catch (err) {
|
|
566
|
+
const message = err instanceof Error ? err.message : 'apply bridge failed';
|
|
567
|
+
await reply.code(500).send({ error: { code: 'BRIDGE_FAILED', message } });
|
|
568
|
+
return reply;
|
|
569
|
+
}
|
|
570
|
+
finally {
|
|
571
|
+
await fs.unlink(tmpPath).catch(() => undefined);
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
// Real apply — SSE stream. Flush headers so the browser opens the
|
|
575
|
+
// channel immediately.
|
|
576
|
+
reply.raw.writeHead(200, {
|
|
577
|
+
'Content-Type': 'text/event-stream',
|
|
578
|
+
'Cache-Control': 'no-cache, no-transform',
|
|
579
|
+
Connection: 'keep-alive',
|
|
580
|
+
'X-Accel-Buffering': 'no',
|
|
581
|
+
});
|
|
582
|
+
reply.raw.flushHeaders?.();
|
|
583
|
+
const controller = new AbortController();
|
|
584
|
+
const onClose = () => {
|
|
585
|
+
if (!reply.raw.writableEnded)
|
|
586
|
+
controller.abort();
|
|
587
|
+
};
|
|
588
|
+
reply.raw.on('close', onClose);
|
|
589
|
+
let written = 0;
|
|
590
|
+
let total = 0;
|
|
591
|
+
let sawTerminal = false;
|
|
249
592
|
try {
|
|
250
593
|
await fs.writeFile(tmpPath, JSON.stringify(payload), { mode: 0o600 });
|
|
251
|
-
const
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
594
|
+
const result = await streamInstaller(scriptPath, ['--apply-payload', tmpPath], (obj) => {
|
|
595
|
+
const t = obj.type;
|
|
596
|
+
if (t === 'file') {
|
|
597
|
+
written = typeof obj.written === 'number' ? obj.written : written;
|
|
598
|
+
total = typeof obj.total === 'number' ? obj.total : total;
|
|
599
|
+
writeFrame(reply, {
|
|
600
|
+
type: 'progress',
|
|
601
|
+
file: obj.file,
|
|
602
|
+
status: obj.status,
|
|
603
|
+
written,
|
|
604
|
+
total,
|
|
605
|
+
});
|
|
606
|
+
}
|
|
607
|
+
else if (t === 'done') {
|
|
608
|
+
sawTerminal = true;
|
|
609
|
+
writeFrame(reply, { type: 'done', summary: { written, total } });
|
|
610
|
+
}
|
|
611
|
+
else if (t === 'error') {
|
|
612
|
+
sawTerminal = true;
|
|
613
|
+
writeFrame(reply, {
|
|
614
|
+
type: 'error',
|
|
615
|
+
code: typeof obj.code === 'string' ? obj.code : 'E_INSTALL',
|
|
616
|
+
message: typeof obj.message === 'string' ? obj.message : 'install failed',
|
|
617
|
+
recoverable: false,
|
|
618
|
+
});
|
|
619
|
+
}
|
|
620
|
+
}, controller.signal);
|
|
621
|
+
// install.py exited without a terminal frame (crash / kill): emit
|
|
622
|
+
// one so the UI never hangs waiting for `done`/`error`.
|
|
623
|
+
if (!sawTerminal) {
|
|
624
|
+
if (result.exitCode === 0) {
|
|
625
|
+
writeFrame(reply, { type: 'done', summary: { written, total } });
|
|
626
|
+
}
|
|
627
|
+
else {
|
|
628
|
+
writeFrame(reply, {
|
|
629
|
+
type: 'error',
|
|
630
|
+
code: 'BRIDGE_FAILED',
|
|
631
|
+
message: result.stderr.trim() || `installer exited ${result.exitCode}`,
|
|
632
|
+
recoverable: false,
|
|
633
|
+
});
|
|
634
|
+
}
|
|
258
635
|
}
|
|
259
|
-
return {
|
|
260
|
-
ok: true,
|
|
261
|
-
dryRun: true,
|
|
262
|
-
schemaVersion: payload.schema_version,
|
|
263
|
-
preview: result.stdout,
|
|
264
|
-
};
|
|
265
636
|
}
|
|
266
637
|
catch (err) {
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
638
|
+
writeFrame(reply, {
|
|
639
|
+
type: 'error',
|
|
640
|
+
code: 'E_CRASH',
|
|
641
|
+
message: err instanceof Error ? err.message : String(err),
|
|
642
|
+
recoverable: false,
|
|
643
|
+
});
|
|
270
644
|
}
|
|
271
645
|
finally {
|
|
646
|
+
reply.raw.off('close', onClose);
|
|
647
|
+
reply.raw.end();
|
|
272
648
|
await fs.unlink(tmpPath).catch(() => undefined);
|
|
273
649
|
}
|
|
650
|
+
return reply;
|
|
274
651
|
});
|
|
275
652
|
app.post('/api/v1/wizard/finish', async (request, reply) => {
|
|
276
653
|
const body = (request.body ?? {});
|
|
@@ -293,6 +670,28 @@ export function wizardRoute(opts) {
|
|
|
293
670
|
});
|
|
294
671
|
return reply;
|
|
295
672
|
}
|
|
673
|
+
// road-to-configurable-modules § Phase E — parse the modules
|
|
674
|
+
// payload. Extended-mode only; legacy 7-step flow never sends
|
|
675
|
+
// this field. Omitted / null → skip persistence (the team
|
|
676
|
+
// file stays untouched).
|
|
677
|
+
const rawModulesConfig = body.modulesConfig;
|
|
678
|
+
let modulesConfigData = null;
|
|
679
|
+
if (rawModulesConfig !== undefined && rawModulesConfig !== null) {
|
|
680
|
+
if (!extended) {
|
|
681
|
+
await reply.code(422).send({
|
|
682
|
+
error: { code: 'VALIDATION', message: 'modulesConfig requires extended mode', fields: [{ path: 'modulesConfig', message: 'extended-mode only' }] },
|
|
683
|
+
});
|
|
684
|
+
return reply;
|
|
685
|
+
}
|
|
686
|
+
const modulesParsed = modulesConfigSchema.safeParse(rawModulesConfig);
|
|
687
|
+
if (!modulesParsed.success) {
|
|
688
|
+
await reply.code(422).send({
|
|
689
|
+
error: { code: 'VALIDATION', message: 'invalid modulesConfig', fields: zodIssuesToFields(modulesParsed.error.issues) },
|
|
690
|
+
});
|
|
691
|
+
return reply;
|
|
692
|
+
}
|
|
693
|
+
modulesConfigData = modulesParsed.data;
|
|
694
|
+
}
|
|
296
695
|
// road-to-global-only-install § Phase 2.3 — explicit scope opt-in.
|
|
297
696
|
// `'global'` (default) lands writes under the resolved writeRoot
|
|
298
697
|
// (typically `~/.event4u/agent-config/`). `'project'` routes
|
|
@@ -332,6 +731,7 @@ export function wizardRoute(opts) {
|
|
|
332
731
|
settingsYaml: settingsBody,
|
|
333
732
|
identity: identityParsed && identityParsed.success ? identityParsed.data : null,
|
|
334
733
|
userIdentityYaml: identityBody,
|
|
734
|
+
modulesConfig: modulesConfigData,
|
|
335
735
|
},
|
|
336
736
|
};
|
|
337
737
|
}
|
|
@@ -355,11 +755,47 @@ export function wizardRoute(opts) {
|
|
|
355
755
|
// and the flat-root files are independent legacy artefacts
|
|
356
756
|
// that should still be cleaned. The helper handles that.
|
|
357
757
|
const migratedFrom = await deleteLegacyArtefacts(legacyReadRoot, effectiveWriteRoot).catch(() => []);
|
|
758
|
+
// road-to-configurable-modules § Phase E — invoke the
|
|
759
|
+
// persistence helper after the 2PC commit so a failed
|
|
760
|
+
// settings write never leaves a half-applied
|
|
761
|
+
// `.agent-project-settings.yml` behind. Best-effort: a
|
|
762
|
+
// bridge failure surfaces in `modulesApply.error` but
|
|
763
|
+
// does NOT roll back the settings commit (the team file
|
|
764
|
+
// is a separate artefact and the user can re-apply).
|
|
765
|
+
// Same root rule as `/auto-detect`: legacyReadRoot ??
|
|
766
|
+
// process.cwd() — that's the consumer repo, not the
|
|
767
|
+
// server's writeRoot.
|
|
768
|
+
let modulesAppliedTo = null;
|
|
769
|
+
let modulesApplyError = null;
|
|
770
|
+
if (modulesConfigData !== null) {
|
|
771
|
+
const projectRoot = legacyReadRoot ?? process.cwd();
|
|
772
|
+
const scriptPath = join(opts.packageRoot, 'scripts', 'apply_modules_config.py');
|
|
773
|
+
const tmpPath = join(tmpdir(), `agent-config-modules-${randomBytes(8).toString('hex')}.json`);
|
|
774
|
+
try {
|
|
775
|
+
await fs.writeFile(tmpPath, JSON.stringify(modulesConfigData), { mode: 0o600 });
|
|
776
|
+
const result = await spawnInstaller(scriptPath, ['--project', projectRoot, '--input-file', tmpPath]);
|
|
777
|
+
if (result.exitCode !== 0) {
|
|
778
|
+
modulesApplyError = { code: 'MODULES_APPLY_FAILED', message: result.stderr || 'modules apply bridge exited non-zero', exitCode: result.exitCode };
|
|
779
|
+
}
|
|
780
|
+
else {
|
|
781
|
+
modulesAppliedTo = result.stdout.trim() || null;
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
catch (err) {
|
|
785
|
+
const message = err instanceof Error ? err.message : 'modules apply bridge failed';
|
|
786
|
+
modulesApplyError = { code: 'MODULES_APPLY_FAILED', message };
|
|
787
|
+
}
|
|
788
|
+
finally {
|
|
789
|
+
await fs.unlink(tmpPath).catch(() => undefined);
|
|
790
|
+
}
|
|
791
|
+
}
|
|
358
792
|
return {
|
|
359
793
|
writtenPaths: payloads.map((p) => p.target),
|
|
360
794
|
txnId,
|
|
361
795
|
scope,
|
|
362
796
|
...(migratedFrom.length > 0 ? { migratedFrom } : {}),
|
|
797
|
+
...(modulesAppliedTo !== null ? { modulesAppliedTo } : {}),
|
|
798
|
+
...(modulesApplyError !== null ? { modulesApplyError } : {}),
|
|
363
799
|
};
|
|
364
800
|
}
|
|
365
801
|
catch (err) {
|