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,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* agent-output-schema.mjs — Runtime validation seam for agent JSON outputs.
|
|
3
|
+
*
|
|
4
|
+
* Issue #417 — JSON-schema-per-agent-output contract.
|
|
5
|
+
*
|
|
6
|
+
* Each agent MAY declare an `output-schema:` field in its YAML frontmatter
|
|
7
|
+
* pointing at a JSON Schema 2020-12 file under `agents/schemas/`. This module
|
|
8
|
+
* loads the schema lazily, extracts the LAST fenced ```json block from the
|
|
9
|
+
* agent's raw return text (mirrors the session-reviewer.md:168-183 pattern),
|
|
10
|
+
* parses it, and validates against the schema using AJV 2020.
|
|
11
|
+
*
|
|
12
|
+
* Backward-compat: agents without `output-schema:` return
|
|
13
|
+
* `{ ok: true, parsed: null, mode: 'unvalidated' }`.
|
|
14
|
+
*
|
|
15
|
+
* Design notes:
|
|
16
|
+
* - AJV is lazy-imported via `import('ajv/dist/2020.js')` so plugin startup
|
|
17
|
+
* does not pay for it when no validation is requested.
|
|
18
|
+
* - Schema compile results are cached per-process in a `Map<agentName, validate>`.
|
|
19
|
+
* - Never throws. All failure modes are reported via the structured result
|
|
20
|
+
* object's `mode` discriminator.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
import { readFile } from 'node:fs/promises';
|
|
24
|
+
import { join, dirname } from 'node:path';
|
|
25
|
+
import { fileURLToPath } from 'node:url';
|
|
26
|
+
import { getAjv2020 } from './ajv-loader.mjs';
|
|
27
|
+
|
|
28
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
29
|
+
// scripts/lib → repo root → agents/schemas/
|
|
30
|
+
// Exported so consumers (validate-plugin, tests) can derive paths without re-encoding the
|
|
31
|
+
// directory structure. check-agents.mjs derives its own schemasDir from pluginRoot — the
|
|
32
|
+
// resolution differs (arg-based root vs __dirname-based) so it does NOT import this constant.
|
|
33
|
+
export const SCHEMAS_DIR = join(__dirname, '..', '..', 'agents', 'schemas');
|
|
34
|
+
|
|
35
|
+
// Per-process compile cache: agentName → AJV ValidateFunction
|
|
36
|
+
const compileCache = new Map();
|
|
37
|
+
|
|
38
|
+
const getAjv = getAjv2020;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Load and parse the JSON schema for a given agent.
|
|
42
|
+
*
|
|
43
|
+
* @param {string} agentName - Agent name (e.g. "code-implementer"), without extension.
|
|
44
|
+
* @returns {Promise<object|null>} Parsed schema object, or null if schema file absent.
|
|
45
|
+
*/
|
|
46
|
+
const AGENT_NAME_RE = /^[a-z0-9-]+$/;
|
|
47
|
+
|
|
48
|
+
export async function loadAgentSchema(agentName) {
|
|
49
|
+
if (typeof agentName !== 'string' || agentName === '') return null;
|
|
50
|
+
if (!AGENT_NAME_RE.test(agentName)) return null;
|
|
51
|
+
const schemaPath = join(SCHEMAS_DIR, `${agentName}.schema.json`);
|
|
52
|
+
let raw;
|
|
53
|
+
try {
|
|
54
|
+
raw = await readFile(schemaPath, 'utf8');
|
|
55
|
+
} catch {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
try {
|
|
59
|
+
return JSON.parse(raw);
|
|
60
|
+
} catch {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Extract the LAST fenced ```json block from a raw text body.
|
|
67
|
+
* Mirrors the session-reviewer.md:168-183 contract — when an agent's output
|
|
68
|
+
* contains multiple json blocks (prose example + final summary), the trailing
|
|
69
|
+
* block is the machine-readable summary.
|
|
70
|
+
*
|
|
71
|
+
* @param {string} raw
|
|
72
|
+
* @returns {{ found: boolean, json?: string }}
|
|
73
|
+
*/
|
|
74
|
+
export function extractLastJsonBlock(raw) {
|
|
75
|
+
if (typeof raw !== 'string' || raw === '') return { found: false };
|
|
76
|
+
// Match ```json ... ``` non-greedy across newlines. Capture the body.
|
|
77
|
+
const re = /```json\s*\n([\s\S]*?)\n```/g;
|
|
78
|
+
let match;
|
|
79
|
+
let last = null;
|
|
80
|
+
while ((match = re.exec(raw)) !== null) {
|
|
81
|
+
last = match[1];
|
|
82
|
+
}
|
|
83
|
+
if (last === null) return { found: false };
|
|
84
|
+
return { found: true, json: last };
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Validate an agent's raw output against its declared schema.
|
|
89
|
+
*
|
|
90
|
+
* @param {object} args
|
|
91
|
+
* @param {string} args.agentName - Agent name (matches schemas/<name>.schema.json).
|
|
92
|
+
* @param {string} args.raw - Raw agent return text (may contain prose + fenced blocks).
|
|
93
|
+
* @returns {Promise<{
|
|
94
|
+
* ok: boolean,
|
|
95
|
+
* parsed?: object|null,
|
|
96
|
+
* errors?: Array<object>,
|
|
97
|
+
* mode: 'validated'|'unvalidated'|'parse-error'|'schema-error'
|
|
98
|
+
* }>}
|
|
99
|
+
*/
|
|
100
|
+
export async function validateAgentOutput({ agentName, raw }) {
|
|
101
|
+
// 1. Load schema (or signal unvalidated mode for backward-compat).
|
|
102
|
+
const schema = await loadAgentSchema(agentName);
|
|
103
|
+
if (schema === null) {
|
|
104
|
+
return { ok: true, parsed: null, mode: 'unvalidated' };
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// 2. Extract last JSON block.
|
|
108
|
+
const extracted = extractLastJsonBlock(raw);
|
|
109
|
+
if (!extracted.found) {
|
|
110
|
+
return {
|
|
111
|
+
ok: false,
|
|
112
|
+
parsed: null,
|
|
113
|
+
mode: 'parse-error',
|
|
114
|
+
errors: [{ message: 'No fenced ```json block found in agent output' }],
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// 3. Parse JSON.
|
|
119
|
+
let parsed;
|
|
120
|
+
try {
|
|
121
|
+
parsed = JSON.parse(extracted.json);
|
|
122
|
+
} catch (err) {
|
|
123
|
+
return {
|
|
124
|
+
ok: false,
|
|
125
|
+
parsed: null,
|
|
126
|
+
mode: 'parse-error',
|
|
127
|
+
errors: [{ message: `JSON parse failed: ${err.message}` }],
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// 4. Compile (or fetch cached) AJV validator.
|
|
132
|
+
let validate = compileCache.get(agentName);
|
|
133
|
+
if (validate === undefined) {
|
|
134
|
+
try {
|
|
135
|
+
const ajv = await getAjv();
|
|
136
|
+
validate = ajv.compile(schema);
|
|
137
|
+
compileCache.set(agentName, validate);
|
|
138
|
+
} catch (err) {
|
|
139
|
+
return {
|
|
140
|
+
ok: false,
|
|
141
|
+
parsed,
|
|
142
|
+
mode: 'schema-error',
|
|
143
|
+
errors: [{ message: `Schema compile failed: ${err.message}` }],
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// 5. Validate.
|
|
149
|
+
const valid = validate(parsed);
|
|
150
|
+
if (!valid) {
|
|
151
|
+
return {
|
|
152
|
+
ok: false,
|
|
153
|
+
parsed,
|
|
154
|
+
mode: 'validated',
|
|
155
|
+
errors: validate.errors ?? [],
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
return { ok: true, parsed, mode: 'validated' };
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Clear the per-process compile cache. Test-only hook.
|
|
163
|
+
*/
|
|
164
|
+
export function _clearCompileCache() {
|
|
165
|
+
compileCache.clear();
|
|
166
|
+
}
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* agent-status.mjs — lean per-agent status push helper (issue #565).
|
|
3
|
+
*
|
|
4
|
+
* Wave-executor agents push lightweight progress/status telemetry that a later
|
|
5
|
+
* tmux-layout / wave-executor integration renders in an operator side-channel.
|
|
6
|
+
* Two files live under `.orchestrator/runtime/` (already gitignored):
|
|
7
|
+
*
|
|
8
|
+
* - `agent-status.jsonl` — append-only event log (one record per push).
|
|
9
|
+
* - `agent-status-current.json` — last-write-wins (LWW) map keyed by agentId.
|
|
10
|
+
*
|
|
11
|
+
* Best-effort telemetry contract: a status push must NEVER crash or block a
|
|
12
|
+
* wave. Every exported function is no-throw and returns a structured result:
|
|
13
|
+
*
|
|
14
|
+
* { ok: true } | { ok: false, reason: 'invalid-input'|'timeout'|'fs-error', error? }
|
|
15
|
+
*
|
|
16
|
+
* Concurrency: the LWW-map read-modify-write is serialised through a
|
|
17
|
+
* self-contained POSIX lock (`agent-status.lock`) using the same `linkSync`
|
|
18
|
+
* create-or-fail idiom the repo uses elsewhere (session-lock.mjs). The lock is
|
|
19
|
+
* intentionally local to this module — it is a fast, short-held write-mutex,
|
|
20
|
+
* orthogonal to the session/state locks in session-lock.mjs.
|
|
21
|
+
*
|
|
22
|
+
* Reuse (do NOT reinvent):
|
|
23
|
+
* - appendJsonl(filePath, obj) — scripts/lib/common.mjs (O_APPEND, PIPE_BUF-atomic)
|
|
24
|
+
* - writeJsonAtomicSync(filePath, ..) — scripts/lib/io.mjs (tmp + renameSync)
|
|
25
|
+
* - isPidAliveOnHost(pid) — scripts/lib/session-lock.mjs (signal-0 probe)
|
|
26
|
+
*
|
|
27
|
+
* No external dependencies — Node 20+ stdlib only.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
import fs from 'node:fs';
|
|
31
|
+
import path from 'node:path';
|
|
32
|
+
|
|
33
|
+
import { appendJsonl } from './common.mjs';
|
|
34
|
+
import { writeJsonAtomicSync } from './io.mjs';
|
|
35
|
+
import { tryAcquireFileLock, releaseFileLock } from './file-lock.mjs';
|
|
36
|
+
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
// Constants
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
|
|
41
|
+
const RUNTIME_DIR = '.orchestrator/runtime';
|
|
42
|
+
const JSONL_NAME = 'agent-status.jsonl';
|
|
43
|
+
const CURRENT_NAME = 'agent-status-current.json';
|
|
44
|
+
const LOCK_NAME = 'agent-status.lock';
|
|
45
|
+
|
|
46
|
+
const DEFAULT_TIMEOUT_MS = 10000;
|
|
47
|
+
const POLL_MS = 100;
|
|
48
|
+
|
|
49
|
+
// macOS PIPE_BUF floor is 512 bytes; keep each JSONL line comfortably under it
|
|
50
|
+
// by truncating free-text fields. 256 chars leaves headroom for the JSON
|
|
51
|
+
// envelope (keys, ts, numbers).
|
|
52
|
+
const MAX_TEXT_LEN = 256;
|
|
53
|
+
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
// Path helpers
|
|
56
|
+
// ---------------------------------------------------------------------------
|
|
57
|
+
|
|
58
|
+
function runtimeDirFor(repoRoot) {
|
|
59
|
+
return path.join(repoRoot ?? process.cwd(), RUNTIME_DIR);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function jsonlPathFor(repoRoot) {
|
|
63
|
+
return path.join(runtimeDirFor(repoRoot), JSONL_NAME);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function currentPathFor(repoRoot) {
|
|
67
|
+
return path.join(runtimeDirFor(repoRoot), CURRENT_NAME);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function lockPathFor(repoRoot) {
|
|
71
|
+
return path.join(runtimeDirFor(repoRoot), LOCK_NAME);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// ---------------------------------------------------------------------------
|
|
75
|
+
// Internal utilities
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Truncate a free-text field to MAX_TEXT_LEN so a single JSONL line stays under
|
|
80
|
+
* the PIPE_BUF floor. Non-strings pass through untouched.
|
|
81
|
+
* @param {*} s
|
|
82
|
+
* @returns {*}
|
|
83
|
+
*/
|
|
84
|
+
function truncate(s) {
|
|
85
|
+
if (typeof s !== 'string') return s;
|
|
86
|
+
return s.length > MAX_TEXT_LEN ? s.slice(0, MAX_TEXT_LEN) : s;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Acquire the write-mutex. Polls every POLL_MS until acquired or the timeout
|
|
91
|
+
* deadline. The first iteration is unconditional so timeoutMs:0 still tries
|
|
92
|
+
* exactly once. On EEXIST, inspects the existing lock and atomically overrides
|
|
93
|
+
* it ONLY when same-host AND its PID is dead, or its body is unparseable
|
|
94
|
+
* (PSA-003: never auto-override a cross-host lock).
|
|
95
|
+
*
|
|
96
|
+
* Delegates to the shared file-lock primitive (issue #630). Behavior is
|
|
97
|
+
* preserved exactly: compact body `{pid, host, acquiredAt}` (indent:null),
|
|
98
|
+
* synchronous busy-wait poll (sync variant), PID staleCheck, console.warn
|
|
99
|
+
* override channel with the original message, override tmp prefix
|
|
100
|
+
* `.agent-status.lock.replace`, and the ENOENT-on-read race collapsed into a
|
|
101
|
+
* retry (signalVanished:false).
|
|
102
|
+
*
|
|
103
|
+
* @param {string} lockFile
|
|
104
|
+
* @param {number} timeoutMs
|
|
105
|
+
* @returns {{ ok: true, body: object } | { ok: false, reason: 'timeout'|'fs-error', error?: string }}
|
|
106
|
+
*/
|
|
107
|
+
function acquireLock(lockFile, timeoutMs) {
|
|
108
|
+
const deadline = Date.now() + Math.max(0, timeoutMs);
|
|
109
|
+
let firstPass = true;
|
|
110
|
+
|
|
111
|
+
while (firstPass || Date.now() < deadline) {
|
|
112
|
+
firstPass = false;
|
|
113
|
+
|
|
114
|
+
const attempt = tryAcquireFileLock(lockFile, {
|
|
115
|
+
staleCheck: 'pid',
|
|
116
|
+
indent: null,
|
|
117
|
+
tmpPrefix: '.agent-status.lock.replace',
|
|
118
|
+
warnMessage: (reason, lp) => `⚠ agent-status: overriding stale lock (${reason}) at ${lp}`,
|
|
119
|
+
});
|
|
120
|
+
if (attempt.acquired) return { ok: true, body: attempt.body };
|
|
121
|
+
if (attempt.reason === 'fs-error') {
|
|
122
|
+
return { ok: false, reason: 'fs-error', error: attempt.error };
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// reason === 'held' (live holder, cross-host, or vanished-collapsed-to-held)
|
|
126
|
+
// → poll until the deadline.
|
|
127
|
+
if (Date.now() >= deadline) break;
|
|
128
|
+
sleepMs(POLL_MS);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return { ok: false, reason: 'timeout' };
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Synchronous busy-wait sleep. The lock is held only for a sub-millisecond
|
|
136
|
+
* read-modify-write, so a short synchronous poll keeps the helper simple and
|
|
137
|
+
* avoids leaking async timers into the best-effort no-throw contract.
|
|
138
|
+
* @param {number} ms
|
|
139
|
+
*/
|
|
140
|
+
function sleepMs(ms) {
|
|
141
|
+
const end = Date.now() + ms;
|
|
142
|
+
// Atomics.wait on a throwaway buffer is a portable, CPU-cheap sleep.
|
|
143
|
+
try {
|
|
144
|
+
const sab = new Int32Array(new SharedArrayBuffer(4));
|
|
145
|
+
Atomics.wait(sab, 0, 0, ms);
|
|
146
|
+
} catch {
|
|
147
|
+
// SharedArrayBuffer unavailable (unlikely on Node 20+) → tight spin fallback.
|
|
148
|
+
while (Date.now() < end) { /* spin */ }
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Release the lock — but ONLY if WE own it (pid + host match). PSA-003: never
|
|
154
|
+
* delete a lock another holder owns. Delegates to releaseFileLock with the
|
|
155
|
+
* default owner-guard (no holder label → falls back to pid+host equality,
|
|
156
|
+
* exactly as the original did).
|
|
157
|
+
* @param {string} lockFile
|
|
158
|
+
* @param {object} _myBody The body returned by acquireLock (unused — the
|
|
159
|
+
* primitive re-reads the on-disk body and matches pid+host of the current
|
|
160
|
+
* process, which is the same process that called acquireLock).
|
|
161
|
+
*/
|
|
162
|
+
function releaseLock(lockFile, _myBody) {
|
|
163
|
+
// ownerGuard:true with no holder → unlink IFF on-disk pid+host match this
|
|
164
|
+
// process. Result reasons (not-found/not-owner) are ignored: best-effort.
|
|
165
|
+
releaseFileLock(lockFile, { ownerGuard: true });
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Read the current LWW map from disk. Returns {} on miss or parse error.
|
|
170
|
+
* @param {string} currentFile
|
|
171
|
+
* @returns {Record<string, object>}
|
|
172
|
+
*/
|
|
173
|
+
function readCurrentMap(currentFile) {
|
|
174
|
+
try {
|
|
175
|
+
const raw = fs.readFileSync(currentFile, 'utf8');
|
|
176
|
+
const obj = JSON.parse(raw);
|
|
177
|
+
if (obj && typeof obj === 'object' && !Array.isArray(obj)) return obj;
|
|
178
|
+
return {};
|
|
179
|
+
} catch {
|
|
180
|
+
return {};
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Shared write path for both setters: append the JSONL record, then perform a
|
|
186
|
+
* lock-serialised read-modify-write of the LWW map. No-throw.
|
|
187
|
+
*
|
|
188
|
+
* @param {object} record Fully-built status record (already validated/truncated).
|
|
189
|
+
* @param {{ repoRoot?: string, timeoutMs?: number }} opts
|
|
190
|
+
* @returns {Promise<{ ok: true } | { ok: false, reason: 'timeout'|'fs-error', error?: string }>}
|
|
191
|
+
*/
|
|
192
|
+
async function pushRecord(record, opts) {
|
|
193
|
+
const repoRoot = opts?.repoRoot;
|
|
194
|
+
const timeoutMs = typeof opts?.timeoutMs === 'number' ? opts.timeoutMs : DEFAULT_TIMEOUT_MS;
|
|
195
|
+
|
|
196
|
+
const jsonlFile = jsonlPathFor(repoRoot);
|
|
197
|
+
const currentFile = currentPathFor(repoRoot);
|
|
198
|
+
const lockFile = lockPathFor(repoRoot);
|
|
199
|
+
|
|
200
|
+
// (1) Append-only JSONL stream. appendJsonl mkdir -p's and is O_APPEND-atomic.
|
|
201
|
+
try {
|
|
202
|
+
await appendJsonl(jsonlFile, record);
|
|
203
|
+
} catch (err) {
|
|
204
|
+
return { ok: false, reason: 'fs-error', error: err?.message ?? String(err) };
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// (2) Lock-serialised RMW of the LWW current-map.
|
|
208
|
+
let acquired;
|
|
209
|
+
try {
|
|
210
|
+
acquired = acquireLock(lockFile, timeoutMs);
|
|
211
|
+
} catch (err) {
|
|
212
|
+
// acquireLock is internally no-throw, but belt-and-suspenders for the
|
|
213
|
+
// best-effort contract.
|
|
214
|
+
return { ok: false, reason: 'fs-error', error: err?.message ?? String(err) };
|
|
215
|
+
}
|
|
216
|
+
if (!acquired.ok) return acquired;
|
|
217
|
+
|
|
218
|
+
try {
|
|
219
|
+
const map = readCurrentMap(currentFile);
|
|
220
|
+
map[record.agentId] = record;
|
|
221
|
+
const written = writeJsonAtomicSync(currentFile, map, { tmpPrefix: '.agent-status-current' });
|
|
222
|
+
if (!written.ok) return { ok: false, reason: 'fs-error', error: written.error };
|
|
223
|
+
return { ok: true };
|
|
224
|
+
} catch (err) {
|
|
225
|
+
return { ok: false, reason: 'fs-error', error: err?.message ?? String(err) };
|
|
226
|
+
} finally {
|
|
227
|
+
releaseLock(lockFile, acquired.body);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// ---------------------------------------------------------------------------
|
|
232
|
+
// Exported API
|
|
233
|
+
// ---------------------------------------------------------------------------
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Push a free-text status for an agent. No-throw, best-effort.
|
|
237
|
+
*
|
|
238
|
+
* @param {string} agentId Non-empty agent identifier (LWW map key).
|
|
239
|
+
* @param {string} text Non-empty status text (truncated to ~256 chars).
|
|
240
|
+
* @param {{ repoRoot?: string, timeoutMs?: number }} [opts]
|
|
241
|
+
* @returns {Promise<{ ok: true } | { ok: false, reason: 'invalid-input'|'timeout'|'fs-error', error?: string }>}
|
|
242
|
+
*/
|
|
243
|
+
export async function setStatus(agentId, text, opts = {}) {
|
|
244
|
+
if (typeof agentId !== 'string' || agentId.trim().length === 0) {
|
|
245
|
+
return { ok: false, reason: 'invalid-input', error: 'agentId must be a non-empty string' };
|
|
246
|
+
}
|
|
247
|
+
if (typeof text !== 'string' || text.trim().length === 0) {
|
|
248
|
+
return { ok: false, reason: 'invalid-input', error: 'text must be a non-empty string' };
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
const record = {
|
|
252
|
+
agentId,
|
|
253
|
+
kind: 'status',
|
|
254
|
+
text: truncate(text),
|
|
255
|
+
ts: new Date().toISOString(),
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
return pushRecord(record, opts);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Push a structured progress update for an agent. No-throw, best-effort.
|
|
263
|
+
*
|
|
264
|
+
* @param {string} agentId Non-empty agent identifier (LWW map key).
|
|
265
|
+
* @param {{ step: number, total: number, label?: string }} progress
|
|
266
|
+
* @param {{ repoRoot?: string, timeoutMs?: number }} [opts]
|
|
267
|
+
* @returns {Promise<{ ok: true } | { ok: false, reason: 'invalid-input'|'timeout'|'fs-error', error?: string }>}
|
|
268
|
+
*/
|
|
269
|
+
export async function setProgress(agentId, progress = {}, opts = {}) {
|
|
270
|
+
if (typeof agentId !== 'string' || agentId.trim().length === 0) {
|
|
271
|
+
return { ok: false, reason: 'invalid-input', error: 'agentId must be a non-empty string' };
|
|
272
|
+
}
|
|
273
|
+
const { step, total, label } = progress ?? {};
|
|
274
|
+
if (typeof step !== 'number' || !Number.isFinite(step)) {
|
|
275
|
+
return { ok: false, reason: 'invalid-input', error: 'step must be a finite number' };
|
|
276
|
+
}
|
|
277
|
+
if (typeof total !== 'number' || !Number.isFinite(total)) {
|
|
278
|
+
return { ok: false, reason: 'invalid-input', error: 'total must be a finite number' };
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const record = {
|
|
282
|
+
agentId,
|
|
283
|
+
kind: 'progress',
|
|
284
|
+
step,
|
|
285
|
+
total,
|
|
286
|
+
ts: new Date().toISOString(),
|
|
287
|
+
};
|
|
288
|
+
if (typeof label === 'string' && label.length > 0) {
|
|
289
|
+
record.label = truncate(label);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
return pushRecord(record, opts);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* Read the current LWW status map. No-throw — returns {} on miss or parse error.
|
|
297
|
+
*
|
|
298
|
+
* @param {{ repoRoot?: string }} [opts]
|
|
299
|
+
* @returns {Record<string, { agentId: string, kind: string, ts: string, text?: string, step?: number, total?: number, label?: string }>}
|
|
300
|
+
*/
|
|
301
|
+
export function readCurrentStatus(opts = {}) {
|
|
302
|
+
return readCurrentMap(currentPathFor(opts?.repoRoot));
|
|
303
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ajv-loader.mjs — shared lazy AJV 2020 instantiation (W3-Q2 fold-in, MED-004).
|
|
3
|
+
*
|
|
4
|
+
* Two call-sites previously duplicated the default-export shape negotiation
|
|
5
|
+
* for `ajv/dist/2020.js`:
|
|
6
|
+
* - scripts/lib/agent-output-schema.mjs
|
|
7
|
+
* - scripts/lib/validate/check-agents.mjs (Check 7)
|
|
8
|
+
*
|
|
9
|
+
* This helper centralises the import + constructor lookup so a future AJV
|
|
10
|
+
* migration only touches one file.
|
|
11
|
+
*
|
|
12
|
+
* Architect-review reference: .orchestrator/audits/wave-reviewer-3-architect.md (MED-004).
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
let Ajv2020Ctor = null;
|
|
16
|
+
|
|
17
|
+
async function loadCtor() {
|
|
18
|
+
if (Ajv2020Ctor === null) {
|
|
19
|
+
const mod = await import('ajv/dist/2020.js');
|
|
20
|
+
Ajv2020Ctor = mod.default ?? mod.Ajv2020 ?? mod;
|
|
21
|
+
}
|
|
22
|
+
return Ajv2020Ctor;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Lazily import AJV 2020 and return a configured instance.
|
|
27
|
+
*
|
|
28
|
+
* @param {object} [opts] - Ajv constructor options (forwarded as-is).
|
|
29
|
+
* @returns {Promise<object>} New Ajv2020 instance.
|
|
30
|
+
*/
|
|
31
|
+
export async function getAjv2020(opts = { allErrors: true, strict: false }) {
|
|
32
|
+
const Ctor = await loadCtor();
|
|
33
|
+
return new Ctor(opts);
|
|
34
|
+
}
|