session-orchestrator 3.16.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/.claude-plugin/marketplace.json +29 -0
- package/.claude-plugin/plugin.json +18 -0
- package/.codex-plugin/agents/explorer.toml +14 -0
- package/.codex-plugin/agents/session-reviewer.toml +23 -0
- package/.codex-plugin/agents/wave-worker.toml +15 -0
- package/.codex-plugin/config.toml +20 -0
- package/.codex-plugin/plugin.json +37 -0
- package/.cursor/rules/000-session-orchestrator.mdc +73 -0
- package/.cursor/rules/010-session-workflow.mdc +170 -0
- package/.cursor/rules/020-quality-gates.mdc +128 -0
- package/.cursor/rules/030-wave-execution.mdc +216 -0
- package/.cursor/rules/040-discovery.mdc +242 -0
- package/.cursor/rules/050-plan.mdc +235 -0
- package/.cursor/rules/060-evolve.mdc +232 -0
- package/.cursor/rules/070-gitlab-ops.mdc +246 -0
- package/.cursor/rules/080-ecosystem-health.mdc +145 -0
- package/.mcp.json +8 -0
- package/CHANGELOG.md +1544 -0
- package/LICENSE +21 -0
- package/NOTICE +64 -0
- package/README.md +242 -0
- package/SECURITY.md +90 -0
- package/agents/AGENTS.md +136 -0
- package/agents/analyst.md +99 -0
- package/agents/architect-reviewer.md +93 -0
- package/agents/code-implementer.md +106 -0
- package/agents/db-specialist.md +104 -0
- package/agents/dialectic-deriver.md +139 -0
- package/agents/docs-writer.md +113 -0
- package/agents/eval-judge.md +146 -0
- package/agents/memory-proposal-collector.md +297 -0
- package/agents/qa-strategist.md +102 -0
- package/agents/schemas/analyst.schema.json +46 -0
- package/agents/schemas/architect-reviewer.schema.json +50 -0
- package/agents/schemas/code-implementer.schema.json +61 -0
- package/agents/schemas/db-specialist.schema.json +80 -0
- package/agents/schemas/docs-writer.schema.json +56 -0
- package/agents/schemas/persona-panel-sidecar.schema.json +245 -0
- package/agents/schemas/qa-strategist.schema.json +46 -0
- package/agents/schemas/security-reviewer.schema.json +86 -0
- package/agents/schemas/session-reviewer.schema.json +69 -0
- package/agents/schemas/test-writer.schema.json +69 -0
- package/agents/schemas/ui-developer.schema.json +90 -0
- package/agents/schemas/ux-evaluator.schema.json +51 -0
- package/agents/security-reviewer.md +236 -0
- package/agents/session-reviewer.md +201 -0
- package/agents/skill-applied-judge.md +122 -0
- package/agents/test-writer.md +123 -0
- package/agents/ui-developer.md +109 -0
- package/agents/ux-evaluator.md +161 -0
- package/assets/icon.svg +11 -0
- package/assets/og-card.png +0 -0
- package/assets/og-card.svg +47 -0
- package/commands/autopilot-multi.md +74 -0
- package/commands/autopilot.md +80 -0
- package/commands/bootstrap.md +56 -0
- package/commands/brainstorm.md +48 -0
- package/commands/close.md +24 -0
- package/commands/debug.md +36 -0
- package/commands/discovery.md +32 -0
- package/commands/dispatcher.md +59 -0
- package/commands/eval.md +28 -0
- package/commands/evolve.md +10 -0
- package/commands/go.md +41 -0
- package/commands/grill.md +45 -0
- package/commands/harness-audit.md +26 -0
- package/commands/memory-cleanup.md +25 -0
- package/commands/persona-panel.md +121 -0
- package/commands/plan.md +15 -0
- package/commands/portfolio.md +97 -0
- package/commands/reconcile.md +23 -0
- package/commands/repo-audit.md +24 -0
- package/commands/session.md +30 -0
- package/commands/spinout.md +15 -0
- package/commands/sunset-review.md +27 -0
- package/commands/templates-ack.md +96 -0
- package/commands/test.md +97 -0
- package/docs/README.md +105 -0
- package/docs/USER-GUIDE.md +1403 -0
- package/docs/ci-setup.md +81 -0
- package/docs/codex-setup.md +142 -0
- package/docs/components.md +74 -0
- package/docs/cursor-setup.md +104 -0
- package/docs/events-schema.md +81 -0
- package/docs/migration-v3.md +148 -0
- package/docs/owner-config-schema.md +154 -0
- package/docs/persona-panel.md +433 -0
- package/docs/pi-setup.md +115 -0
- package/docs/plugin-architecture-v3.md +296 -0
- package/docs/pm-skills-marketplace.md +114 -0
- package/docs/policy-cache-validation-2026-04-28.md +118 -0
- package/docs/rule-authoring.md +316 -0
- package/docs/session-config-reference.md +1439 -0
- package/docs/session-config-template.md +961 -0
- package/docs/vault-docs-architecture.md +297 -0
- package/hooks/_lib/lock-bootstrap.mjs +272 -0
- package/hooks/_lib/lock-reconcile.mjs +93 -0
- package/hooks/_lib/profile-gate.mjs +95 -0
- package/hooks/_lib/transcript-history.mjs +211 -0
- package/hooks/agent-teams-h3-test.sh +362 -0
- package/hooks/config-protection.mjs +0 -0
- package/hooks/cwd-change-restore.mjs +131 -0
- package/hooks/enforce-commands.mjs +179 -0
- package/hooks/enforce-scope.mjs +273 -0
- package/hooks/hooks-codex.json +60 -0
- package/hooks/hooks-cursor.json +15 -0
- package/hooks/hooks-pi.json +115 -0
- package/hooks/hooks.json +215 -0
- package/hooks/loop-guard.mjs +260 -0
- package/hooks/on-session-end.mjs +217 -0
- package/hooks/on-session-start.mjs +660 -0
- package/hooks/on-stop.mjs +294 -0
- package/hooks/operator-steer.mjs +64 -0
- package/hooks/post-edit-validate.mjs +225 -0
- package/hooks/post-subagent-discovery-validator.mjs +398 -0
- package/hooks/post-tool-batch-wave-signal.mjs +328 -0
- package/hooks/post-tool-failure-corrective-context.mjs +248 -0
- package/hooks/post-tooluse-frontend-slop.mjs +184 -0
- package/hooks/pre-bash-destructive-guard.mjs +515 -0
- package/hooks/pre-bash-memory-propose-audit.mjs +206 -0
- package/hooks/pre-bash-staging-fence.mjs +223 -0
- package/hooks/pre-bash-templates-first.mjs +404 -0
- package/hooks/run-node.sh +72 -0
- package/hooks/skill-invocation-telemetry.mjs +99 -0
- package/hooks/subagent-telemetry.mjs +249 -0
- package/hooks/wave-scope-commit-guard.mjs +191 -0
- package/monitors/monitors.json +14 -0
- package/output-styles/finding-report.md +48 -0
- package/output-styles/session-report.md +53 -0
- package/output-styles/wave-summary.md +38 -0
- package/package.json +94 -0
- package/pi/extensions/session-orchestrator.ts +25 -0
- package/pi/prompts/autopilot-multi.md +12 -0
- package/pi/prompts/autopilot.md +12 -0
- package/pi/prompts/bootstrap.md +12 -0
- package/pi/prompts/brainstorm.md +12 -0
- package/pi/prompts/close.md +11 -0
- package/pi/prompts/debug.md +12 -0
- package/pi/prompts/discovery.md +12 -0
- package/pi/prompts/dispatcher.md +12 -0
- package/pi/prompts/eval.md +12 -0
- package/pi/prompts/evolve.md +12 -0
- package/pi/prompts/go.md +12 -0
- package/pi/prompts/grill.md +12 -0
- package/pi/prompts/harness-audit.md +12 -0
- package/pi/prompts/memory-cleanup.md +12 -0
- package/pi/prompts/persona-panel.md +12 -0
- package/pi/prompts/plan.md +12 -0
- package/pi/prompts/portfolio.md +12 -0
- package/pi/prompts/reconcile.md +12 -0
- package/pi/prompts/repo-audit.md +12 -0
- package/pi/prompts/session.md +12 -0
- package/pi/prompts/spinout.md +12 -0
- package/pi/prompts/sunset-review.md +12 -0
- package/pi/prompts/templates-ack.md +12 -0
- package/pi/prompts/test.md +12 -0
- package/rules/_index.md +51 -0
- package/rules/always-on/commit-discipline.md +26 -0
- package/rules/always-on/npm-quality-gates.md +26 -0
- package/rules/always-on/parallel-sessions.md +43 -0
- package/rules/opt-in-domain/prompt-caching.md +270 -0
- package/rules/opt-in-stack/backend-data.md +188 -0
- package/rules/opt-in-stack/backend.md +390 -0
- package/rules/opt-in-stack/frontend.md +98 -0
- package/rules/opt-in-stack/security-web.md +194 -0
- package/rules/opt-in-stack/swift.md +65 -0
- package/scripts/archive-closed-prds.mjs +416 -0
- package/scripts/autopilot-multi.mjs +802 -0
- package/scripts/autopilot.mjs +383 -0
- package/scripts/backfill-abandoned-sessions.mjs +265 -0
- package/scripts/backfill-learnings-expires.mjs +196 -0
- package/scripts/backfill-learnings.mjs +203 -0
- package/scripts/backfill-sessions.mjs +282 -0
- package/scripts/check-doc-consistency.sh +279 -0
- package/scripts/check-package-manager.mjs +445 -0
- package/scripts/ci/assert-vitest-green.mjs +267 -0
- package/scripts/codex-install.mjs +435 -0
- package/scripts/compute-grounding-injection.sh +186 -0
- package/scripts/cursor-install.mjs +113 -0
- package/scripts/dialectic-deriver.mjs +573 -0
- package/scripts/emit-event.mjs +160 -0
- package/scripts/emit-session.mjs +212 -0
- package/scripts/eval-session.mjs +262 -0
- package/scripts/export-hw-learnings.mjs +437 -0
- package/scripts/gc-stale-worktrees.mjs +666 -0
- package/scripts/generate-pi-prompts.mjs +127 -0
- package/scripts/harness-audit.mjs +287 -0
- package/scripts/lib/agent-frontmatter.mjs +266 -0
- package/scripts/lib/agent-output-schema.mjs +166 -0
- package/scripts/lib/agent-status.mjs +303 -0
- package/scripts/lib/ajv-loader.mjs +34 -0
- package/scripts/lib/auto-dialectic.mjs +382 -0
- package/scripts/lib/auto-dream.mjs +471 -0
- package/scripts/lib/autonomy/suitability.mjs +212 -0
- package/scripts/lib/autopilot/dep-graph.mjs +417 -0
- package/scripts/lib/autopilot/durable-telemetry.mjs +121 -0
- package/scripts/lib/autopilot/flags.mjs +104 -0
- package/scripts/lib/autopilot/kill-switches.mjs +174 -0
- package/scripts/lib/autopilot/loop.mjs +320 -0
- package/scripts/lib/autopilot/mr-draft.mjs +520 -0
- package/scripts/lib/autopilot/multi-killswitch.mjs +184 -0
- package/scripts/lib/autopilot/recent-runs.mjs +106 -0
- package/scripts/lib/autopilot/stall-sampler.mjs +97 -0
- package/scripts/lib/autopilot/telemetry.mjs +224 -0
- package/scripts/lib/autopilot/worktree-pipeline.mjs +605 -0
- package/scripts/lib/autopilot-telemetry.mjs +11 -0
- package/scripts/lib/autopilot.mjs +39 -0
- package/scripts/lib/backlog-scan.mjs +179 -0
- package/scripts/lib/bootstrap-lock-freshness.mjs +260 -0
- package/scripts/lib/bootstrap-lock-refresh.mjs +186 -0
- package/scripts/lib/build-live-signals.mjs +150 -0
- package/scripts/lib/ci-status-banner.mjs +425 -0
- package/scripts/lib/claude-md-budget-lint.mjs +246 -0
- package/scripts/lib/cli-flags.mjs +158 -0
- package/scripts/lib/codex/plugin-contract.mjs +610 -0
- package/scripts/lib/cold-start-detector.mjs +240 -0
- package/scripts/lib/command-blocker.mjs +458 -0
- package/scripts/lib/common.mjs +333 -0
- package/scripts/lib/config/auto-dream.mjs +77 -0
- package/scripts/lib/config/block-header.mjs +94 -0
- package/scripts/lib/config/broken-window.mjs +114 -0
- package/scripts/lib/config/coercers.mjs +248 -0
- package/scripts/lib/config/cold-start.mjs +92 -0
- package/scripts/lib/config/config-protection.mjs +120 -0
- package/scripts/lib/config/cross-repo.mjs +104 -0
- package/scripts/lib/config/custom-phases.mjs +213 -0
- package/scripts/lib/config/dialectic.mjs +92 -0
- package/scripts/lib/config/discovery-validator.mjs +75 -0
- package/scripts/lib/config/dispatcher-autonomy-capture.mjs +240 -0
- package/scripts/lib/config/dispatcher-autonomy.mjs +152 -0
- package/scripts/lib/config/docs-orchestrator.mjs +90 -0
- package/scripts/lib/config/docs-staleness.mjs +96 -0
- package/scripts/lib/config/drift-check.mjs +155 -0
- package/scripts/lib/config/eval.mjs +130 -0
- package/scripts/lib/config/events-rotation.mjs +74 -0
- package/scripts/lib/config/evolve.mjs +308 -0
- package/scripts/lib/config/frontend-slop-hook.mjs +104 -0
- package/scripts/lib/config/gitlab-portfolio.mjs +150 -0
- package/scripts/lib/config/handover-gate.mjs +106 -0
- package/scripts/lib/config/host-paths.mjs +76 -0
- package/scripts/lib/config/io.mjs +54 -0
- package/scripts/lib/config/loop-guard.mjs +117 -0
- package/scripts/lib/config/memory.mjs +150 -0
- package/scripts/lib/config/persona-gate-wave.mjs +258 -0
- package/scripts/lib/config/reconcile.mjs +205 -0
- package/scripts/lib/config/section-extractor.mjs +100 -0
- package/scripts/lib/config/skill-evolution.mjs +112 -0
- package/scripts/lib/config/slopcheck.mjs +99 -0
- package/scripts/lib/config/state-md-lock.mjs +83 -0
- package/scripts/lib/config/templates-first.mjs +94 -0
- package/scripts/lib/config/test.mjs +113 -0
- package/scripts/lib/config/vault-integration.mjs +201 -0
- package/scripts/lib/config/vault-mirror-quality.mjs +99 -0
- package/scripts/lib/config/vault-staleness.mjs +84 -0
- package/scripts/lib/config/vault-sync.mjs +96 -0
- package/scripts/lib/config/verification-auto-fix.mjs +84 -0
- package/scripts/lib/config/wave-reviewers.mjs +133 -0
- package/scripts/lib/config-schema.mjs +345 -0
- package/scripts/lib/config.mjs +474 -0
- package/scripts/lib/convergence-monitor.mjs +389 -0
- package/scripts/lib/coordinator-snapshot.mjs +371 -0
- package/scripts/lib/crypto-digest-utils.mjs +91 -0
- package/scripts/lib/discovery/helpers.mjs +127 -0
- package/scripts/lib/discovery/triage-state.mjs +279 -0
- package/scripts/lib/dispatcher/cli.mjs +257 -0
- package/scripts/lib/dispatcher/enumerate.mjs +243 -0
- package/scripts/lib/dispatcher/rank.mjs +363 -0
- package/scripts/lib/ecosystem-health.mjs +224 -0
- package/scripts/lib/ecosystem-wizard/ci-detector.mjs +18 -0
- package/scripts/lib/ecosystem-wizard/config-parser.mjs +54 -0
- package/scripts/lib/ecosystem-wizard/config-writer.mjs +287 -0
- package/scripts/lib/ecosystem-wizard/package-manager-detector.mjs +42 -0
- package/scripts/lib/ecosystem-wizard/wizard-prompt.mjs +246 -0
- package/scripts/lib/ecosystem-wizard.mjs +48 -0
- package/scripts/lib/env-check.mjs +89 -0
- package/scripts/lib/eval/engine.mjs +605 -0
- package/scripts/lib/eval/judge.mjs +433 -0
- package/scripts/lib/eval/report.mjs +367 -0
- package/scripts/lib/eval/schema.mjs +618 -0
- package/scripts/lib/eval/session-resolve.mjs +137 -0
- package/scripts/lib/eval/sink.mjs +77 -0
- package/scripts/lib/events-rotation.mjs +86 -0
- package/scripts/lib/events-schema.mjs +81 -0
- package/scripts/lib/events.mjs +80 -0
- package/scripts/lib/evolve/autonomy-verdict.mjs +461 -0
- package/scripts/lib/evolve/autopilot-effectiveness.mjs +293 -0
- package/scripts/lib/exclusivity-matrix.mjs +68 -0
- package/scripts/lib/fetch-baseline.mjs +311 -0
- package/scripts/lib/file-lock.mjs +512 -0
- package/scripts/lib/frontend-detect/detect.mjs +138 -0
- package/scripts/lib/frontend-detect/rules.mjs +295 -0
- package/scripts/lib/frontmatter-guard.mjs +241 -0
- package/scripts/lib/gates/echo-stub-detect.mjs +39 -0
- package/scripts/lib/gates/gate-baseline.mjs +42 -0
- package/scripts/lib/gates/gate-full.mjs +85 -0
- package/scripts/lib/gates/gate-helpers.mjs +231 -0
- package/scripts/lib/gates/gate-incremental.mjs +76 -0
- package/scripts/lib/gates/gate-per-file.mjs +55 -0
- package/scripts/lib/gitlab-ops/stale-mr-sweep.mjs +447 -0
- package/scripts/lib/gitlab-portfolio/aggregator.mjs +383 -0
- package/scripts/lib/gitlab-portfolio/cli.mjs +428 -0
- package/scripts/lib/gitlab-portfolio/markdown-writer.mjs +289 -0
- package/scripts/lib/gitlab-portfolio/vcs-detect.mjs +182 -0
- package/scripts/lib/handover-gate.mjs +222 -0
- package/scripts/lib/hardening.mjs +43 -0
- package/scripts/lib/hardware-pattern-detector.mjs +238 -0
- package/scripts/lib/harness-audit/categories/category1.mjs +123 -0
- package/scripts/lib/harness-audit/categories/category2.mjs +145 -0
- package/scripts/lib/harness-audit/categories/category3.mjs +143 -0
- package/scripts/lib/harness-audit/categories/category4.mjs +202 -0
- package/scripts/lib/harness-audit/categories/category5.mjs +152 -0
- package/scripts/lib/harness-audit/categories/category6.mjs +211 -0
- package/scripts/lib/harness-audit/categories/category7.mjs +125 -0
- package/scripts/lib/harness-audit/categories/category8.mjs +328 -0
- package/scripts/lib/harness-audit/categories/category9.mjs +294 -0
- package/scripts/lib/harness-audit/categories/helpers.mjs +165 -0
- package/scripts/lib/harness-audit/categories.mjs +19 -0
- package/scripts/lib/historical-guard.mjs +15 -0
- package/scripts/lib/host-identity.mjs +262 -0
- package/scripts/lib/instruction-budget-guard.mjs +332 -0
- package/scripts/lib/io.mjs +304 -0
- package/scripts/lib/issue-close-strip-labels.mjs +161 -0
- package/scripts/lib/language-mappers/README.md +57 -0
- package/scripts/lib/language-mappers/index.mjs +165 -0
- package/scripts/lib/language-mappers/markdown.mjs +149 -0
- package/scripts/lib/language-mappers/python.mjs +249 -0
- package/scripts/lib/language-mappers/swift.mjs +201 -0
- package/scripts/lib/language-mappers/typescript.mjs +433 -0
- package/scripts/lib/learnings/expiry-sweep.mjs +164 -0
- package/scripts/lib/learnings/filters.mjs +43 -0
- package/scripts/lib/learnings/io.mjs +255 -0
- package/scripts/lib/learnings/schema.mjs +518 -0
- package/scripts/lib/learnings/surface.mjs +207 -0
- package/scripts/lib/learnings.mjs +42 -0
- package/scripts/lib/lock-reaper.mjs +648 -0
- package/scripts/lib/locks/index.mjs +31 -0
- package/scripts/lib/locks/lock-body.mjs +62 -0
- package/scripts/lib/locks/staging-fence-lock.mjs +267 -0
- package/scripts/lib/locks/state-md-lock.mjs +351 -0
- package/scripts/lib/loop-readiness-banner.mjs +144 -0
- package/scripts/lib/memory-banner.mjs +478 -0
- package/scripts/lib/memory-cleanup/worktree-sweep.mjs +108 -0
- package/scripts/lib/memory-cleanup-stamp.mjs +56 -0
- package/scripts/lib/memory-paths.mjs +31 -0
- package/scripts/lib/memory-proposals/collector.mjs +334 -0
- package/scripts/lib/memory-proposals/schema.mjs +289 -0
- package/scripts/lib/memory-proposals/sink.mjs +507 -0
- package/scripts/lib/memory-proposals/store.mjs +441 -0
- package/scripts/lib/mission-status-schema.mjs +114 -0
- package/scripts/lib/mode-selector/alternatives.mjs +64 -0
- package/scripts/lib/mode-selector/constants.mjs +29 -0
- package/scripts/lib/mode-selector/context-pressure.mjs +157 -0
- package/scripts/lib/mode-selector/rationale.mjs +55 -0
- package/scripts/lib/mode-selector/scoring.mjs +221 -0
- package/scripts/lib/mode-selector-accuracy.mjs +121 -0
- package/scripts/lib/mode-selector.mjs +160 -0
- package/scripts/lib/multi-provider-build/providers.mjs +64 -0
- package/scripts/lib/multi-provider-build/templating.mjs +130 -0
- package/scripts/lib/named-baseline-resolver.mjs +233 -0
- package/scripts/lib/named-vault-resolver.mjs +433 -0
- package/scripts/lib/owner-config/coerce.mjs +29 -0
- package/scripts/lib/owner-config/constants.mjs +21 -0
- package/scripts/lib/owner-config/defaults.mjs +50 -0
- package/scripts/lib/owner-config/error.mjs +19 -0
- package/scripts/lib/owner-config/index.mjs +13 -0
- package/scripts/lib/owner-config/merge.mjs +52 -0
- package/scripts/lib/owner-config/validate.mjs +259 -0
- package/scripts/lib/owner-config-banner.mjs +126 -0
- package/scripts/lib/owner-config-loader.mjs +159 -0
- package/scripts/lib/owner-config.example.yaml +72 -0
- package/scripts/lib/owner-config.mjs +28 -0
- package/scripts/lib/owner-interview.mjs +243 -0
- package/scripts/lib/owner-yaml.mjs +571 -0
- package/scripts/lib/package-manager.mjs +160 -0
- package/scripts/lib/path-utils.mjs +217 -0
- package/scripts/lib/peer-cards/merger.mjs +310 -0
- package/scripts/lib/peer-cards/reader.mjs +125 -0
- package/scripts/lib/peer-cards/schema.mjs +230 -0
- package/scripts/lib/peer-cards/staleness-banner.mjs +86 -0
- package/scripts/lib/peer-cards/writer.mjs +138 -0
- package/scripts/lib/peer-discovery.mjs +200 -0
- package/scripts/lib/persona-panel/catalog-loader.mjs +577 -0
- package/scripts/lib/persona-panel/consolidator.mjs +370 -0
- package/scripts/lib/persona-panel/persona-runner.mjs +375 -0
- package/scripts/lib/persona-panel/threshold.mjs +130 -0
- package/scripts/lib/pi-hook-bridge.mjs +328 -0
- package/scripts/lib/platform.mjs +266 -0
- package/scripts/lib/playwright-driver/runner.mjs +297 -0
- package/scripts/lib/plugin-root.mjs +210 -0
- package/scripts/lib/pre-dispatch-check.mjs +126 -0
- package/scripts/lib/product-repo-detect.mjs +121 -0
- package/scripts/lib/profiles/registry.mjs +176 -0
- package/scripts/lib/profiles/schema.mjs +209 -0
- package/scripts/lib/qg-command-drift-banner.mjs +88 -0
- package/scripts/lib/quality-gate/diagnostics.mjs +92 -0
- package/scripts/lib/quality-gate.mjs +536 -0
- package/scripts/lib/quality-gates-cache.mjs +228 -0
- package/scripts/lib/quality-gates-policy.mjs +95 -0
- package/scripts/lib/recommendations-v0.mjs +156 -0
- package/scripts/lib/reconcile/eligibility.mjs +203 -0
- package/scripts/lib/reconcile/emitter.mjs +244 -0
- package/scripts/lib/reconcile/engine.mjs +412 -0
- package/scripts/lib/reconcile/idempotency.mjs +239 -0
- package/scripts/lib/reconcile/renderer.mjs +211 -0
- package/scripts/lib/reconcile/writer.mjs +293 -0
- package/scripts/lib/reconcile-nudge-banner.mjs +284 -0
- package/scripts/lib/resource-probe/evaluate.mjs +190 -0
- package/scripts/lib/resource-probe/parsers.mjs +181 -0
- package/scripts/lib/resource-probe/probe-platform.mjs +300 -0
- package/scripts/lib/resource-probe.mjs +95 -0
- package/scripts/lib/rule-loader.mjs +552 -0
- package/scripts/lib/rules-sync.mjs +439 -0
- package/scripts/lib/scope-gate.mjs +496 -0
- package/scripts/lib/session-close-backfill.mjs +539 -0
- package/scripts/lib/session-discovery.mjs +256 -0
- package/scripts/lib/session-end/phase-skip.mjs +357 -0
- package/scripts/lib/session-end/worktree-cleanup.mjs +112 -0
- package/scripts/lib/session-id.mjs +362 -0
- package/scripts/lib/session-lock.mjs +703 -0
- package/scripts/lib/session-registry.mjs +355 -0
- package/scripts/lib/session-schema/aliases.mjs +71 -0
- package/scripts/lib/session-schema/constants.mjs +115 -0
- package/scripts/lib/session-schema/normalizer.mjs +66 -0
- package/scripts/lib/session-schema/timestamps.mjs +64 -0
- package/scripts/lib/session-schema/validator.mjs +453 -0
- package/scripts/lib/session-schema.mjs +71 -0
- package/scripts/lib/session-token-rollup.mjs +137 -0
- package/scripts/lib/sessions-staleness-banner.mjs +247 -0
- package/scripts/lib/skill-evolution/blast-radius-classifier.mjs +114 -0
- package/scripts/lib/skill-evolution/candidate-intake.mjs +270 -0
- package/scripts/lib/skill-evolution/config-validation-gate.mjs +279 -0
- package/scripts/lib/skill-evolution/engine.mjs +719 -0
- package/scripts/lib/skill-evolution/idempotency.mjs +279 -0
- package/scripts/lib/skill-evolution/mr-opener.mjs +507 -0
- package/scripts/lib/skill-health/join.mjs +181 -0
- package/scripts/lib/skill-health/score.mjs +123 -0
- package/scripts/lib/skill-invocations-schema.mjs +214 -0
- package/scripts/lib/skill-judge.mjs +348 -0
- package/scripts/lib/skill-judgments-schema.mjs +264 -0
- package/scripts/lib/slopcheck.mjs +501 -0
- package/scripts/lib/soul-resolve.mjs +118 -0
- package/scripts/lib/spiral-carryover.mjs +495 -0
- package/scripts/lib/state-md/body-sections.mjs +851 -0
- package/scripts/lib/state-md/frontmatter-mutators.mjs +453 -0
- package/scripts/lib/state-md/mission-status.mjs +247 -0
- package/scripts/lib/state-md/recommendations.mjs +57 -0
- package/scripts/lib/state-md/yaml-parser.mjs +234 -0
- package/scripts/lib/state-md-peer-guard.mjs +232 -0
- package/scripts/lib/state-md.mjs +53 -0
- package/scripts/lib/subagents-schema.mjs +309 -0
- package/scripts/lib/sunset/walker.mjs +1192 -0
- package/scripts/lib/test-runner/artifact-paths.mjs +94 -0
- package/scripts/lib/test-runner/fingerprint.mjs +33 -0
- package/scripts/lib/test-runner/issue-reconcile.mjs +770 -0
- package/scripts/lib/tmux-layout/layouts.mjs +224 -0
- package/scripts/lib/tmux-layout/telemetry-stats.mjs +100 -0
- package/scripts/lib/tmux-layout/telemetry.mjs +88 -0
- package/scripts/lib/tmux-layout/tmux-shell.mjs +82 -0
- package/scripts/lib/tmux-layout/vcs-detector.mjs +88 -0
- package/scripts/lib/validate/check-agents.mjs +457 -0
- package/scripts/lib/validate/check-codex-plugin.mjs +37 -0
- package/scripts/lib/validate/check-commands.mjs +148 -0
- package/scripts/lib/validate/check-component-paths.mjs +112 -0
- package/scripts/lib/validate/check-dead-bridge.mjs +180 -0
- package/scripts/lib/validate/check-hooks-symmetry.mjs +258 -0
- package/scripts/lib/validate/check-json-files.mjs +116 -0
- package/scripts/lib/validate/check-owner-leakage.mjs +1011 -0
- package/scripts/lib/validate/check-path-utils-canary.mjs +175 -0
- package/scripts/lib/validate/check-peekaboo-driver-canary.mjs +201 -0
- package/scripts/lib/validate/check-pi-package.mjs +110 -0
- package/scripts/lib/validate/check-pi-prompts.mjs +43 -0
- package/scripts/lib/validate/check-playwright-mcp-canary.mjs +154 -0
- package/scripts/lib/validate/check-plugin-json.mjs +96 -0
- package/scripts/lib/validate/check-plugin-monitors.mjs +206 -0
- package/scripts/lib/validate/check-plugin-schema.mjs +137 -0
- package/scripts/lib/validate/check-rules.mjs +143 -0
- package/scripts/lib/validate/check-session-plan-routing.mjs +154 -0
- package/scripts/lib/validate/check-test-fixture-shapes.mjs +280 -0
- package/scripts/lib/validate/check-unicode-safety.mjs +533 -0
- package/scripts/lib/validate/confidential-names.mjs +169 -0
- package/scripts/lib/validate/dead-bridge-corpus.mjs +141 -0
- package/scripts/lib/validate/dead-bridge-detectors.mjs +568 -0
- package/scripts/lib/validate/tier-inference.mjs +100 -0
- package/scripts/lib/validate-vendored-rules.mjs +519 -0
- package/scripts/lib/vault-archive.mjs +404 -0
- package/scripts/lib/vault-backfill/glab.mjs +164 -0
- package/scripts/lib/vault-backfill/manifest.mjs +75 -0
- package/scripts/lib/vault-backfill/template.mjs +130 -0
- package/scripts/lib/vault-consolidate-fs.mjs +331 -0
- package/scripts/lib/vault-migration-rules.mjs +155 -0
- package/scripts/lib/vault-mirror/auto-commit.mjs +203 -0
- package/scripts/lib/vault-mirror/namespace.mjs +152 -0
- package/scripts/lib/vault-mirror/process.mjs +567 -0
- package/scripts/lib/vault-mirror/pseudonym-map.mjs +164 -0
- package/scripts/lib/vault-mirror/render-learnings.mjs +201 -0
- package/scripts/lib/vault-mirror/render-sessions.mjs +367 -0
- package/scripts/lib/vault-mirror/render.mjs +8 -0
- package/scripts/lib/vault-mirror/utils.mjs +217 -0
- package/scripts/lib/vault-relocation-rules.mjs +555 -0
- package/scripts/lib/vault-repo-backfill.mjs +235 -0
- package/scripts/lib/vault-staleness-banner.mjs +142 -0
- package/scripts/lib/vault-status/board-writer.mjs +769 -0
- package/scripts/lib/vault-status/narrative-mirror.mjs +544 -0
- package/scripts/lib/vault-sync-baseline.mjs +152 -0
- package/scripts/lib/wave-context.mjs +29 -0
- package/scripts/lib/wave-executor/pool.mjs +248 -0
- package/scripts/lib/wave-resource-gate.mjs +204 -0
- package/scripts/lib/wave-sizing.mjs +75 -0
- package/scripts/lib/webhook-url.mjs +105 -0
- package/scripts/lib/workspace.mjs +198 -0
- package/scripts/lib/worktree/constants.mjs +35 -0
- package/scripts/lib/worktree/index.mjs +17 -0
- package/scripts/lib/worktree/lifecycle.mjs +287 -0
- package/scripts/lib/worktree/listing.mjs +118 -0
- package/scripts/lib/worktree/meta.mjs +64 -0
- package/scripts/lib/worktree-freshness.mjs +313 -0
- package/scripts/lib/worktree.mjs +15 -0
- package/scripts/lifecycle-sim-v6.mjs +347 -0
- package/scripts/lock-reaper.mjs +185 -0
- package/scripts/mcp-server.sh +241 -0
- package/scripts/measure-policy-cache-effectiveness.mjs +427 -0
- package/scripts/memory-propose.mjs +464 -0
- package/scripts/migrate-cold-start-seed.mjs +404 -0
- package/scripts/migrate-learnings-jsonl.mjs +189 -0
- package/scripts/migrate-legacy-learnings.sh +61 -0
- package/scripts/migrate-sessions-jsonl.mjs +448 -0
- package/scripts/migrate-subagents-jsonl.mjs +196 -0
- package/scripts/migrate-vault-paths.mjs +796 -0
- package/scripts/parse-config.mjs +149 -0
- package/scripts/pi-install.mjs +117 -0
- package/scripts/print-applicable-rules.mjs +247 -0
- package/scripts/promote-vault-strict.mjs +496 -0
- package/scripts/relocate-vault-corpus.mjs +1178 -0
- package/scripts/run-migrate-v2-cross-repo.mjs +385 -0
- package/scripts/run-quality-gate.mjs +216 -0
- package/scripts/spikes/h3-agent-teams/preflight.sh +53 -0
- package/scripts/spikes/h3-agent-teams/run-h3.sh +112 -0
- package/scripts/spikes/h3-agent-teams/setup.sh +137 -0
- package/scripts/spikes/h3-agent-teams/toggle.sh +38 -0
- package/scripts/sweep-expired-learnings.mjs +135 -0
- package/scripts/sync-vault-schema.mjs +376 -0
- package/scripts/tests/fixtures/fetch-baseline/sample-rule.md +8 -0
- package/scripts/tmux-layout.mjs +245 -0
- package/scripts/token-audit.sh +191 -0
- package/scripts/typecheck.mjs +42 -0
- package/scripts/upload-social-preview.mjs +316 -0
- package/scripts/validate-config.mjs +46 -0
- package/scripts/validate-plugin-manifests.mjs +163 -0
- package/scripts/validate-plugin.mjs +264 -0
- package/scripts/validate-wave-scope.mjs +289 -0
- package/scripts/vault-backfill.mjs +404 -0
- package/scripts/vault-consolidate.mjs +596 -0
- package/scripts/vault-integration-watcher.mjs +394 -0
- package/scripts/vault-mirror.mjs +430 -0
- package/skills/_shared/bootstrap-gate.md +111 -0
- package/skills/_shared/config-reading.md +226 -0
- package/skills/_shared/instruction-file-resolution.md +79 -0
- package/skills/_shared/model-selection.md +64 -0
- package/skills/_shared/monitor-patterns.md +300 -0
- package/skills/_shared/parallel-aware-auq.md +121 -0
- package/skills/_shared/parallel-aware-preamble.md +185 -0
- package/skills/_shared/platform-tools.md +96 -0
- package/skills/_shared/state-ownership.md +221 -0
- package/skills/architecture/DEEPENING.md +37 -0
- package/skills/architecture/INTERFACE-DESIGN.md +44 -0
- package/skills/architecture/LANGUAGE.md +53 -0
- package/skills/architecture/SKILL.md +92 -0
- package/skills/autopilot/SKILL.md +419 -0
- package/skills/bootstrap/SKILL.md +592 -0
- package/skills/bootstrap/STATE.md.template +24 -0
- package/skills/bootstrap/_shared-template.md +243 -0
- package/skills/bootstrap/deep-template.md +659 -0
- package/skills/bootstrap/fast-template.md +251 -0
- package/skills/bootstrap/intensity-heuristic.md +80 -0
- package/skills/bootstrap/public-fallback.md +342 -0
- package/skills/bootstrap/standard-template.md +736 -0
- package/skills/bootstrap/templates/agents/project-code-review.md +18 -0
- package/skills/bootstrap/templates/agents/project-discovery.md +18 -0
- package/skills/bootstrap/templates/agents/project-quality-gate.md +18 -0
- package/skills/brainstorm/SKILL.md +268 -0
- package/skills/brainstorm/soul.md +49 -0
- package/skills/claude-md-drift-check/SKILL.md +186 -0
- package/skills/claude-md-drift-check/checker.mjs +1380 -0
- package/skills/claude-md-drift-check/checker.sh +37 -0
- package/skills/claude-md-drift-check/package.json +16 -0
- package/skills/convergence-monitoring/README.md +39 -0
- package/skills/convergence-monitoring/SIGNALS.md +246 -0
- package/skills/convergence-monitoring/SKILL.md +285 -0
- package/skills/daily/SKILL.md +222 -0
- package/skills/daily/generate.sh +92 -0
- package/skills/daily/templates/daily.md.tpl +36 -0
- package/skills/debug/SKILL.md +188 -0
- package/skills/debug/soul.md +35 -0
- package/skills/discovery/SKILL.md +567 -0
- package/skills/discovery/issue-templates.md +237 -0
- package/skills/discovery/probes/docs-staleness.mjs +195 -0
- package/skills/discovery/probes/frontend-slop.mjs +186 -0
- package/skills/discovery/probes/ssot-code-diff.mjs +310 -0
- package/skills/discovery/probes/supply-chain-slopcheck.mjs +440 -0
- package/skills/discovery/probes/vault-narrative-staleness.mjs +355 -0
- package/skills/discovery/probes/vault-staleness.mjs +272 -0
- package/skills/discovery/probes-arch.md +252 -0
- package/skills/discovery/probes-audit.md +95 -0
- package/skills/discovery/probes-code.md +329 -0
- package/skills/discovery/probes-docs.md +76 -0
- package/skills/discovery/probes-feature.md +150 -0
- package/skills/discovery/probes-infra.md +138 -0
- package/skills/discovery/probes-intro.md +25 -0
- package/skills/discovery/probes-session.md +495 -0
- package/skills/discovery/probes-supply-chain.md +94 -0
- package/skills/discovery/probes-ui.md +147 -0
- package/skills/discovery/probes-vault.md +64 -0
- package/skills/discovery/slop-patterns.md +115 -0
- package/skills/dispatcher/SKILL.md +173 -0
- package/skills/docs-orchestrator/SKILL.md +362 -0
- package/skills/docs-orchestrator/audience-mapping.md +140 -0
- package/skills/domain-model/ADR-FORMAT.md +47 -0
- package/skills/domain-model/CONTEXT-FORMAT.md +77 -0
- package/skills/domain-model/SKILL.md +85 -0
- package/skills/ecosystem-health/SKILL.md +119 -0
- package/skills/ecosystem-health/wizard.md +193 -0
- package/skills/eval/SKILL.md +293 -0
- package/skills/eval/rubric-v1.md +218 -0
- package/skills/evolve/SKILL.md +546 -0
- package/skills/frontmatter-guard/SKILL.md +126 -0
- package/skills/gitlab-ops/SKILL.md +368 -0
- package/skills/gitlab-portfolio/SKILL.md +196 -0
- package/skills/grill/SKILL.md +185 -0
- package/skills/grill/soul.md +55 -0
- package/skills/hook-development/SKILL.md +413 -0
- package/skills/mcp-builder/SKILL.md +260 -0
- package/skills/memory-cleanup/SKILL.md +310 -0
- package/skills/mode-selector/SKILL.md +226 -0
- package/skills/peekaboo-driver/SKILL.md +237 -0
- package/skills/peekaboo-driver/soul.md +32 -0
- package/skills/persona-panel/SKILL.md +365 -0
- package/skills/persona-panel/persona-format.md +205 -0
- package/skills/persona-panel/presets/designer-lens.md +87 -0
- package/skills/persona-panel/presets/engineer-lens.md +88 -0
- package/skills/persona-panel/presets/pm-lens.md +86 -0
- package/skills/plan/SKILL.md +496 -0
- package/skills/plan/mode-feature.md +141 -0
- package/skills/plan/mode-new.md +297 -0
- package/skills/plan/mode-retro.md +271 -0
- package/skills/plan/prd-feature-template.md +132 -0
- package/skills/plan/prd-full-template.md +151 -0
- package/skills/plan/prd-reviewer-prompt.md +103 -0
- package/skills/plan/retro-template.md +75 -0
- package/skills/plan/soul.md +62 -0
- package/skills/playwright-driver/SKILL.md +226 -0
- package/skills/playwright-driver/soul.md +30 -0
- package/skills/quality-gates/SKILL.md +212 -0
- package/skills/reconcile/SKILL.md +324 -0
- package/skills/repo-audit/SKILL.md +272 -0
- package/skills/session-end/SKILL.md +1044 -0
- package/skills/session-end/discovery-scan.md +37 -0
- package/skills/session-end/drift-operations.md +97 -0
- package/skills/session-end/learning-patterns.md +78 -0
- package/skills/session-end/metrics-collection.md +175 -0
- package/skills/session-end/phase-3-2-docs-verification.md +148 -0
- package/skills/session-end/phase-3-6-tail.md +344 -0
- package/skills/session-end/phase-3-7a-recommendations.md +86 -0
- package/skills/session-end/plan-verification.md +288 -0
- package/skills/session-end/session-metrics-write.md +223 -0
- package/skills/session-end/vault-operations.md +50 -0
- package/skills/session-end/verification-checklist.md +20 -0
- package/skills/session-plan/SKILL.md +554 -0
- package/skills/session-plan/wave-template.md +37 -0
- package/skills/session-start/SKILL.md +1043 -0
- package/skills/session-start/phase-2-5-docs-planning.md +119 -0
- package/skills/session-start/phase-4-5-resource-health.md +49 -0
- package/skills/session-start/phase-7-1-premise-check.md +47 -0
- package/skills/session-start/phase-7-5-mode-selector.md +237 -0
- package/skills/session-start/phase-8-5-express-path.md +61 -0
- package/skills/session-start/presentation-format.md +81 -0
- package/skills/session-start/soul.md +57 -0
- package/skills/skill-creator/SKILL.md +168 -0
- package/skills/spinout/SKILL.md +76 -0
- package/skills/sunset-review/SKILL.md +96 -0
- package/skills/test-runner/SKILL.md +362 -0
- package/skills/test-runner/rubric-v1.md +388 -0
- package/skills/test-runner/soul.md +46 -0
- package/skills/tmux-layout/SKILL.md +104 -0
- package/skills/ubiquitous-language/SKILL.md +97 -0
- package/skills/using-orchestrator/SKILL.md +144 -0
- package/skills/vault-mirror/SKILL.md +234 -0
- package/skills/vault-sync/SKILL.md +319 -0
- package/skills/vault-sync/package-lock.json +40 -0
- package/skills/vault-sync/package.json +11 -0
- package/skills/vault-sync/tests/fixtures/archive-test-vault/90-archive/bad-archived.md +8 -0
- package/skills/vault-sync/tests/fixtures/archive-test-vault/_meta/.gitkeep +0 -0
- package/skills/vault-sync/tests/fixtures/archive-test-vault/live-note.md +8 -0
- package/skills/vault-sync/tests/fixtures/broken-frontmatter-vault/_meta/.gitkeep +0 -0
- package/skills/vault-sync/tests/fixtures/broken-frontmatter-vault/bad-type.md +8 -0
- package/skills/vault-sync/tests/fixtures/broken-frontmatter-vault/good-note.md +8 -0
- package/skills/vault-sync/tests/fixtures/clean-vault/.obsidian/config.md +8 -0
- package/skills/vault-sync/tests/fixtures/clean-vault/01-projects/foo/projects-baseline.md +10 -0
- package/skills/vault-sync/tests/fixtures/clean-vault/03-daily/daily-2026-04-13.md +8 -0
- package/skills/vault-sync/tests/fixtures/clean-vault/README.md +3 -0
- package/skills/vault-sync/tests/fixtures/clean-vault/hello-world.md +11 -0
- package/skills/vault-sync/tests/fixtures/dangling-link-vault/_meta/.gitkeep +0 -0
- package/skills/vault-sync/tests/fixtures/dangling-link-vault/has-dangling.md +9 -0
- package/skills/vault-sync/tests/fixtures/dangling-link-vault/real-target.md +8 -0
- package/skills/vault-sync/tests/fixtures/empty-vault/_meta/.gitkeep +0 -0
- package/skills/vault-sync/tests/fixtures/missing-field-vault/_meta/.gitkeep +0 -0
- package/skills/vault-sync/tests/fixtures/missing-field-vault/missing-id.md +7 -0
- package/skills/vault-sync/tests/fixtures/nested-tag-vault/03-daily/daily-2026-04-13.md +9 -0
- package/skills/vault-sync/tests/fixtures/nested-tag-vault/_meta/.gitkeep +0 -0
- package/skills/vault-sync/tests/fixtures/nested-tag-vault/nested-tags-note.md +11 -0
- package/skills/vault-sync/tests/fixtures/no-frontmatter-vault/README.md +3 -0
- package/skills/vault-sync/tests/fixtures/no-frontmatter-vault/_MOC.md +3 -0
- package/skills/vault-sync/tests/fixtures/no-frontmatter-vault/_meta/.gitkeep +0 -0
- package/skills/vault-sync/tests/fixtures/with-moc-vault/_MOC.md +11 -0
- package/skills/vault-sync/tests/fixtures/with-moc-vault/_meta/.gitkeep +0 -0
- package/skills/vault-sync/tests/fixtures/with-moc-vault/hello-world.md +11 -0
- package/skills/vault-sync/tests/schema-drift.test.mjs +133 -0
- package/skills/vault-sync/validator.mjs +658 -0
- package/skills/vault-sync/validator.sh +55 -0
- package/skills/wave-executor/SKILL.md +496 -0
- package/skills/wave-executor/circuit-breaker.md +169 -0
- package/skills/wave-executor/wave-loop.md +1043 -0
- package/skills/write-executable-plan/SKILL.md +237 -0
- package/skills/write-executable-plan/plan-template.md +154 -0
- package/templates/_minimal/CLAUDE.md.tmpl +41 -0
- package/templates/_minimal/README.md.tmpl +15 -0
- package/templates/_minimal/gitignore.tmpl +47 -0
- package/templates/_shared/harte-regeln.md +16 -0
- package/templates/_shared/loop.md +90 -0
- package/templates/_shared/rules/parallel-sessions.md +77 -0
- package/templates/nextjs-minimal/README.md +30 -0
- package/templates/nextjs-minimal/app/layout.tsx +18 -0
- package/templates/nextjs-minimal/app/page.tsx +7 -0
- package/templates/nextjs-minimal/eslint.config.mjs +16 -0
- package/templates/nextjs-minimal/next.config.mjs +4 -0
- package/templates/nextjs-minimal/package.json +27 -0
- package/templates/nextjs-minimal/tsconfig.json +23 -0
- package/templates/node-minimal/README.md +33 -0
- package/templates/node-minimal/eslint.config.mjs +10 -0
- package/templates/node-minimal/package.json +21 -0
- package/templates/node-minimal/src/index.ts +1 -0
- package/templates/node-minimal/tests/sanity.test.ts +5 -0
- package/templates/node-minimal/tsconfig.json +17 -0
- package/templates/personas/README.md +150 -0
- package/templates/personas/accounting-compliance.v1.md +120 -0
- package/templates/personas/accounting-tax-advisor.v1.md +116 -0
- package/templates/personas/buyer-p1-cto.v1.md +125 -0
- package/templates/personas/buyer-p2-kanzlei.v1.md +134 -0
- package/templates/personas/buyer-p3-build.v1.md +130 -0
- package/templates/personas/buyer-p4-tech-veto.v1.md +130 -0
- package/templates/personas/buyer-p5-solo.v1.md +132 -0
- package/templates/personas/buyer-p6-ld.v1.md +130 -0
- package/templates/personas/klima-ai-expert.v1.md +114 -0
- package/templates/personas/klima-physicist.v1.md +117 -0
- package/templates/python-uv/README.md +28 -0
- package/templates/python-uv/pyproject.toml +32 -0
- package/templates/python-uv/src/__PROJECT_NAME__/__init__.py +0 -0
- package/templates/python-uv/src/__PROJECT_NAME__/main.py +6 -0
- package/templates/python-uv/tests/test_sanity.py +2 -0
- package/templates/static-html/README.md +19 -0
- package/templates/static-html/index.html +15 -0
- package/templates/static-html/script.js +1 -0
- package/templates/static-html/styles.css +26 -0
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* sync-vault-schema.mjs — Manages the vendored Zod schema in validator.mjs.
|
|
4
|
+
*
|
|
5
|
+
* Keeps the inline schema block in skills/vault-sync/validator.mjs in lockstep
|
|
6
|
+
* with the canonical TypeScript source in projects-baseline. The vendored block
|
|
7
|
+
* is wrapped in sentinel comments; this script replaces only that block.
|
|
8
|
+
*
|
|
9
|
+
* CLI usage:
|
|
10
|
+
* node sync-vault-schema.mjs [--write] [--check] [--canonical <path>] [--validator <path>]
|
|
11
|
+
*
|
|
12
|
+
* Modes:
|
|
13
|
+
* --write (default) Regenerate sentinel block in validator.mjs from canonical. Idempotent.
|
|
14
|
+
* --check Exit 0 if block matches; exit 1 with unified diff on stderr if drifted.
|
|
15
|
+
*
|
|
16
|
+
* Path overrides:
|
|
17
|
+
* --canonical <path> Override canonical .ts path.
|
|
18
|
+
* Fallback env: CANONICAL_VAULT_FRONTMATTER
|
|
19
|
+
* Default: ../../projects-baseline/packages/zod-schemas/src/vault-frontmatter.ts
|
|
20
|
+
* --validator <path> Override validator.mjs path.
|
|
21
|
+
* Default: ../skills/vault-sync/validator.mjs
|
|
22
|
+
*
|
|
23
|
+
* Exit codes:
|
|
24
|
+
* 0 — success / no drift
|
|
25
|
+
* 1 — drift detected (--check mode)
|
|
26
|
+
* 2 — missing file
|
|
27
|
+
* 3 — malformed sentinels (only one of begin/end present)
|
|
28
|
+
*
|
|
29
|
+
* Vendor-ahead state (2026-05-23, #503, I5):
|
|
30
|
+
* The vaultNoteTypeSchema enum in validator.mjs currently includes
|
|
31
|
+
* `peer-card` which is NOT yet present in the canonical
|
|
32
|
+
* projects-baseline source. Until #503 lands upstream, `--check` will
|
|
33
|
+
* report drift; this is expected and is tracked as upstream-sync-debt
|
|
34
|
+
* in the #503 PRD (W5 F2 docs agent owns the PRD update). Once
|
|
35
|
+
* upstream catches up, `--write` will become a no-op (idempotent).
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
import { readFileSync, writeFileSync, existsSync } from 'node:fs';
|
|
39
|
+
import { resolve, dirname } from 'node:path';
|
|
40
|
+
import { fileURLToPath } from 'node:url';
|
|
41
|
+
|
|
42
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
43
|
+
|
|
44
|
+
// ── Sentinel markers ─────────────────────────────────────────────────────────
|
|
45
|
+
const SENTINEL_BEGIN =
|
|
46
|
+
'// ── BEGIN GENERATED SCHEMA (sync-vault-schema.mjs) — do not edit between sentinels ──';
|
|
47
|
+
const SENTINEL_END = '// ── END GENERATED SCHEMA ──';
|
|
48
|
+
|
|
49
|
+
// ── CLI argument parsing ─────────────────────────────────────────────────────
|
|
50
|
+
const args = process.argv.slice(2);
|
|
51
|
+
|
|
52
|
+
function getArg(name) {
|
|
53
|
+
const idx = args.indexOf(name);
|
|
54
|
+
return idx !== -1 ? args[idx + 1] : undefined;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const isCheck = args.includes('--check');
|
|
58
|
+
// --write is the default mode (the non-check path); --write flag just makes intent explicit
|
|
59
|
+
|
|
60
|
+
const canonicalOverride = getArg('--canonical') ?? process.env.CANONICAL_VAULT_FRONTMATTER;
|
|
61
|
+
const validatorOverride = getArg('--validator');
|
|
62
|
+
|
|
63
|
+
const canonicalPath = canonicalOverride
|
|
64
|
+
? resolve(canonicalOverride)
|
|
65
|
+
: resolve(__dirname, '../../projects-baseline/packages/zod-schemas/src/vault-frontmatter.ts');
|
|
66
|
+
|
|
67
|
+
const validatorPath = validatorOverride
|
|
68
|
+
? resolve(validatorOverride)
|
|
69
|
+
: resolve(__dirname, '../skills/vault-sync/validator.mjs');
|
|
70
|
+
|
|
71
|
+
// ── File existence checks ────────────────────────────────────────────────────
|
|
72
|
+
if (!existsSync(canonicalPath)) {
|
|
73
|
+
process.stderr.write(
|
|
74
|
+
`sync-vault-schema: error: canonical file not found: ${canonicalPath}\n`,
|
|
75
|
+
);
|
|
76
|
+
process.exit(2);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (!existsSync(validatorPath)) {
|
|
80
|
+
process.stderr.write(
|
|
81
|
+
`sync-vault-schema: error: validator file not found: ${validatorPath}\n`,
|
|
82
|
+
);
|
|
83
|
+
process.exit(2);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// ── Read canonical .ts ───────────────────────────────────────────────────────
|
|
87
|
+
const canonicalSrc = readFileSync(canonicalPath, 'utf8');
|
|
88
|
+
const canonicalLines = canonicalSrc.split('\n');
|
|
89
|
+
|
|
90
|
+
// Extract a const declaration block starting from a line containing startSearch
|
|
91
|
+
// up to and including the first line matching endSearch (regex or string).
|
|
92
|
+
// Returns the lines as an array (without trailing empty line from split).
|
|
93
|
+
function _extractBlock(lines, startSearch, endSearch) {
|
|
94
|
+
const startIdx = lines.findIndex((l) => l.includes(startSearch));
|
|
95
|
+
if (startIdx === -1) {
|
|
96
|
+
process.stderr.write(
|
|
97
|
+
`sync-vault-schema: error: cannot find anchor "${startSearch}" in canonical file.\n` +
|
|
98
|
+
` If the canonical file structure has changed, update this script.\n`,
|
|
99
|
+
);
|
|
100
|
+
process.exit(2);
|
|
101
|
+
}
|
|
102
|
+
const endRe = typeof endSearch === 'string' ? null : endSearch;
|
|
103
|
+
const endStr = typeof endSearch === 'string' ? endSearch : null;
|
|
104
|
+
|
|
105
|
+
for (let i = startIdx; i < lines.length; i++) {
|
|
106
|
+
const matches = endRe ? endRe.test(lines[i]) : lines[i].includes(endStr);
|
|
107
|
+
if (matches) {
|
|
108
|
+
return lines.slice(startIdx, i + 1);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
process.stderr.write(
|
|
112
|
+
`sync-vault-schema: error: found start anchor "${startSearch}" but no end anchor in canonical file.\n`,
|
|
113
|
+
);
|
|
114
|
+
process.exit(2);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Strip TypeScript-only syntax from a line.
|
|
118
|
+
// Returns null to skip the line entirely, or the cleaned line string.
|
|
119
|
+
// Handles: export keyword removal, export type lines, JSDoc/block comments.
|
|
120
|
+
function stripTsLine(line) {
|
|
121
|
+
// Skip lines that are purely a `export type ...` (z.infer type alias)
|
|
122
|
+
if (/^\s*export\s+type\s+/.test(line)) return null;
|
|
123
|
+
|
|
124
|
+
// Strip `export ` keyword from const/function declarations
|
|
125
|
+
const stripped = line.replace(/^(export\s+)(const|function|let|var)\s/, '$2 ');
|
|
126
|
+
|
|
127
|
+
return stripped;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Strip JSDoc/block-comment lines. We drop entire comment blocks
|
|
131
|
+
// (lines starting with slash-star-star, space-star, etc.) to keep the generated block compact.
|
|
132
|
+
function stripCommentLine(line) {
|
|
133
|
+
const trimmed = line.trim();
|
|
134
|
+
// Block comment openers, continuations, closers, and inline JSDoc
|
|
135
|
+
if (
|
|
136
|
+
trimmed.startsWith('/**') ||
|
|
137
|
+
trimmed.startsWith('* ') ||
|
|
138
|
+
trimmed === '*' ||
|
|
139
|
+
trimmed.startsWith('*/')
|
|
140
|
+
) {
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
// Single-line doc comment
|
|
144
|
+
if (trimmed.startsWith('// ') && !trimmed.startsWith('// ──')) {
|
|
145
|
+
// Keep structural separator comments, drop narrative ones
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
return line;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// ── Extract the five schema constants ────────────────────────────────────────
|
|
152
|
+
// Each extraction: find start (line includes anchor), end (semicolon-terminated)
|
|
153
|
+
|
|
154
|
+
// Regex consts (single-line or two-line continued)
|
|
155
|
+
function extractRegexConst(lines, name) {
|
|
156
|
+
const startIdx = lines.findIndex((l) => l.includes(`const ${name} =`));
|
|
157
|
+
if (startIdx === -1) {
|
|
158
|
+
process.stderr.write(
|
|
159
|
+
`sync-vault-schema: error: cannot find "const ${name}" in canonical file.\n`,
|
|
160
|
+
);
|
|
161
|
+
process.exit(2);
|
|
162
|
+
}
|
|
163
|
+
// May be a single line or two lines (value continues on next line)
|
|
164
|
+
// End when we hit a line ending with `;`
|
|
165
|
+
const result = [];
|
|
166
|
+
for (let i = startIdx; i < lines.length; i++) {
|
|
167
|
+
result.push(lines[i]);
|
|
168
|
+
if (lines[i].trimEnd().endsWith(';')) break;
|
|
169
|
+
}
|
|
170
|
+
return result;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// z.enum and z.object const blocks — end when line is `);` at top indent level
|
|
174
|
+
function extractZodConst(lines, name) {
|
|
175
|
+
const startIdx = lines.findIndex((l) => {
|
|
176
|
+
// Match `export const <name>` or `const <name>`
|
|
177
|
+
return /^(?:export\s+)?const\s+/.test(l) && l.includes(`const ${name} =`);
|
|
178
|
+
});
|
|
179
|
+
if (startIdx === -1) {
|
|
180
|
+
process.stderr.write(
|
|
181
|
+
`sync-vault-schema: error: cannot find "const ${name}" in canonical file.\n`,
|
|
182
|
+
);
|
|
183
|
+
process.exit(2);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// For z.enum: ends with `]);` at column 0 or indented as part of enum
|
|
187
|
+
// For z.object: ends with `.passthrough();`
|
|
188
|
+
const result = [];
|
|
189
|
+
let depth = 0; // rough bracket depth
|
|
190
|
+
for (let i = startIdx; i < lines.length; i++) {
|
|
191
|
+
const l = lines[i];
|
|
192
|
+
result.push(l);
|
|
193
|
+
for (const ch of l) {
|
|
194
|
+
if (ch === '(' || ch === '[' || ch === '{') depth++;
|
|
195
|
+
if (ch === ')' || ch === ']' || ch === '}') depth--;
|
|
196
|
+
}
|
|
197
|
+
// Terminated when depth returns to 0 AND line ends with `;`
|
|
198
|
+
if (depth === 0 && l.trimEnd().endsWith(';')) break;
|
|
199
|
+
}
|
|
200
|
+
return result;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// ── Build generated block ────────────────────────────────────────────────────
|
|
204
|
+
function buildGeneratedBlock() {
|
|
205
|
+
const sections = [
|
|
206
|
+
extractRegexConst(canonicalLines, 'slugRegex'),
|
|
207
|
+
extractRegexConst(canonicalLines, 'tagPathRegex'),
|
|
208
|
+
extractRegexConst(canonicalLines, 'isoDateRegex'),
|
|
209
|
+
extractZodConst(canonicalLines, 'vaultNoteTypeSchema'),
|
|
210
|
+
extractZodConst(canonicalLines, 'vaultNoteStatusSchema'),
|
|
211
|
+
extractZodConst(canonicalLines, 'vaultFrontmatterSchema'),
|
|
212
|
+
];
|
|
213
|
+
|
|
214
|
+
const outputLines = [];
|
|
215
|
+
for (const section of sections) {
|
|
216
|
+
for (const rawLine of section) {
|
|
217
|
+
// Strip TypeScript-only syntax
|
|
218
|
+
const afterTs = stripTsLine(rawLine);
|
|
219
|
+
if (afterTs === null) continue;
|
|
220
|
+
// Strip JSDoc/block-comment lines
|
|
221
|
+
const afterComment = stripCommentLine(afterTs);
|
|
222
|
+
if (afterComment === null) continue;
|
|
223
|
+
outputLines.push(afterComment);
|
|
224
|
+
}
|
|
225
|
+
// Blank line between sections
|
|
226
|
+
outputLines.push('');
|
|
227
|
+
}
|
|
228
|
+
// Remove trailing blank line
|
|
229
|
+
while (outputLines.length > 0 && outputLines[outputLines.length - 1] === '') {
|
|
230
|
+
outputLines.pop();
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return outputLines.join('\n');
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// ── Locate / replace sentinel block in validator.mjs ─────────────────────────
|
|
237
|
+
function updateValidator(validatorContent, generatedBlock, _dryRun = false) {
|
|
238
|
+
const beginIdx = validatorContent.indexOf(SENTINEL_BEGIN);
|
|
239
|
+
const endIdx = validatorContent.indexOf(SENTINEL_END);
|
|
240
|
+
|
|
241
|
+
if (beginIdx !== -1 && endIdx === -1) {
|
|
242
|
+
process.stderr.write(
|
|
243
|
+
`sync-vault-schema: error: found BEGIN sentinel but missing END sentinel in validator.mjs.\n`,
|
|
244
|
+
);
|
|
245
|
+
process.exit(3);
|
|
246
|
+
}
|
|
247
|
+
if (beginIdx === -1 && endIdx !== -1) {
|
|
248
|
+
process.stderr.write(
|
|
249
|
+
`sync-vault-schema: error: found END sentinel but missing BEGIN sentinel in validator.mjs.\n`,
|
|
250
|
+
);
|
|
251
|
+
process.exit(3);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// Build the full replacement block (sentinels + content)
|
|
255
|
+
const fullBlock = `${SENTINEL_BEGIN}\n${generatedBlock}\n${SENTINEL_END}`;
|
|
256
|
+
|
|
257
|
+
let updatedContent;
|
|
258
|
+
|
|
259
|
+
if (beginIdx !== -1 && endIdx !== -1) {
|
|
260
|
+
// Sentinels exist — replace the range between (and including) them
|
|
261
|
+
const afterEnd = endIdx + SENTINEL_END.length;
|
|
262
|
+
updatedContent =
|
|
263
|
+
validatorContent.slice(0, beginIdx) + fullBlock + validatorContent.slice(afterEnd);
|
|
264
|
+
} else {
|
|
265
|
+
// First run — no sentinels yet. Locate the existing inline schema block.
|
|
266
|
+
// Search for `const slugRegex = ` as start anchor.
|
|
267
|
+
const inlineStart = validatorContent.indexOf('const slugRegex = ');
|
|
268
|
+
if (inlineStart === -1) {
|
|
269
|
+
process.stderr.write(
|
|
270
|
+
`sync-vault-schema: error: no sentinels found and cannot locate inline schema anchor "const slugRegex = " in validator.mjs.\n`,
|
|
271
|
+
);
|
|
272
|
+
process.exit(2);
|
|
273
|
+
}
|
|
274
|
+
// Find end: `.passthrough();` (the final line of vaultFrontmatterSchema)
|
|
275
|
+
const inlineEnd = validatorContent.indexOf('.passthrough();', inlineStart);
|
|
276
|
+
if (inlineEnd === -1) {
|
|
277
|
+
process.stderr.write(
|
|
278
|
+
`sync-vault-schema: error: found start anchor but cannot locate ".passthrough();" in validator.mjs.\n`,
|
|
279
|
+
);
|
|
280
|
+
process.exit(2);
|
|
281
|
+
}
|
|
282
|
+
// Include to the end of that line
|
|
283
|
+
const eolAfterEnd = validatorContent.indexOf('\n', inlineEnd);
|
|
284
|
+
const replaceEnd = eolAfterEnd !== -1 ? eolAfterEnd : validatorContent.length;
|
|
285
|
+
|
|
286
|
+
updatedContent =
|
|
287
|
+
validatorContent.slice(0, inlineStart) + fullBlock + validatorContent.slice(replaceEnd);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
return updatedContent;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
// ── Produce a simple unified diff (no external deps) ─────────────────────────
|
|
294
|
+
function unifiedDiff(labelA, labelB, linesA, linesB) {
|
|
295
|
+
// Naive line-by-line diff — sufficient for small schema blocks
|
|
296
|
+
const out = [`--- ${labelA}`, `+++ ${labelB}`];
|
|
297
|
+
const maxLen = Math.max(linesA.length, linesB.length);
|
|
298
|
+
let hasDiff = false;
|
|
299
|
+
for (let i = 0; i < maxLen; i++) {
|
|
300
|
+
const a = linesA[i];
|
|
301
|
+
const b = linesB[i];
|
|
302
|
+
if (a !== b) {
|
|
303
|
+
hasDiff = true;
|
|
304
|
+
if (a !== undefined) out.push(`-${a}`);
|
|
305
|
+
if (b !== undefined) out.push(`+${b}`);
|
|
306
|
+
} else {
|
|
307
|
+
out.push(` ${a}`);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
return { hasDiff, text: out.join('\n') };
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// ── Main ─────────────────────────────────────────────────────────────────────
|
|
314
|
+
const validatorContent = readFileSync(validatorPath, 'utf8');
|
|
315
|
+
const generatedBlock = buildGeneratedBlock();
|
|
316
|
+
|
|
317
|
+
if (isCheck) {
|
|
318
|
+
// Extract current block from validator (between sentinels or inline)
|
|
319
|
+
const beginIdx = validatorContent.indexOf(SENTINEL_BEGIN);
|
|
320
|
+
const endIdx = validatorContent.indexOf(SENTINEL_END);
|
|
321
|
+
|
|
322
|
+
let currentBlock;
|
|
323
|
+
if (beginIdx !== -1 && endIdx !== -1) {
|
|
324
|
+
// Content between sentinels (exclusive)
|
|
325
|
+
const afterBegin = validatorContent.indexOf('\n', beginIdx) + 1;
|
|
326
|
+
currentBlock = validatorContent.slice(afterBegin, endIdx).trimEnd();
|
|
327
|
+
} else if (beginIdx !== -1 || endIdx !== -1) {
|
|
328
|
+
// One sentinel missing
|
|
329
|
+
process.stderr.write(
|
|
330
|
+
`sync-vault-schema: error: malformed sentinels in validator.mjs (only one sentinel found).\n`,
|
|
331
|
+
);
|
|
332
|
+
process.exit(3);
|
|
333
|
+
} else {
|
|
334
|
+
// No sentinels — compare against inline schema region
|
|
335
|
+
const inlineStart = validatorContent.indexOf('const slugRegex = ');
|
|
336
|
+
const inlineEnd = validatorContent.indexOf('.passthrough();');
|
|
337
|
+
if (inlineStart === -1 || inlineEnd === -1) {
|
|
338
|
+
process.stderr.write(
|
|
339
|
+
`sync-vault-schema: error: cannot locate inline schema in validator.mjs for comparison.\n`,
|
|
340
|
+
);
|
|
341
|
+
process.exit(2);
|
|
342
|
+
}
|
|
343
|
+
const eolAfterEnd = validatorContent.indexOf('\n', inlineEnd);
|
|
344
|
+
currentBlock = validatorContent.slice(inlineStart, eolAfterEnd).trimEnd();
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
const { hasDiff, text } = unifiedDiff(
|
|
348
|
+
'validator.mjs (current)',
|
|
349
|
+
'canonical (generated)',
|
|
350
|
+
currentBlock.split('\n'),
|
|
351
|
+
generatedBlock.split('\n'),
|
|
352
|
+
);
|
|
353
|
+
|
|
354
|
+
if (hasDiff) {
|
|
355
|
+
process.stderr.write(`sync-vault-schema: drift detected between validator.mjs and canonical.\n\n`);
|
|
356
|
+
process.stderr.write(text + '\n');
|
|
357
|
+
process.exit(1);
|
|
358
|
+
} else {
|
|
359
|
+
process.stdout.write('sync-vault-schema: check passed — no drift detected.\n');
|
|
360
|
+
process.exit(0);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// --write mode (default)
|
|
365
|
+
const updatedContent = updateValidator(validatorContent, generatedBlock);
|
|
366
|
+
|
|
367
|
+
if (updatedContent === validatorContent) {
|
|
368
|
+
process.stdout.write('sync-vault-schema: synced: 0 changes (already up-to-date).\n');
|
|
369
|
+
process.exit(0);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
writeFileSync(validatorPath, updatedContent, 'utf8');
|
|
373
|
+
|
|
374
|
+
const newLines = generatedBlock.split('\n').length;
|
|
375
|
+
process.stdout.write(`sync-vault-schema: wrote: ${newLines} lines between sentinels.\n`);
|
|
376
|
+
process.exit(0);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Sample Baseline Rule (test fixture)
|
|
2
|
+
|
|
3
|
+
This file is used by scripts/tests/fetch-baseline.bats as the mocked response body
|
|
4
|
+
for the GitLab API raw-file endpoint. It has no real content — presence is enough
|
|
5
|
+
to verify the fetch + cache path.
|
|
6
|
+
|
|
7
|
+
- Rule ID: TEST-001
|
|
8
|
+
- Purpose: end-to-end fetch verification
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* tmux-layout — opt-in tmux visualization for operator-side session side-channels.
|
|
4
|
+
* Per ADR-0007 + GitLab #561. NOT a coordinator chat surface — Pane 1 is a scratch shell.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* node scripts/tmux-layout.mjs [options]
|
|
8
|
+
* tmux-layout [options] # via bin symlink
|
|
9
|
+
*
|
|
10
|
+
* Exit codes:
|
|
11
|
+
* 0 — success (layout rendered, one-liner printed)
|
|
12
|
+
* 1 — user-input error (invalid --layout, malformed --session-name, conflicting flags)
|
|
13
|
+
* 2 — system error (tmux not found, tmux version < 3.0, session collision without --force)
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { parseArgs } from 'node:util';
|
|
17
|
+
import { renderDefaultLayout, renderDebugLayout } from './lib/tmux-layout/layouts.mjs';
|
|
18
|
+
import { detectTmuxVersion } from './lib/tmux-layout/tmux-shell.mjs';
|
|
19
|
+
import { resolveStateDir } from './lib/platform.mjs';
|
|
20
|
+
import { readConfigFile, parseSessionConfig } from './lib/config.mjs';
|
|
21
|
+
|
|
22
|
+
const SCRIPT_VERSION = '0.1.0';
|
|
23
|
+
const VALID_LAYOUTS = ['default', 'debug'];
|
|
24
|
+
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
// Help text
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
|
|
29
|
+
function printHelp() {
|
|
30
|
+
return `Usage: tmux-layout [options]
|
|
31
|
+
|
|
32
|
+
-l, --layout <name> Layout variant: default | debug (default: default)
|
|
33
|
+
--session-name <s> Custom tmux session name (default: so-layout-<layout>)
|
|
34
|
+
-f, --force Replace existing tmux session (PSA-003 escape hatch)
|
|
35
|
+
--with-status-pane Add a 5th pane tailing agent-status telemetry (#565)
|
|
36
|
+
--json Machine-readable JSON output to stdout
|
|
37
|
+
-h, --help Show this help
|
|
38
|
+
-V, --version Show version
|
|
39
|
+
|
|
40
|
+
Opt-in operator-side tmux visualization substrate (ADR-0007).
|
|
41
|
+
Pane 1 is a SCRATCH SHELL — NOT a new claude session.
|
|
42
|
+
Your original (coordinator) terminal stays as-is.
|
|
43
|
+
See skills/tmux-layout/SKILL.md for pane details.
|
|
44
|
+
`;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// ---------------------------------------------------------------------------
|
|
48
|
+
// Argument parsing
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
|
|
51
|
+
function parseCliArgs(argv) {
|
|
52
|
+
return parseArgs({
|
|
53
|
+
args: argv,
|
|
54
|
+
options: {
|
|
55
|
+
layout: { type: 'string', short: 'l', default: 'default' },
|
|
56
|
+
'session-name': { type: 'string' },
|
|
57
|
+
force: { type: 'boolean', short: 'f', default: false },
|
|
58
|
+
'with-status-pane': { type: 'boolean', default: false },
|
|
59
|
+
json: { type: 'boolean', default: false },
|
|
60
|
+
help: { type: 'boolean', short: 'h', default: false },
|
|
61
|
+
version: { type: 'boolean', short: 'V', default: false },
|
|
62
|
+
},
|
|
63
|
+
allowPositionals: false,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
// Dispatch logic
|
|
69
|
+
// ---------------------------------------------------------------------------
|
|
70
|
+
|
|
71
|
+
async function dispatch({ values }) {
|
|
72
|
+
// (1) Handle --help / --version first — no validation needed
|
|
73
|
+
if (values.help) {
|
|
74
|
+
return { exitCode: 0, output: printHelp(), kind: 'help' };
|
|
75
|
+
}
|
|
76
|
+
if (values.version) {
|
|
77
|
+
return { exitCode: 0, output: SCRIPT_VERSION, kind: 'version' };
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// (2) Validate --layout
|
|
81
|
+
if (!VALID_LAYOUTS.includes(values.layout)) {
|
|
82
|
+
return {
|
|
83
|
+
exitCode: 1,
|
|
84
|
+
output: {
|
|
85
|
+
ok: false,
|
|
86
|
+
error: `Invalid --layout '${values.layout}' (must be one of: ${VALID_LAYOUTS.join(', ')})`,
|
|
87
|
+
exitCode: 1,
|
|
88
|
+
},
|
|
89
|
+
kind: 'json-error',
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// (3) Validate --session-name (no whitespace, no colons — tmux constraint)
|
|
94
|
+
const sessionName = values['session-name'] ?? `so-layout-${values.layout}`;
|
|
95
|
+
if (/[\s:]/.test(sessionName)) {
|
|
96
|
+
return {
|
|
97
|
+
exitCode: 1,
|
|
98
|
+
output: {
|
|
99
|
+
ok: false,
|
|
100
|
+
error: `Invalid --session-name '${sessionName}': must not contain whitespace or colons (tmux constraint)`,
|
|
101
|
+
exitCode: 1,
|
|
102
|
+
},
|
|
103
|
+
kind: 'json-error',
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// (4) Degradation pre-check: tmux availability
|
|
108
|
+
const ver = detectTmuxVersion();
|
|
109
|
+
if (!ver.available) {
|
|
110
|
+
return {
|
|
111
|
+
exitCode: 2,
|
|
112
|
+
output: {
|
|
113
|
+
ok: false,
|
|
114
|
+
error: 'tmux not found in $PATH',
|
|
115
|
+
exitCode: 2,
|
|
116
|
+
remediation: 'Install tmux ≥ 3.0 via: brew install tmux OR apt install tmux',
|
|
117
|
+
},
|
|
118
|
+
kind: 'json-error',
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// (5) Degradation pre-check: tmux version ≥ 3.0
|
|
123
|
+
if (!ver.satisfiesMin) {
|
|
124
|
+
return {
|
|
125
|
+
exitCode: 2,
|
|
126
|
+
output: {
|
|
127
|
+
ok: false,
|
|
128
|
+
error: `tmux version '${ver.version}' is below the 3.0 minimum required`,
|
|
129
|
+
exitCode: 2,
|
|
130
|
+
remediation: 'Upgrade tmux to ≥ 3.0 via: brew upgrade tmux OR apt upgrade tmux',
|
|
131
|
+
},
|
|
132
|
+
kind: 'json-error',
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// (6) Resolve project root + state dir (informational — passed to renderer)
|
|
137
|
+
const projectRoot = process.cwd();
|
|
138
|
+
const stateDir = resolveStateDir(); // uses SO_PLATFORM env detection
|
|
139
|
+
|
|
140
|
+
// (7) Load VCS config from Session Config (best-effort — fall back to defaults)
|
|
141
|
+
let vcsConfig = {};
|
|
142
|
+
try {
|
|
143
|
+
const mdContent = await readConfigFile(projectRoot);
|
|
144
|
+
const cfg = parseSessionConfig(mdContent);
|
|
145
|
+
vcsConfig = {
|
|
146
|
+
vcs: cfg['vcs'],
|
|
147
|
+
'gitlab-host': cfg['gitlab-host'],
|
|
148
|
+
mirror: cfg['mirror'],
|
|
149
|
+
};
|
|
150
|
+
} catch {
|
|
151
|
+
// Non-fatal: renderer can run without Session Config context
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// (8) Dispatch to layout renderer
|
|
155
|
+
const ctx = {
|
|
156
|
+
sessionName,
|
|
157
|
+
force: values.force,
|
|
158
|
+
withStatusPane: values['with-status-pane'],
|
|
159
|
+
projectRoot,
|
|
160
|
+
stateDir,
|
|
161
|
+
vcsConfig,
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
const result = values.layout === 'default'
|
|
165
|
+
? await renderDefaultLayout(ctx)
|
|
166
|
+
: await renderDebugLayout(ctx);
|
|
167
|
+
|
|
168
|
+
if (!result.ok) {
|
|
169
|
+
return {
|
|
170
|
+
exitCode: 2,
|
|
171
|
+
output: {
|
|
172
|
+
ok: false,
|
|
173
|
+
error: result.error ?? 'Layout render failed',
|
|
174
|
+
exitCode: 2,
|
|
175
|
+
...(result.remediation ? { remediation: result.remediation } : {}),
|
|
176
|
+
},
|
|
177
|
+
kind: 'json-error',
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return {
|
|
182
|
+
exitCode: 0,
|
|
183
|
+
output: {
|
|
184
|
+
ok: true,
|
|
185
|
+
sessionName,
|
|
186
|
+
layout: values.layout,
|
|
187
|
+
panes: result.panes,
|
|
188
|
+
degraded: result.degraded ?? false,
|
|
189
|
+
oneliner: result.oneliner,
|
|
190
|
+
},
|
|
191
|
+
kind: 'json-success',
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// ---------------------------------------------------------------------------
|
|
196
|
+
// Output + entry-point
|
|
197
|
+
// ---------------------------------------------------------------------------
|
|
198
|
+
|
|
199
|
+
async function main(argv) {
|
|
200
|
+
let parsed;
|
|
201
|
+
try {
|
|
202
|
+
parsed = parseCliArgs(argv);
|
|
203
|
+
} catch (err) {
|
|
204
|
+
process.stderr.write(`tmux-layout: ${err.message}\n\n${printHelp()}\n`);
|
|
205
|
+
return 1;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const result = await dispatch(parsed);
|
|
209
|
+
|
|
210
|
+
if (result.kind === 'help' || result.kind === 'version') {
|
|
211
|
+
process.stdout.write(result.output + '\n');
|
|
212
|
+
return result.exitCode;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (parsed.values.json) {
|
|
216
|
+
// --json: structured output to stdout, silence stderr notes
|
|
217
|
+
process.stdout.write(JSON.stringify(result.output) + '\n');
|
|
218
|
+
} else if (result.kind === 'json-success') {
|
|
219
|
+
// Human-readable: one-liner to stdout, usage note to stderr
|
|
220
|
+
process.stdout.write(result.output.oneliner + '\n');
|
|
221
|
+
process.stderr.write(
|
|
222
|
+
'\n' +
|
|
223
|
+
'# Paste the line above into a SECOND terminal.\n' +
|
|
224
|
+
'# Your original (coordinator) terminal stays as-is —\n' +
|
|
225
|
+
'# Pane 1 of the layout is a scratch shell, NOT a new claude session.\n' +
|
|
226
|
+
`# Session: ${result.output.sessionName} | Layout: ${result.output.layout} | Panes: ${result.output.panes}` +
|
|
227
|
+
(result.output.degraded ? ' | degraded: true' : '') +
|
|
228
|
+
'\n',
|
|
229
|
+
);
|
|
230
|
+
} else if (result.kind === 'json-error') {
|
|
231
|
+
process.stderr.write(`tmux-layout: ${result.output.error}\n`);
|
|
232
|
+
if (result.output.remediation) {
|
|
233
|
+
process.stderr.write(` Remediation: ${result.output.remediation}\n`);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return result.exitCode;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
main(process.argv.slice(2))
|
|
241
|
+
.then((code) => process.exit(code))
|
|
242
|
+
.catch((err) => {
|
|
243
|
+
process.stderr.write(`tmux-layout: fatal: ${err.message}\n${err.stack ?? ''}\n`);
|
|
244
|
+
process.exit(2);
|
|
245
|
+
});
|