session-orchestrator 3.24.0 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/architecture/SKILL.md +18 -0
- package/.agents/skills/autopilot/SKILL.md +17 -0
- package/.agents/skills/bootstrap/SKILL.md +20 -0
- package/.agents/skills/brainstorm/SKILL.md +22 -0
- package/.agents/skills/claude-md-drift-check/SKILL.md +15 -0
- package/.agents/skills/convergence-monitoring/SKILL.md +22 -0
- package/.agents/skills/debug/SKILL.md +22 -0
- package/.agents/skills/discovery/SKILL.md +20 -0
- package/.agents/skills/dispatcher/SKILL.md +15 -0
- package/.agents/skills/docs-orchestrator/SKILL.md +18 -0
- package/.agents/skills/ecosystem-health/SKILL.md +20 -0
- package/.agents/skills/eli5/SKILL.md +20 -0
- package/.agents/skills/eval/SKILL.md +21 -0
- package/.agents/skills/evolve/SKILL.md +21 -0
- package/.agents/skills/frontmatter-guard/SKILL.md +15 -0
- package/.agents/skills/gitlab-ops/SKILL.md +20 -0
- package/.agents/skills/gitlab-portfolio/SKILL.md +15 -0
- package/.agents/skills/grill/SKILL.md +22 -0
- package/.agents/skills/hook-development/SKILL.md +15 -0
- package/.agents/skills/mcp-builder/SKILL.md +15 -0
- package/.agents/skills/memory-cleanup/SKILL.md +21 -0
- package/.agents/skills/mode-selector/SKILL.md +17 -0
- package/.agents/skills/npm-publish/SKILL.md +16 -0
- package/.agents/skills/peekaboo-driver/SKILL.md +18 -0
- package/.agents/skills/persona-panel/SKILL.md +17 -0
- package/.agents/skills/plan/SKILL.md +20 -0
- package/.agents/skills/playwright-driver/SKILL.md +20 -0
- package/.agents/skills/quality-gates/SKILL.md +20 -0
- package/.agents/skills/reconcile/SKILL.md +21 -0
- package/.agents/skills/remote-offload/SKILL.md +20 -0
- package/.agents/skills/repo-audit/SKILL.md +16 -0
- package/.agents/skills/session-end/SKILL.md +20 -0
- package/.agents/skills/session-plan/SKILL.md +20 -0
- package/.agents/skills/session-start/SKILL.md +20 -0
- package/.agents/skills/spinout/SKILL.md +16 -0
- package/.agents/skills/sunset-review/SKILL.md +16 -0
- package/.agents/skills/test-runner/SKILL.md +20 -0
- package/.agents/skills/tmux-layout/SKILL.md +21 -0
- package/.agents/skills/using-orchestrator/SKILL.md +17 -0
- package/.agents/skills/vault-mirror/SKILL.md +15 -0
- package/.agents/skills/vault-sync/SKILL.md +15 -0
- package/.agents/skills/wave-executor/SKILL.md +20 -0
- package/.agents/skills/write-executable-plan/SKILL.md +22 -0
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +3 -2
- package/.codex-plugin/skills/architecture/SKILL.md +20 -0
- package/.codex-plugin/skills/autopilot/SKILL.md +21 -0
- package/.codex-plugin/skills/autopilot/agents/openai.yaml +5 -0
- package/.codex-plugin/skills/bootstrap/SKILL.md +22 -0
- package/.codex-plugin/skills/bootstrap/agents/openai.yaml +5 -0
- package/.codex-plugin/skills/brainstorm/SKILL.md +22 -0
- package/.codex-plugin/skills/brainstorm/agents/openai.yaml +5 -0
- package/.codex-plugin/skills/claude-md-drift-check/SKILL.md +17 -0
- package/.codex-plugin/skills/close/SKILL.md +21 -0
- package/.codex-plugin/skills/close/agents/openai.yaml +5 -0
- package/.codex-plugin/skills/convergence-monitoring/SKILL.md +24 -0
- package/.codex-plugin/skills/debug/SKILL.md +21 -0
- package/.codex-plugin/skills/debug/agents/openai.yaml +5 -0
- package/.codex-plugin/skills/discovery/SKILL.md +21 -0
- package/.codex-plugin/skills/discovery/agents/openai.yaml +5 -0
- package/.codex-plugin/skills/dispatcher/SKILL.md +21 -0
- package/.codex-plugin/skills/dispatcher/agents/openai.yaml +5 -0
- package/.codex-plugin/skills/docs-orchestrator/SKILL.md +20 -0
- package/.codex-plugin/skills/ecosystem-health/SKILL.md +22 -0
- package/.codex-plugin/skills/eli5/SKILL.md +21 -0
- package/.codex-plugin/skills/eli5/agents/openai.yaml +5 -0
- package/.codex-plugin/skills/eval/SKILL.md +21 -0
- package/.codex-plugin/skills/eval/agents/openai.yaml +5 -0
- package/.codex-plugin/skills/evolve/SKILL.md +21 -0
- package/.codex-plugin/skills/evolve/agents/openai.yaml +5 -0
- package/.codex-plugin/skills/frontmatter-guard/SKILL.md +17 -0
- package/.codex-plugin/skills/gitlab-ops/SKILL.md +22 -0
- package/.codex-plugin/skills/gitlab-portfolio/SKILL.md +17 -0
- package/.codex-plugin/skills/go/SKILL.md +22 -0
- package/.codex-plugin/skills/go/agents/openai.yaml +5 -0
- package/.codex-plugin/skills/grill/SKILL.md +21 -0
- package/.codex-plugin/skills/grill/agents/openai.yaml +5 -0
- package/.codex-plugin/skills/harness-audit/SKILL.md +19 -0
- package/.codex-plugin/skills/harness-audit/agents/openai.yaml +5 -0
- package/.codex-plugin/skills/hook-development/SKILL.md +17 -0
- package/.codex-plugin/skills/mcp-builder/SKILL.md +17 -0
- package/.codex-plugin/skills/memory-cleanup/SKILL.md +21 -0
- package/.codex-plugin/skills/memory-cleanup/agents/openai.yaml +5 -0
- package/.codex-plugin/skills/mode-selector/SKILL.md +19 -0
- package/.codex-plugin/skills/npm-publish/SKILL.md +18 -0
- package/.codex-plugin/skills/peekaboo-driver/SKILL.md +20 -0
- package/.codex-plugin/skills/persona-panel/SKILL.md +22 -0
- package/.codex-plugin/skills/persona-panel/agents/openai.yaml +5 -0
- package/.codex-plugin/skills/plan/SKILL.md +22 -0
- package/.codex-plugin/skills/plan/agents/openai.yaml +5 -0
- package/.codex-plugin/skills/playwright-driver/SKILL.md +22 -0
- package/.codex-plugin/skills/portfolio/SKILL.md +21 -0
- package/.codex-plugin/skills/portfolio/agents/openai.yaml +5 -0
- package/.codex-plugin/skills/quality-gates/SKILL.md +22 -0
- package/.codex-plugin/skills/reconcile/SKILL.md +21 -0
- package/.codex-plugin/skills/reconcile/agents/openai.yaml +5 -0
- package/.codex-plugin/skills/release/SKILL.md +22 -0
- package/.codex-plugin/skills/release/agents/openai.yaml +5 -0
- package/.codex-plugin/skills/remote-offload/SKILL.md +22 -0
- package/.codex-plugin/skills/repo-audit/SKILL.md +19 -0
- package/.codex-plugin/skills/repo-audit/agents/openai.yaml +5 -0
- package/.codex-plugin/skills/session/SKILL.md +21 -0
- package/.codex-plugin/skills/session/agents/openai.yaml +5 -0
- package/.codex-plugin/skills/session-end/SKILL.md +22 -0
- package/.codex-plugin/skills/session-plan/SKILL.md +22 -0
- package/.codex-plugin/skills/session-start/SKILL.md +22 -0
- package/.codex-plugin/skills/spinout/SKILL.md +21 -0
- package/.codex-plugin/skills/spinout/agents/openai.yaml +5 -0
- package/.codex-plugin/skills/sunset-review/SKILL.md +21 -0
- package/.codex-plugin/skills/sunset-review/agents/openai.yaml +5 -0
- package/.codex-plugin/skills/templates-ack/SKILL.md +21 -0
- package/.codex-plugin/skills/templates-ack/agents/openai.yaml +5 -0
- package/.codex-plugin/skills/test/SKILL.md +21 -0
- package/.codex-plugin/skills/test/agents/openai.yaml +5 -0
- package/.codex-plugin/skills/test-runner/SKILL.md +22 -0
- package/.codex-plugin/skills/tmux-layout/SKILL.md +23 -0
- package/.codex-plugin/skills/using-orchestrator/SKILL.md +19 -0
- package/.codex-plugin/skills/vault-mirror/SKILL.md +17 -0
- package/.codex-plugin/skills/vault-sync/SKILL.md +17 -0
- package/.codex-plugin/skills/wave-executor/SKILL.md +22 -0
- package/.codex-plugin/skills/write-executable-plan/SKILL.md +24 -0
- package/.cursor/commands/autopilot.md +2 -2
- package/.cursor/commands/bootstrap.md +1 -1
- package/.cursor/commands/brainstorm.md +1 -1
- package/.cursor/commands/debug.md +1 -1
- package/.cursor/commands/discovery.md +1 -1
- package/.cursor/commands/dispatcher.md +2 -2
- package/.cursor/commands/eli5.md +2 -2
- package/.cursor/commands/eval.md +2 -2
- package/.cursor/commands/evolve.md +1 -1
- package/.cursor/commands/go.md +1 -1
- package/.cursor/commands/grill.md +2 -2
- package/.cursor/commands/memory-cleanup.md +2 -2
- package/.cursor/commands/persona-panel.md +1 -1
- package/.cursor/commands/plan.md +1 -1
- package/.cursor/commands/portfolio.md +1 -1
- package/.cursor/commands/reconcile.md +2 -2
- package/.cursor/commands/release.md +2 -2
- package/.cursor/commands/session.md +2 -2
- package/.cursor/commands/spinout.md +2 -2
- package/.cursor/commands/sunset-review.md +2 -2
- package/.cursor/commands/templates-ack.md +2 -2
- package/.cursor/commands/test.md +2 -2
- package/.cursor/skills/brainstorm/SKILL.md +1 -1
- package/.cursor/skills/eval/SKILL.md +1 -1
- package/.cursor/skills/quality-gates/SKILL.md +1 -1
- package/.cursor/skills/remote-offload/SKILL.md +1 -1
- package/.cursor-plugin/plugin.json +30 -0
- package/.orchestrator/policy/blocked-commands.json +121 -0
- package/.orchestrator/policy/ecosystem.schema.json +66 -0
- package/.orchestrator/policy/quality-gates.example.json +16 -0
- package/.orchestrator/policy/quality-gates.schema.json +38 -0
- package/.orchestrator/policy/templates-policy.json +27 -0
- package/.orchestrator/policy/test-profiles.json +47 -0
- package/AGENTS.md +225 -0
- package/CHANGELOG.md +1314 -2
- package/NOTICE +11 -6
- package/README.md +135 -94
- package/agents/eval-judge.md +1 -1
- package/agents/skill-applied-judge.md +1 -1
- package/assets/wave-lifecycle.svg +98 -0
- package/commands/release.md +6 -3
- package/commands/session.md +18 -3
- package/docs/README.md +4 -0
- package/{agents/AGENTS.md → docs/agent-authoring.md} +19 -26
- package/docs/baseline.md +67 -0
- package/docs/ci-setup.md +108 -62
- package/docs/codex-setup.md +107 -29
- package/docs/components.md +38 -16
- package/docs/cursor-setup.md +6 -2
- package/docs/events-schema.md +9 -6
- package/docs/instruction-delivery.md +69 -0
- package/{agents/memory-proposal-collector.md → docs/memory-proposal-flow.md} +1 -8
- package/docs/migration-v4.md +365 -0
- package/docs/pi-setup.md +6 -1
- package/docs/plugin-architecture-v3.md +1 -1
- package/docs/rule-authoring.md +85 -19
- package/docs/scope-collision-guard.md +5 -5
- package/docs/session-config-reference.md +57 -56
- package/docs/session-config-template.md +6 -29
- package/docs/telemetry.md +157 -3
- package/docs/vault-docs-architecture.md +50 -11
- package/hooks/_lib/hook-import-set.json +1488 -0
- package/hooks/_lib/subagent-transcript.mjs +562 -0
- package/hooks/config-protection.mjs +2 -2
- package/hooks/cwd-change-restore.mjs +2 -2
- package/hooks/enforce-commands.mjs +69 -0
- package/hooks/hooks-codex.json +1 -1
- package/hooks/hooks-cursor.json +10 -0
- package/hooks/hooks-pi.json +5 -0
- package/hooks/hooks.json +6 -1
- package/hooks/loop-guard.mjs +3 -3
- package/hooks/on-session-end.mjs +2 -2
- package/hooks/on-session-start.mjs +103 -2
- package/hooks/on-stop.mjs +60 -14
- package/hooks/operator-steer.mjs +2 -2
- package/hooks/post-bash-write-verify.mjs +85 -0
- package/hooks/post-edit-import-probe.mjs +344 -0
- package/hooks/post-subagent-discovery-validator.mjs +187 -431
- package/hooks/post-tool-batch-wave-signal.mjs +118 -4
- package/hooks/post-tool-failure-corrective-context.mjs +2 -2
- package/hooks/post-tooluse-frontend-slop.mjs +3 -3
- package/hooks/pre-bash-destructive-guard.mjs +39 -13
- package/hooks/skill-invocation-telemetry.mjs +17 -5
- package/hooks/subagent-telemetry.mjs +13 -4
- package/monitors/monitors.json +3 -3
- package/package.json +9 -1
- package/pi/prompts/session.md +2 -2
- package/scripts/backfill-abandoned-sessions.mjs +50 -4
- package/scripts/backfill-learnings-from-vault.mjs +9 -3
- package/scripts/dialectic-deriver.mjs +73 -8
- package/scripts/export-hw-learnings.mjs +113 -1
- package/scripts/generate-agents-skills.mjs +378 -0
- package/scripts/generate-codex-skills.mjs +246 -0
- package/scripts/generate-cursor-adapter.mjs +45 -8
- package/scripts/generate-hook-import-set.mjs +292 -0
- package/scripts/lib/agent-status.mjs +13 -2
- package/scripts/lib/auto-dream.mjs +38 -36
- package/scripts/lib/autonomy/suitability.mjs +6 -0
- package/scripts/lib/autopilot/loop.mjs +2 -2
- package/scripts/lib/ci-status-banner.mjs +220 -75
- package/scripts/lib/codex/plugin-contract.mjs +88 -6
- package/scripts/lib/config/auto-dream.mjs +2 -1
- package/scripts/lib/config/block-header.mjs +8 -0
- package/scripts/lib/config/block-preprocess.mjs +177 -0
- package/scripts/lib/config/broken-window.mjs +2 -1
- package/scripts/lib/config/cold-start.mjs +2 -1
- package/scripts/lib/config/config-protection.mjs +22 -2
- package/scripts/lib/config/context-coverage.mjs +2 -1
- package/scripts/lib/config/cross-repo.mjs +2 -1
- package/scripts/lib/config/custom-phases.mjs +2 -1
- package/scripts/lib/config/dialectic.mjs +2 -1
- package/scripts/lib/config/discovery-validator.mjs +2 -1
- package/scripts/lib/config/dispatcher-autonomy-capture.mjs +24 -1
- package/scripts/lib/config/dispatcher-autonomy.mjs +2 -1
- package/scripts/lib/config/docs-orchestrator.mjs +2 -1
- package/scripts/lib/config/docs-staleness.mjs +2 -1
- package/scripts/lib/config/drift-check.mjs +2 -1
- package/scripts/lib/config/eval.mjs +2 -1
- package/scripts/lib/config/events-rotation.mjs +2 -1
- package/scripts/lib/config/evolve.mjs +8 -2
- package/scripts/lib/config/frontend-slop-hook.mjs +7 -3
- package/scripts/lib/config/gitlab-portfolio.mjs +2 -1
- package/scripts/lib/config/handover-gate.mjs +2 -1
- package/scripts/lib/config/health-endpoints.mjs +7 -2
- package/scripts/lib/config/host-paths.mjs +20 -4
- package/scripts/lib/config/issue-budget.mjs +2 -1
- package/scripts/lib/config/loop-guard.mjs +2 -1
- package/scripts/lib/config/memory.mjs +2 -1
- package/scripts/lib/config/moc-staleness.mjs +2 -1
- package/scripts/lib/config/persona-gate-wave.mjs +2 -1
- package/scripts/lib/config/private-config-dir.mjs +67 -0
- package/scripts/lib/config/reconcile.mjs +2 -1
- package/scripts/lib/config/remote-hosts.mjs +2 -1
- package/scripts/lib/config/section-extractor.mjs +7 -1
- package/scripts/lib/config/skill-evolution.mjs +2 -1
- package/scripts/lib/config/slopcheck.mjs +2 -1
- package/scripts/lib/config/state-md-lock.mjs +2 -1
- package/scripts/lib/config/templates-first.mjs +2 -1
- package/scripts/lib/config/test.mjs +2 -1
- package/scripts/lib/config/vault-integration.mjs +7 -1
- package/scripts/lib/config/vault-mirror-quality.mjs +2 -1
- package/scripts/lib/config/vault-staleness.mjs +2 -1
- package/scripts/lib/config/vault-sync.mjs +2 -1
- package/scripts/lib/config/verification-auto-fix.mjs +2 -1
- package/scripts/lib/config/wave-reviewers.mjs +2 -1
- package/scripts/lib/config/worktree-orphans.mjs +2 -1
- package/scripts/lib/convergence-monitor.mjs +82 -16
- package/scripts/lib/dispatcher/rank.mjs +124 -48
- package/scripts/lib/ecosystem-health.mjs +16 -2
- package/scripts/lib/eval/engine.mjs +9 -1
- package/scripts/lib/eval/session-resolve.mjs +23 -4
- package/scripts/lib/events.mjs +22 -6
- package/scripts/lib/frontmatter-guard.mjs +131 -13
- package/scripts/lib/gates/gate-full.mjs +30 -0
- package/scripts/lib/gates/gate-helpers.mjs +76 -0
- package/scripts/lib/hardware-pattern-detector.mjs +18 -1
- package/scripts/lib/harness-audit/categories/category4.mjs +31 -11
- package/scripts/lib/host-identity.mjs +50 -11
- package/scripts/lib/instruction-budget-guard.mjs +171 -5
- package/scripts/lib/learnings/evolve-telemetry.mjs +178 -0
- package/scripts/lib/learnings/io.mjs +60 -6
- package/scripts/lib/memory-proposals/store.mjs +30 -22
- package/scripts/lib/owner-config-banner.mjs +41 -6
- package/scripts/lib/owner-config-loader.mjs +21 -10
- package/scripts/lib/owner-interview.mjs +3 -3
- package/scripts/lib/owner-yaml.mjs +215 -15
- package/scripts/lib/platform.mjs +108 -15
- package/scripts/lib/plugin-update-banner.mjs +414 -0
- package/scripts/lib/project-hygiene.mjs +38 -2
- package/scripts/lib/qg-command-drift-banner.mjs +50 -12
- package/scripts/lib/quality-gate.mjs +133 -44
- package/scripts/lib/reconcile/emitter.mjs +68 -6
- package/scripts/lib/reconcile/engine.mjs +51 -11
- package/scripts/lib/reconcile/idempotency.mjs +37 -4
- package/scripts/lib/reconcile/writer.mjs +40 -18
- package/scripts/lib/session-close-backfill.mjs +67 -9
- package/scripts/lib/session-id.mjs +12 -23
- package/scripts/lib/session-identity/own-session.mjs +125 -10
- package/scripts/lib/session-lock-shape.mjs +43 -0
- package/scripts/lib/session-lock.mjs +5 -10
- package/scripts/lib/session-registry.mjs +25 -9
- package/scripts/lib/session-schema/constants.mjs +64 -3
- package/scripts/lib/session-schema/validator.mjs +38 -4
- package/scripts/lib/session-start-probes.mjs +30 -1
- package/scripts/lib/sessions-staleness-banner.mjs +18 -11
- package/scripts/lib/skill-health/join.mjs +17 -4
- package/scripts/lib/state-md.mjs +78 -0
- package/scripts/lib/sunset/walker.mjs +6 -0
- package/scripts/lib/telemetry/schema.mjs +202 -9
- package/scripts/lib/telemetry/sync.mjs +368 -12
- package/scripts/lib/telemetry-flush-health-banner.mjs +211 -0
- package/scripts/lib/validate/check-agents-skills.mjs +327 -0
- package/scripts/lib/validate/check-agents.mjs +3 -3
- package/scripts/lib/validate/check-codex-skills.mjs +191 -0
- package/scripts/lib/validate/check-cursor-adapter.mjs +234 -72
- package/scripts/lib/validate/check-hooks-symmetry.mjs +45 -16
- package/scripts/lib/validate/check-owner-leakage.mjs +319 -22
- package/scripts/lib/validate/check-skill-links.mjs +193 -0
- package/scripts/lib/validate/check-skill-script-paths.mjs +47 -28
- package/scripts/lib/validate/check-test-git-config-target.mjs +192 -12
- package/scripts/lib/validate/check-unwired-features.mjs +163 -15
- package/scripts/lib/validate/check-validator-registration.mjs +10 -4
- package/scripts/lib/validate/confidential-names.mjs +95 -30
- package/scripts/lib/validate/enumerate-repo-files.mjs +317 -0
- package/scripts/lib/validate/repo-files.mjs +48 -14
- package/scripts/lib/vault-backfill/template.mjs +63 -6
- package/scripts/lib/vault-mirror/process.mjs +165 -42
- package/scripts/lib/vault-mirror/telemetry.mjs +2 -2
- package/scripts/lib/vault-status/narrative-mirror.mjs +127 -18
- package/scripts/lib/wave-executor/dispatch-common.mjs +164 -0
- package/scripts/lib/wave-executor/foreign-dispatch.mjs +7 -142
- package/scripts/lib/wave-executor/remote-dispatch.mjs +5 -7
- package/scripts/lib/wave-resource-gate.mjs +8 -2
- package/scripts/lib/wave-sizing.mjs +4 -1
- package/scripts/lib/wave-transcript-tail.mjs +118 -4
- package/scripts/materialize-wave-scope.mjs +12 -5
- package/scripts/memory-propose.mjs +19 -5
- package/scripts/migrate-cold-start-seed.mjs +4 -1
- package/scripts/parse-config.mjs +60 -3
- package/scripts/release.mjs +430 -31
- package/scripts/repair-invalid-sessions.mjs +3 -3
- package/scripts/run-quality-gate.mjs +128 -11
- package/scripts/site-numbers.mjs +344 -8
- package/scripts/sweep-expired-learnings.mjs +90 -0
- package/scripts/sync-vault-schema.mjs +3 -1
- package/scripts/telemetry.mjs +2 -2
- package/scripts/validate-plugin.mjs +164 -0
- package/scripts/validate-wave-scope.mjs +28 -8
- package/scripts/wave-scope-binding.mjs +215 -0
- package/skills/_shared/instruction-file-resolution.md +10 -0
- package/skills/_shared/parallel-aware-preamble.md +1 -0
- package/skills/_shared/platform-tools.md +1 -1
- package/skills/_shared/state-ownership.md +1 -1
- package/skills/architecture/SKILL.md +7 -5
- package/skills/{domain-model/SKILL.md → architecture/references/domain-model.md} +9 -9
- package/skills/autopilot/SKILL.md +4 -18
- package/skills/claude-md-drift-check/SKILL.md +5 -1
- package/skills/claude-md-drift-check/checker.mjs +62 -2
- package/skills/convergence-monitoring/SIGNALS.md +55 -0
- package/skills/discovery/probes/vault-staleness.mjs +37 -13
- package/skills/discovery/probes-arch.md +20 -18
- package/skills/dispatcher/SKILL.md +3 -2
- package/skills/evolve/SKILL.md +65 -26
- package/skills/frontmatter-guard/SKILL.md +11 -5
- package/skills/npm-publish/SKILL.md +1 -1
- package/skills/reconcile/SKILL.md +33 -0
- package/skills/remote-offload/SKILL.md +1 -1
- package/skills/session-end/SKILL.md +18 -905
- package/skills/session-end/phase-3-6-tail.md +10 -3
- package/skills/session-end/plan-verification.md +221 -155
- package/skills/session-end/references/phase-2-quality-gate.md +93 -0
- package/skills/session-end/references/phase-3-documentation-updates.md +229 -0
- package/skills/session-end/references/phase-4a-worktree-cleanup.md +120 -0
- package/skills/session-end/references/phase-4b-worktree-orphan-sweep.md +58 -0
- package/skills/session-end/references/phase-5-issue-cleanup.md +104 -0
- package/skills/session-end/references/session-summary-template.md +62 -0
- package/skills/session-plan/SKILL.md +49 -0
- package/skills/session-start/SKILL.md +22 -904
- package/skills/session-start/phase-8-5-express-path.md +1 -1
- package/skills/session-start/references/phase-1-1-dispatcher-autonomy-capture.md +55 -0
- package/skills/session-start/references/phase-1-2-session-lock.md +140 -0
- package/skills/session-start/references/phase-1-5-session-continuity.md +254 -0
- package/skills/session-start/references/phase-1-7-vault-status-board.md +53 -0
- package/skills/session-start/references/phase-2-7-portfolio-snapshot.md +75 -0
- package/skills/session-start/references/phase-4-ssot-environment-check.md +160 -0
- package/skills/session-start/references/phase-6-5-forced-reads.md +75 -0
- package/skills/session-start/references/phase-6-6-project-intelligence.md +81 -0
- package/skills/session-start/references/phase-6-7-memory-banner-telemetry-consent.md +103 -0
- package/skills/vault-sync/SKILL.md +10 -0
- package/skills/vault-sync/validator.mjs +21 -27
- package/skills/wave-executor/SKILL.md +15 -1
- package/skills/wave-executor/references/wave-loop-dispatch.md +612 -0
- package/skills/wave-executor/references/wave-loop-review.md +570 -0
- package/skills/wave-executor/references/wave-loop-scope-manifest.md +162 -0
- package/skills/wave-executor/wave-loop.md +14 -1309
- package/templates/_shared/journey-manifest.md +10 -6
- package/.cursor/commands/autopilot-multi.md +0 -14
- package/.cursor/commands/contract-version-bump.md +0 -14
- package/.cursor/commands/journey-audit.md +0 -14
- package/.cursor/skills/contract-version-bump/SKILL.md +0 -12
- package/.cursor/skills/daily/SKILL.md +0 -12
- package/.cursor/skills/domain-model/SKILL.md +0 -13
- package/.cursor/skills/journey-audit/SKILL.md +0 -13
- package/.cursor/skills/skill-creator/SKILL.md +0 -13
- package/.cursor/skills/ubiquitous-language/SKILL.md +0 -13
- package/commands/autopilot-multi.md +0 -74
- package/commands/contract-version-bump.md +0 -28
- package/commands/journey-audit.md +0 -43
- package/pi/prompts/autopilot-multi.md +0 -12
- package/pi/prompts/contract-version-bump.md +0 -12
- package/pi/prompts/journey-audit.md +0 -12
- package/scripts/autopilot-multi.mjs +0 -885
- package/scripts/backfill-learnings-expires.mjs +0 -196
- package/scripts/backfill-learnings.mjs +0 -203
- package/scripts/fleet-instruction-scan.mjs +0 -141
- package/scripts/lib/autopilot/dep-graph.mjs +0 -417
- package/scripts/lib/autopilot/multi-killswitch.mjs +0 -184
- package/scripts/lib/webhook-url.mjs +0 -105
- package/scripts/lifecycle-sim-v6.mjs +0 -347
- package/scripts/migrate-learnings-jsonl.mjs +0 -189
- package/scripts/migrate-subagents-jsonl.mjs +0 -196
- package/scripts/upload-social-preview.mjs +0 -316
- package/skills/_shared/model-selection.md +0 -64
- package/skills/contract-version-bump/SKILL.md +0 -219
- package/skills/daily/SKILL.md +0 -222
- package/skills/daily/generate.sh +0 -92
- package/skills/daily/templates/daily.md.tpl +0 -36
- package/skills/journey-audit/SKILL.md +0 -270
- package/skills/skill-creator/SKILL.md +0 -168
- package/skills/ubiquitous-language/SKILL.md +0 -97
- package/skills/vault-sync/package-lock.json +0 -40
- /package/skills/{domain-model → architecture/references}/ADR-FORMAT.md +0 -0
- /package/skills/{domain-model → architecture/references}/CONTEXT-FORMAT.md +0 -0
|
@@ -38,26 +38,148 @@
|
|
|
38
38
|
*
|
|
39
39
|
* ── Exports ───────────────────────────────────────────────────────────────────
|
|
40
40
|
*
|
|
41
|
-
*
|
|
41
|
+
* resolvePrivateConfigDir({env}?) — THE host-private config dir resolver (#1223)
|
|
42
|
+
* resolveOwnerYamlPath(env?) — owner.yaml path, resolved at CALL time (#1223)
|
|
42
43
|
* validateOwnerSections(obj) — pure validation, no I/O; bucketed per section (#820)
|
|
43
44
|
* validateOwnerConfig(obj) — pure validation, no I/O; thin wrapper over validateOwnerSections
|
|
44
45
|
* loadOwnerConfig({path?}) — reads file; per-section tolerance for OPTIONAL
|
|
45
46
|
* sections (paths/dispatcher/vaults/baselines) — #820
|
|
46
47
|
* writeOwnerConfig(config, {path?}) — validates, writes YAML, creates dir
|
|
47
48
|
* getDefaults() — returns sensible default config object
|
|
49
|
+
*
|
|
50
|
+
* ── Zero bare-specifier imports (GH#62/#63, GitLab #1230) ────────────────────
|
|
51
|
+
*
|
|
52
|
+
* `js-yaml` is resolved LAZILY inside {@link loadOwnerConfig} / {@link
|
|
53
|
+
* writeOwnerConfig} (see {@link getYaml}), never at module load. Importing this
|
|
54
|
+
* module therefore costs `node:fs` + `node:path` + `node:module` and nothing
|
|
55
|
+
* else, which is what keeps it safe on the hook import graph: before this
|
|
56
|
+
* change, `import yaml from 'js-yaml'` at the top of this file crashed FOUR
|
|
57
|
+
* hooks with `ERR_MODULE_NOT_FOUND` for anyone whose `node_modules` was absent
|
|
58
|
+
* (on-session-start, on-session-end, post-edit-validate,
|
|
59
|
+
* skill-invocation-telemetry — measured 2026-09-06 over a `hooks/` + `scripts/`
|
|
60
|
+
* copy with no `node_modules`, 4 of 27 hooks rc=1).
|
|
61
|
+
*
|
|
62
|
+
* When the package cannot be resolved both entry points DEGRADE rather than
|
|
63
|
+
* throw: they return their normal shape plus `reason: 'yaml-parser-missing'`
|
|
64
|
+
* (`source: 'defaults'` / `written: false`) and emit ONE rate-limited stderr
|
|
65
|
+
* WARN naming `npm install` as the fix.
|
|
48
66
|
*/
|
|
49
67
|
|
|
50
68
|
import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
|
|
51
69
|
import { join, dirname } from 'node:path';
|
|
52
|
-
import {
|
|
53
|
-
import
|
|
70
|
+
import { createRequire } from 'node:module';
|
|
71
|
+
import { resolvePrivateConfigDir } from './config/private-config-dir.mjs';
|
|
54
72
|
|
|
55
73
|
// ---------------------------------------------------------------------------
|
|
56
74
|
// Constants
|
|
57
75
|
// ---------------------------------------------------------------------------
|
|
58
76
|
|
|
59
|
-
/**
|
|
60
|
-
|
|
77
|
+
/** Basename of the owner persona config file. */
|
|
78
|
+
const OWNER_YAML_FILE = 'owner.yaml';
|
|
79
|
+
|
|
80
|
+
// ---------------------------------------------------------------------------
|
|
81
|
+
// Lazy js-yaml resolution (GH#62/#63, GitLab #1230)
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Memoised `js-yaml` module, or `false` once resolution has failed.
|
|
86
|
+
* `null` = not yet attempted.
|
|
87
|
+
* @type {null | false | { load: Function, dump: Function }}
|
|
88
|
+
*/
|
|
89
|
+
let _yaml = null;
|
|
90
|
+
|
|
91
|
+
/** Guards the one-per-process stderr WARN below. */
|
|
92
|
+
let _yamlWarned = false;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Resolve `js-yaml` at CALL time instead of at import time (GH#62/#63).
|
|
96
|
+
*
|
|
97
|
+
* WHY `createRequire` and not `await import('js-yaml')`: every caller of
|
|
98
|
+
* {@link loadOwnerConfig} consumes it SYNCHRONOUSLY. Measured 2026-09-06 with
|
|
99
|
+
* `rg -n --glob '!tests/**' 'loadOwnerConfig\(' scripts hooks skills` (minus
|
|
100
|
+
* this file and the unrelated async homonym in `owner-config-loader.mjs`):
|
|
101
|
+
* 9 call sites — 8 in code, 1 in `skills/session-start/SKILL.md:1113` — and
|
|
102
|
+
* `rg 'await\s+loadOwnerConfig'` over the same scope returns ZERO. Eight read
|
|
103
|
+
* `loadOwnerConfig().config` (`hooks/on-session-start.mjs:639`,
|
|
104
|
+
* `hooks/skill-invocation-telemetry.mjs:155`, `scripts/telemetry.mjs:81,130`,
|
|
105
|
+
* `scripts/vault-mirror.mjs:444`, `scripts/lib/telemetry/sync.mjs:202,269`,
|
|
106
|
+
* and the SKILL.md snippet); the ninth destructures the same sync return
|
|
107
|
+
* (`scripts/lib/soul-resolve.mjs:123`). `writeOwnerConfig` is likewise sync at
|
|
108
|
+
* its single call site, `scripts/lib/owner-interview.mjs:228`.
|
|
109
|
+
*
|
|
110
|
+
* Making either loader async would be a breaking change to all of them; a lazy
|
|
111
|
+
* `require()` keeps the sync contract and only fails at CALL time — where the
|
|
112
|
+
* failure is catchable — instead of at module load, where it is not.
|
|
113
|
+
*
|
|
114
|
+
* Same shape as the `getPicomatch()` pattern in `scripts/lib/rule-loader.mjs`
|
|
115
|
+
* and `scripts/lib/validate-vendored-rules.mjs`.
|
|
116
|
+
*
|
|
117
|
+
* @returns {{ load: Function, dump: Function } | null} the module, or `null`
|
|
118
|
+
* when `node_modules` is absent / the package cannot be resolved.
|
|
119
|
+
*/
|
|
120
|
+
function getYaml() {
|
|
121
|
+
if (_yaml !== null) return _yaml === false ? null : _yaml;
|
|
122
|
+
try {
|
|
123
|
+
_yaml = createRequire(import.meta.url)('js-yaml');
|
|
124
|
+
} catch {
|
|
125
|
+
_yaml = false;
|
|
126
|
+
}
|
|
127
|
+
return _yaml === false ? null : _yaml;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Emit the one-per-process actionable WARN for a missing `js-yaml`. Kept to a
|
|
132
|
+
* SINGLE line and rate-limited to once per process, mirroring the GH#63
|
|
133
|
+
* degradation contract `hooks/on-stop.mjs` already satisfies: a missing package
|
|
134
|
+
* must never be louder than the fix it asks for.
|
|
135
|
+
*/
|
|
136
|
+
function warnYamlMissing() {
|
|
137
|
+
if (_yamlWarned) return;
|
|
138
|
+
_yamlWarned = true;
|
|
139
|
+
console.warn(
|
|
140
|
+
"WARN owner-yaml: 'js-yaml' is not installed — owner.yaml cannot be parsed or written; " +
|
|
141
|
+
"using defaults. Run 'npm install' in the plugin directory to restore it.",
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Re-export of the single host-private-config-dir resolver (#1223).
|
|
147
|
+
*
|
|
148
|
+
* The implementation lives in the ZERO-IMPORT leaf
|
|
149
|
+
* `scripts/lib/config/private-config-dir.mjs`, NOT here: `host-identity.mjs`
|
|
150
|
+
* sits on `hooks/on-stop.mjs`'s import subgraph (via `session-lock.mjs`), and
|
|
151
|
+
* this module statically imports `js-yaml`. While the resolver lived here,
|
|
152
|
+
* importing it from `host-identity.mjs` dragged `js-yaml` onto THAT subgraph and
|
|
153
|
+
* broke the GH#63 "degrade gracefully without node_modules" contract
|
|
154
|
+
* (`ERR_MODULE_NOT_FOUND` in `tests/hooks/on-stop.test.mjs`).
|
|
155
|
+
*
|
|
156
|
+
* As of GitLab #1230 (2026-09-06) THIS module is no longer a bare-specifier node
|
|
157
|
+
* on that graph either: the `js-yaml` import it used to carry statically is now
|
|
158
|
+
* lazy (see {@link getYaml}), so the four hooks that reach this file —
|
|
159
|
+
* on-session-start, on-session-end, post-edit-validate,
|
|
160
|
+
* skill-invocation-telemetry — load without `node_modules` instead of dying with
|
|
161
|
+
* ERR_MODULE_NOT_FOUND. Keep it that way: any NEW static bare import added here
|
|
162
|
+
* re-breaks all four at once, in a file whose own unit tests would never notice
|
|
163
|
+
* (the repo always has `node_modules`).
|
|
164
|
+
*
|
|
165
|
+
* NOTE for `tests/husky/pre-commit-owner-leakage.test.mjs`: that test copies
|
|
166
|
+
* the CP11 import chain FILE BY FILE into a tmp repo, so the leaf below is on
|
|
167
|
+
* its copied-file list. Any FURTHER repo-local import added here needs the same
|
|
168
|
+
* treatment.
|
|
169
|
+
*/
|
|
170
|
+
export { resolvePrivateConfigDir };
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Resolve the owner.yaml path at CALL time via the single private-config-dir
|
|
174
|
+
* resolver {@link resolvePrivateConfigDir} (#1223). Honours
|
|
175
|
+
* `SO_CONFIG_HOME` > `XDG_CONFIG_HOME` > homedir, each trimmed.
|
|
176
|
+
*
|
|
177
|
+
* @param {Record<string, string|undefined>} [env] — env source (default `process.env`)
|
|
178
|
+
* @returns {string} absolute path to owner.yaml
|
|
179
|
+
*/
|
|
180
|
+
export function resolveOwnerYamlPath(env = process.env) {
|
|
181
|
+
return join(resolvePrivateConfigDir({ env }), OWNER_YAML_FILE);
|
|
182
|
+
}
|
|
61
183
|
|
|
62
184
|
const VALID_LANGUAGES = /** @type {const} */ (['de', 'en']);
|
|
63
185
|
const VALID_TONE_STYLES = /** @type {const} */ (['direct', 'neutral', 'friendly']);
|
|
@@ -74,8 +196,15 @@ const REQUIRED_SECTIONS = /** @type {const} */ (['owner', 'tone', 'efficiency',
|
|
|
74
196
|
* OPTIONAL object sections (#820) — a malformed entry is replaced by its
|
|
75
197
|
* `getDefaults()` value and reported via `droppedSections` + a stderr WARN,
|
|
76
198
|
* but does NOT discard the rest of the file.
|
|
199
|
+
*
|
|
200
|
+
* Exported (#1262.4) as the SSOT for consumers that must iterate exactly these
|
|
201
|
+
* sections — currently `scripts/lib/owner-config-banner.mjs`, which derived the
|
|
202
|
+
* #1244 "survived a whole-file discard" set from a hand-mirrored local copy.
|
|
203
|
+
* Frozen so a consumer cannot mutate the shared array.
|
|
77
204
|
*/
|
|
78
|
-
const OPTIONAL_OBJECT_SECTIONS = /** @type {const} */ (
|
|
205
|
+
export const OPTIONAL_OBJECT_SECTIONS = /** @type {const} */ (
|
|
206
|
+
Object.freeze(['paths', 'dispatcher'])
|
|
207
|
+
);
|
|
79
208
|
|
|
80
209
|
/**
|
|
81
210
|
* OPTIONAL list sections (#820) — malformed entries are passed through
|
|
@@ -418,19 +547,43 @@ export function validateOwnerConfig(obj) {
|
|
|
418
547
|
* surfaced only via `sectionWarnings` (never dropped, never counted towards
|
|
419
548
|
* `'partial'`).
|
|
420
549
|
*
|
|
550
|
+
* MERGE RULE for the whole-file discard (GitLab #1244). The discard returns
|
|
551
|
+
* `getDefaults()` — but a VALID optional object section is merged back on top
|
|
552
|
+
* of its default (`{...defaults[name], ...parsed[name]}`), key by key. `source`
|
|
553
|
+
* stays `'defaults'` and `errors` still carries every required-section error,
|
|
554
|
+
* so no existing caller's branch changes; what changes is that a host-local
|
|
555
|
+
* path the operator DID declare correctly is no longer thrown away because an
|
|
556
|
+
* unrelated section (e.g. `tone:`) is malformed. That silent loss was a
|
|
557
|
+
* fail-OPEN path for the owner-leakage scanner's CP11 rule: a partial
|
|
558
|
+
* owner.yaml carrying only `owner:` + `paths.confidential-names-file:` made the
|
|
559
|
+
* scanner report PASS while matching nothing. An INVALID optional section is
|
|
560
|
+
* still replaced by its default and is now reported via `droppedSections` on
|
|
561
|
+
* this branch too (previously only on the required-valid branch), so a consumer
|
|
562
|
+
* can tell "not configured" from "configured but unusable".
|
|
563
|
+
*
|
|
421
564
|
* Defensive — never throws.
|
|
422
565
|
*
|
|
566
|
+
* When `js-yaml` cannot be resolved (no `node_modules`), returns defaults with
|
|
567
|
+
* `source: 'defaults'`, `reason: 'yaml-parser-missing'` and one explanatory
|
|
568
|
+
* entry in `errors` — never throws, never crashes the importing hook (GH#62/#63).
|
|
569
|
+
* When the file exists but cannot be turned into an object at all (unreadable,
|
|
570
|
+
* YAML syntax error, non-mapping top level) the same shape is returned with
|
|
571
|
+
* `reason: 'unparseable'`: in that state NOTHING about the file's contents is
|
|
572
|
+
* knowable, which is the distinction CP11 needs in order to fail CLOSED rather
|
|
573
|
+
* than assume "nothing configured".
|
|
574
|
+
*
|
|
423
575
|
* @param {{ path?: string }} [opts]
|
|
424
576
|
* @returns {{
|
|
425
577
|
* config: object,
|
|
426
578
|
* source: 'file'|'defaults'|'partial',
|
|
427
579
|
* errors: string[],
|
|
580
|
+
* reason?: 'yaml-parser-missing'|'unparseable',
|
|
428
581
|
* droppedSections?: Array<{ section: string, errors: string[] }>,
|
|
429
582
|
* sectionWarnings?: Array<{ section: string, errors: string[] }>,
|
|
430
583
|
* }}
|
|
431
584
|
*/
|
|
432
585
|
export function loadOwnerConfig(opts = {}) {
|
|
433
|
-
const filePath = opts.path ??
|
|
586
|
+
const filePath = opts.path ?? resolveOwnerYamlPath();
|
|
434
587
|
|
|
435
588
|
if (!existsSync(filePath)) {
|
|
436
589
|
return { config: getDefaults(), source: 'defaults', errors: [] };
|
|
@@ -443,10 +596,24 @@ export function loadOwnerConfig(opts = {}) {
|
|
|
443
596
|
return {
|
|
444
597
|
config: getDefaults(),
|
|
445
598
|
source: 'defaults',
|
|
599
|
+
reason: 'unparseable',
|
|
446
600
|
errors: [`failed to read owner.yaml: ${err.message}`],
|
|
447
601
|
};
|
|
448
602
|
}
|
|
449
603
|
|
|
604
|
+
const yaml = getYaml();
|
|
605
|
+
if (!yaml) {
|
|
606
|
+
warnYamlMissing();
|
|
607
|
+
return {
|
|
608
|
+
config: getDefaults(),
|
|
609
|
+
source: 'defaults',
|
|
610
|
+
reason: 'yaml-parser-missing',
|
|
611
|
+
errors: [
|
|
612
|
+
"yaml-parser-missing: 'js-yaml' is not installed, so owner.yaml could not be parsed (run 'npm install' in the plugin directory)",
|
|
613
|
+
],
|
|
614
|
+
};
|
|
615
|
+
}
|
|
616
|
+
|
|
450
617
|
let parsed;
|
|
451
618
|
try {
|
|
452
619
|
parsed = yaml.load(raw);
|
|
@@ -454,6 +621,7 @@ export function loadOwnerConfig(opts = {}) {
|
|
|
454
621
|
return {
|
|
455
622
|
config: getDefaults(),
|
|
456
623
|
source: 'defaults',
|
|
624
|
+
reason: 'unparseable',
|
|
457
625
|
errors: [`YAML parse error: ${err.message}`],
|
|
458
626
|
};
|
|
459
627
|
}
|
|
@@ -462,20 +630,36 @@ export function loadOwnerConfig(opts = {}) {
|
|
|
462
630
|
return {
|
|
463
631
|
config: getDefaults(),
|
|
464
632
|
source: 'defaults',
|
|
633
|
+
reason: 'unparseable',
|
|
465
634
|
errors: ['owner.yaml must contain a YAML mapping at the top level'],
|
|
466
635
|
};
|
|
467
636
|
}
|
|
468
637
|
|
|
469
638
|
const { sections, errors: allErrors } = validateOwnerSections(parsed);
|
|
470
639
|
|
|
471
|
-
// Any REQUIRED section invalid →
|
|
640
|
+
// Any REQUIRED section invalid → whole-file discard (#820), EXCEPT that a
|
|
641
|
+
// VALID optional object section is merged back onto its default (#1244 — see
|
|
642
|
+
// the MERGE RULE in the JSDoc above). `source` stays 'defaults' and `errors`
|
|
643
|
+
// is unchanged, so every existing caller branch is untouched; only the
|
|
644
|
+
// discarded-but-valid `paths:`/`dispatcher:` keys survive, which is what stops
|
|
645
|
+
// CP11 from going silently inert on a partial owner.yaml.
|
|
472
646
|
const requiredInvalid = REQUIRED_SECTIONS.some((name) => !sections[name]?.valid);
|
|
473
647
|
if (requiredInvalid) {
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
648
|
+
const discardConfig = getDefaults();
|
|
649
|
+
const discardDropped = [];
|
|
650
|
+
for (const name of OPTIONAL_OBJECT_SECTIONS) {
|
|
651
|
+
const sec = sections[name];
|
|
652
|
+
if (sec?.valid && isPlainObject(parsed[name])) {
|
|
653
|
+
discardConfig[name] = { ...discardConfig[name], ...parsed[name] };
|
|
654
|
+
} else if (sec && !sec.valid) {
|
|
655
|
+
// Present but malformed — already replaced by its default above. Report
|
|
656
|
+
// it so a consumer can distinguish "not configured" from "unusable".
|
|
657
|
+
discardDropped.push({ section: name, errors: sec.errors });
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
const discardResult = { config: discardConfig, source: 'defaults', errors: allErrors };
|
|
661
|
+
if (discardDropped.length > 0) discardResult.droppedSections = discardDropped;
|
|
662
|
+
return discardResult;
|
|
479
663
|
}
|
|
480
664
|
|
|
481
665
|
// All REQUIRED sections valid — tolerate malformed OPTIONAL sections instead
|
|
@@ -532,12 +716,16 @@ export function loadOwnerConfig(opts = {}) {
|
|
|
532
716
|
*
|
|
533
717
|
* Synchronous. Defensive — never throws.
|
|
534
718
|
*
|
|
719
|
+
* When `js-yaml` cannot be resolved (no `node_modules`), returns
|
|
720
|
+
* `{ written: false, reason: 'yaml-parser-missing', errors: [...] }` — the file
|
|
721
|
+
* is left untouched rather than half-written (GH#62/#63).
|
|
722
|
+
*
|
|
535
723
|
* @param {object} config
|
|
536
724
|
* @param {{ path?: string }} [opts]
|
|
537
|
-
* @returns {{ written: boolean, errors: string[] }}
|
|
725
|
+
* @returns {{ written: boolean, errors: string[], reason?: 'yaml-parser-missing' }}
|
|
538
726
|
*/
|
|
539
727
|
export function writeOwnerConfig(config, opts = {}) {
|
|
540
|
-
const filePath = opts.path ??
|
|
728
|
+
const filePath = opts.path ?? resolveOwnerYamlPath();
|
|
541
729
|
|
|
542
730
|
const validation = validateOwnerConfig(config);
|
|
543
731
|
if (!validation.valid) {
|
|
@@ -554,6 +742,18 @@ export function writeOwnerConfig(config, opts = {}) {
|
|
|
554
742
|
};
|
|
555
743
|
}
|
|
556
744
|
|
|
745
|
+
const yaml = getYaml();
|
|
746
|
+
if (!yaml) {
|
|
747
|
+
warnYamlMissing();
|
|
748
|
+
return {
|
|
749
|
+
written: false,
|
|
750
|
+
reason: 'yaml-parser-missing',
|
|
751
|
+
errors: [
|
|
752
|
+
"yaml-parser-missing: 'js-yaml' is not installed, so owner.yaml could not be written (run 'npm install' in the plugin directory)",
|
|
753
|
+
],
|
|
754
|
+
};
|
|
755
|
+
}
|
|
756
|
+
|
|
557
757
|
let yamlStr;
|
|
558
758
|
try {
|
|
559
759
|
yamlStr = yaml.dump(config, { lineWidth: 120, noRefs: true });
|
package/scripts/lib/platform.mjs
CHANGED
|
@@ -2,10 +2,15 @@
|
|
|
2
2
|
* platform.mjs — platform detection for session-orchestrator (Node.js port of platform.sh)
|
|
3
3
|
* ESM-importable. Uses only Node built-ins. No external dependencies.
|
|
4
4
|
*
|
|
5
|
-
* Exports
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* Exports:
|
|
6
|
+
* - lazy memoized accessors (#1153 P5): getPlatform, getPluginRoot, getProjectDir,
|
|
7
|
+
* getStateDir, getConfigFile (+ test-only _resetPlatformCache)
|
|
8
|
+
* - plain constants (no filesystem work): SO_SHARED_DIR, SO_OS, SO_IS_WINDOWS,
|
|
9
|
+
* SO_IS_WSL, SO_PATH_SEP
|
|
10
|
+
* - pure resolvers: detectPlatform, resolvePluginRoot, resolveProjectDir,
|
|
11
|
+
* resolveStateDir, resolveConfigFile
|
|
12
|
+
*
|
|
13
|
+
* NOTHING in this module touches the filesystem at import time.
|
|
9
14
|
*/
|
|
10
15
|
|
|
11
16
|
import { existsSync, statSync } from 'node:fs';
|
|
@@ -293,23 +298,111 @@ export function resolveConfigFile(platform) {
|
|
|
293
298
|
}
|
|
294
299
|
|
|
295
300
|
// ---------------------------------------------------------------------------
|
|
296
|
-
//
|
|
301
|
+
// Lazy, memoized accessors (#1153 P5)
|
|
297
302
|
// ---------------------------------------------------------------------------
|
|
303
|
+
//
|
|
304
|
+
// These five values used to be `export const … = detect…()` evaluated at MODULE
|
|
305
|
+
// LOAD, so every one of the ~31 static importers — including the hottest
|
|
306
|
+
// deny-capable hooks, which run on every single tool call — paid a filesystem
|
|
307
|
+
// walk-up (statSync/existsSync per ancestor directory, twice over for
|
|
308
|
+
// resolvePluginRoot) merely for importing this module, whether or not it ever
|
|
309
|
+
// read the value.
|
|
310
|
+
//
|
|
311
|
+
// They are now computed on FIRST USE and memoized. Call the getter at the point
|
|
312
|
+
// of use, never at a module's top level — a top-level `const X = getProjectDir()`
|
|
313
|
+
// re-creates the exact cost this change removes.
|
|
298
314
|
|
|
299
|
-
/**
|
|
300
|
-
|
|
315
|
+
/**
|
|
316
|
+
* Memo slots. `undefined` is the miss sentinel — `''` is a legitimate
|
|
317
|
+
* resolvePluginRoot() result and must not re-trigger resolution.
|
|
318
|
+
* @type {{platform: ("claude"|"codex"|"cursor"|"pi")|undefined, pluginRoot: string|undefined, projectDir: string|undefined, stateDir: string|undefined, configFile: string|undefined}}
|
|
319
|
+
*/
|
|
320
|
+
const _cache = {
|
|
321
|
+
platform: undefined,
|
|
322
|
+
pluginRoot: undefined,
|
|
323
|
+
projectDir: undefined,
|
|
324
|
+
stateDir: undefined,
|
|
325
|
+
configFile: undefined,
|
|
326
|
+
};
|
|
301
327
|
|
|
302
|
-
/**
|
|
303
|
-
|
|
328
|
+
/**
|
|
329
|
+
* Host platform, detected once per process.
|
|
330
|
+
* @returns {"claude"|"codex"|"cursor"|"pi"}
|
|
331
|
+
*/
|
|
332
|
+
export function getPlatform() {
|
|
333
|
+
if (_cache.platform === undefined) {
|
|
334
|
+
_cache.platform = detectPlatform();
|
|
335
|
+
}
|
|
336
|
+
return _cache.platform;
|
|
337
|
+
}
|
|
304
338
|
|
|
305
|
-
/**
|
|
306
|
-
|
|
339
|
+
/**
|
|
340
|
+
* Absolute path to the session-orchestrator plugin directory, resolved once.
|
|
341
|
+
* @returns {string} Absolute path, or empty string if unresolvable.
|
|
342
|
+
*/
|
|
343
|
+
export function getPluginRoot() {
|
|
344
|
+
if (_cache.pluginRoot === undefined) {
|
|
345
|
+
_cache.pluginRoot = resolvePluginRoot(getPlatform());
|
|
346
|
+
}
|
|
347
|
+
return _cache.pluginRoot;
|
|
348
|
+
}
|
|
307
349
|
|
|
308
|
-
/**
|
|
309
|
-
|
|
350
|
+
/**
|
|
351
|
+
* Absolute path to the current project root, resolved once.
|
|
352
|
+
* @returns {string}
|
|
353
|
+
*/
|
|
354
|
+
export function getProjectDir() {
|
|
355
|
+
if (_cache.projectDir === undefined) {
|
|
356
|
+
_cache.projectDir = resolveProjectDir(getPlatform());
|
|
357
|
+
}
|
|
358
|
+
return _cache.projectDir;
|
|
359
|
+
}
|
|
310
360
|
|
|
311
|
-
/**
|
|
312
|
-
|
|
361
|
+
/**
|
|
362
|
+
* Platform-native state directory name (".claude" | ".codex" | ".cursor" | ".pi").
|
|
363
|
+
* @returns {string}
|
|
364
|
+
*/
|
|
365
|
+
export function getStateDir() {
|
|
366
|
+
if (_cache.stateDir === undefined) {
|
|
367
|
+
_cache.stateDir = resolveStateDir(getPlatform());
|
|
368
|
+
}
|
|
369
|
+
return _cache.stateDir;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Platform config file name ("CLAUDE.md" | "AGENTS.md").
|
|
374
|
+
* @returns {string}
|
|
375
|
+
*/
|
|
376
|
+
export function getConfigFile() {
|
|
377
|
+
if (_cache.configFile === undefined) {
|
|
378
|
+
_cache.configFile = resolveConfigFile(getPlatform());
|
|
379
|
+
}
|
|
380
|
+
return _cache.configFile;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Test-only: drop every memoized value so the next getter re-detects.
|
|
385
|
+
* Production code must never call this — the values are process-stable.
|
|
386
|
+
* @returns {void}
|
|
387
|
+
*/
|
|
388
|
+
export function _resetPlatformCache() {
|
|
389
|
+
_cache.platform = undefined;
|
|
390
|
+
_cache.pluginRoot = undefined;
|
|
391
|
+
_cache.projectDir = undefined;
|
|
392
|
+
_cache.stateDir = undefined;
|
|
393
|
+
_cache.configFile = undefined;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// The deprecated `export let SO_PLATFORM / SO_PLUGIN_ROOT / SO_PROJECT_DIR /
|
|
397
|
+
// SO_STATE_DIR / SO_CONFIG_FILE` live bindings (#1153 P5) are GONE. They were
|
|
398
|
+
// `undefined` until the matching getter had run in the process, which made
|
|
399
|
+
// every bare read a silent wrong answer. Every consumer now calls the getter
|
|
400
|
+
// (getPlatform(), getProjectDir(), …). A re-introduction is caught by the
|
|
401
|
+
// named-export assertion in tests/lib/platform.test.mjs — do not add them back.
|
|
402
|
+
|
|
403
|
+
// ---------------------------------------------------------------------------
|
|
404
|
+
// Plain constants — no filesystem work, safe to evaluate at load
|
|
405
|
+
// ---------------------------------------------------------------------------
|
|
313
406
|
|
|
314
407
|
/** Shared orchestrator directory name — always ".orchestrator" */
|
|
315
408
|
export const SO_SHARED_DIR = '.orchestrator';
|