@mmerterden/multi-agent-pipeline 20.2.1 → 20.3.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/CHANGELOG.md +919 -1
- package/README.md +104 -81
- package/README.tr.md +103 -62
- package/docs/FIGMA_PIPELINE.md +35 -35
- package/docs/adr/0006-skills-core-external-split.md +1 -1
- package/docs/adr/0007-multi-tool-adapter-framework.md +6 -0
- package/docs/adr/0008-installer-modularization-and-secret-leak-defense.md +7 -0
- package/docs/architecture.md +50 -14
- package/docs/best-practices.md +1 -1
- package/docs/ecosystem.md +56 -32
- package/docs/facts.json +10 -10
- package/docs/features.md +97 -5
- package/docs/recovery-guide.md +7 -14
- package/docs/server-readiness.md +31 -24
- package/index.js +1 -1
- package/install/_common.mjs +3 -5
- package/install/_platform-filter.mjs +23 -1
- package/install/_unattended-profile.mjs +321 -75
- package/install/claude.mjs +51 -10
- package/install/codex.mjs +2 -0
- package/install/copilot.mjs +2 -0
- package/install/index.mjs +30 -17
- package/install/templates/claude-hooks.json +16 -5
- package/install/templates/copilot-instructions.md +1 -1
- package/install/templates/multi-agent-autopilot-awake.plist.template +48 -0
- package/install/templates/multi-agent-autopilot.plist.template +12 -5
- package/install/unattended-profile-legacy.json +80 -0
- package/manifest.json +617 -483
- package/package.json +8 -3
- package/pipeline/agents/code-reviewer.md +10 -0
- package/pipeline/agents/plan-critic.md +98 -0
- package/pipeline/agents/security-auditor.md +10 -0
- package/pipeline/agents/task-clarifier.md +10 -0
- package/pipeline/commands/multi-agent/SKILL.md +2 -2
- package/pipeline/commands/multi-agent/analysis/SKILL.md +6 -2
- package/pipeline/commands/multi-agent/analysis-jira/SKILL.md +12 -1
- package/pipeline/commands/multi-agent/analysis-resolve/SKILL.md +4 -0
- package/pipeline/commands/multi-agent/autopilot/SKILL.md +6 -2
- package/pipeline/commands/multi-agent/autopilot-off/SKILL.md +36 -6
- package/pipeline/commands/multi-agent/autopilot-on/SKILL.md +77 -12
- package/pipeline/commands/multi-agent/autopilot-status/SKILL.md +29 -8
- package/pipeline/commands/multi-agent/build-optimize/SKILL.md +4 -0
- package/pipeline/commands/multi-agent/channels/SKILL.md +9 -9
- package/pipeline/commands/multi-agent/complaint-analysis/SKILL.md +5 -1
- package/pipeline/commands/multi-agent/create-jira/SKILL.md +4 -0
- package/pipeline/commands/multi-agent/design-check/SKILL.md +16 -11
- package/pipeline/commands/multi-agent/diff-explain/SKILL.md +4 -0
- package/pipeline/commands/multi-agent/doctor/SKILL.md +4 -0
- package/pipeline/commands/multi-agent/feedback/SKILL.md +5 -1
- package/pipeline/commands/multi-agent/forget/SKILL.md +4 -0
- package/pipeline/commands/multi-agent/garbage-collect/SKILL.md +4 -0
- package/pipeline/commands/multi-agent/graph/SKILL.md +4 -0
- package/pipeline/commands/multi-agent/help/SKILL.md +37 -39
- package/pipeline/commands/multi-agent/ios-coding-standard/SKILL.md +4 -0
- package/pipeline/commands/multi-agent/issue/SKILL.md +7 -1
- package/pipeline/commands/multi-agent/jira/SKILL.md +7 -1
- package/pipeline/commands/multi-agent/kill/SKILL.md +9 -3
- package/pipeline/commands/multi-agent/language/SKILL.md +4 -0
- package/pipeline/commands/multi-agent/log/SKILL.md +4 -0
- package/pipeline/commands/multi-agent/manual-test/SKILL.md +5 -0
- package/pipeline/commands/multi-agent/model/SKILL.md +4 -0
- package/pipeline/commands/multi-agent/prune-logs/SKILL.md +4 -0
- package/pipeline/commands/multi-agent/prune-prompts/SKILL.md +4 -0
- package/pipeline/commands/multi-agent/purge/SKILL.md +4 -0
- package/pipeline/commands/multi-agent/refactor/SKILL.md +5 -0
- package/pipeline/commands/multi-agent/research/SKILL.md +49 -0
- package/pipeline/commands/multi-agent/resume/SKILL.md +29 -6
- package/pipeline/commands/multi-agent/review/SKILL.md +28 -9
- package/pipeline/commands/multi-agent/review-analysis/SKILL.md +5 -1
- package/pipeline/commands/multi-agent/review-issue/SKILL.md +4 -0
- package/pipeline/commands/multi-agent/review-jira/SKILL.md +4 -0
- package/pipeline/commands/multi-agent/route-off/SKILL.md +4 -0
- package/pipeline/commands/multi-agent/route-on/SKILL.md +4 -0
- package/pipeline/commands/multi-agent/route-status/SKILL.md +4 -0
- package/pipeline/commands/multi-agent/routines/SKILL.md +4 -0
- package/pipeline/commands/multi-agent/save/SKILL.md +6 -2
- package/pipeline/commands/multi-agent/scaffold/SKILL.md +47 -0
- package/pipeline/commands/multi-agent/scan/SKILL.md +4 -0
- package/pipeline/commands/multi-agent/search/SKILL.md +12 -8
- package/pipeline/commands/multi-agent/security-review/SKILL.md +4 -0
- package/pipeline/commands/multi-agent/serve/SKILL.md +62 -0
- package/pipeline/commands/multi-agent/setup/SKILL.md +27 -36
- package/pipeline/commands/multi-agent/stack/SKILL.md +4 -0
- package/pipeline/commands/multi-agent/status/SKILL.md +10 -9
- package/pipeline/commands/multi-agent/steer/SKILL.md +5 -1
- package/pipeline/commands/multi-agent/store-ready/SKILL.md +4 -0
- package/pipeline/commands/multi-agent/sync/SKILL.md +13 -13
- package/pipeline/commands/multi-agent/test/SKILL.md +4 -0
- package/pipeline/commands/multi-agent/test-accessibility/SKILL.md +4 -0
- package/pipeline/commands/multi-agent/test-dark-mode/SKILL.md +4 -0
- package/pipeline/commands/multi-agent/test-dynamic-type/SKILL.md +4 -0
- package/pipeline/commands/multi-agent/test-screenshots/SKILL.md +5 -1
- package/pipeline/commands/multi-agent/testflight-validation/SKILL.md +4 -0
- package/pipeline/commands/multi-agent/uninstall/SKILL.md +5 -1
- package/pipeline/commands/multi-agent/update/SKILL.md +4 -0
- package/pipeline/contract/CHANGELOG.md +74 -0
- package/pipeline/contract/README.md +126 -0
- package/pipeline/contract/build.mjs +427 -0
- package/pipeline/contract/fixtures/answer-result.json +11 -0
- package/pipeline/contract/fixtures/error-invalid-request.json +8 -0
- package/pipeline/contract/fixtures/error-unauthorized.json +5 -0
- package/pipeline/contract/fixtures/error-unsigned.json +5 -0
- package/pipeline/contract/fixtures/issues-empty.json +18 -0
- package/pipeline/contract/fixtures/launch-plan.json +31 -0
- package/pipeline/contract/fixtures/runs-awaiting-question.json +70 -0
- package/pipeline/contract/fixtures/runs-empty.json +6 -0
- package/pipeline/contract/fixtures/runs-failed.json +84 -0
- package/pipeline/contract/fixtures/runs-old-schema.json +70 -0
- package/pipeline/contract/fixtures/runs-pr-opened-redacted.json +101 -0
- package/pipeline/contract/fixtures/runs-pr-opened.json +106 -0
- package/pipeline/contract/fixtures/runs-running.json +84 -0
- package/pipeline/contract/fixtures/worktrees-empty.json +4 -0
- package/pipeline/contract/frozen/toolbox.json +107 -0
- package/pipeline/contract/manifest.json +263 -0
- package/pipeline/contract/types/index.d.ts +343 -0
- package/pipeline/lib/_jira-auth.sh +6 -2
- package/pipeline/lib/account-resolver.sh +1 -1
- package/pipeline/lib/autopilot-state.sh +19 -0
- package/pipeline/lib/context-link-extractor.sh +12 -5
- package/pipeline/lib/credential-inventory.sh +12 -5
- package/pipeline/lib/credential-store.sh +116 -185
- package/pipeline/lib/fetch-confluence.sh +44 -3
- package/pipeline/lib/fetch-document.sh +3 -4
- package/pipeline/lib/fetch-fortify.sh +1 -1
- package/pipeline/lib/figma-mcp-refresh.sh +2 -2
- package/pipeline/lib/figma-token.sh +5 -1
- package/pipeline/lib/issue-fetcher.sh +233 -16
- package/pipeline/lib/json-file-lock.mjs +172 -0
- package/pipeline/lib/model-dispatch.sh +21 -12
- package/pipeline/lib/model-rung.sh +6 -1
- package/pipeline/lib/multi-repo-pipeline.sh +1 -1
- package/pipeline/lib/outbound-gate.mjs +46 -16
- package/pipeline/lib/parse-complaints.sh +14 -7
- package/pipeline/lib/plan-todos.sh +3 -3
- package/pipeline/lib/post-pr-review.sh +9 -9
- package/pipeline/lib/pr-request-location.mjs +85 -0
- package/pipeline/lib/regular-file.mjs +153 -0
- package/pipeline/lib/repo-hygiene.sh +17 -0
- package/pipeline/lib/route-state.sh +5 -1
- package/pipeline/lib/run-paths.sh +3 -2
- package/pipeline/lib/stack-detect.sh +19 -1
- package/pipeline/lib/unattended-profile-check.mjs +178 -0
- package/pipeline/lib/unattended-settings-location.mjs +28 -0
- package/pipeline/lib/unattended.mjs +76 -0
- package/pipeline/lib/unattended.sh +32 -0
- package/pipeline/lib/untrusted.mjs +76 -0
- package/pipeline/lib/usage-endpoint.mjs +33 -0
- package/pipeline/lib/user-facing.mjs +82 -0
- package/pipeline/lib/user-facing.sh +58 -0
- package/pipeline/multi-agent-refs/_dev-context.md +1 -1
- package/pipeline/multi-agent-refs/analysis/evidence.md +4 -0
- package/pipeline/multi-agent-refs/analysis/locked.md +2 -2
- package/pipeline/multi-agent-refs/analysis/render.md +4 -3
- package/pipeline/multi-agent-refs/analysis/resolve.md +3 -1
- package/pipeline/multi-agent-refs/analysis/synthesis.md +4 -5
- package/pipeline/multi-agent-refs/analysis-template.md +10 -17
- package/pipeline/multi-agent-refs/channels/jira.md +1 -1
- package/pipeline/multi-agent-refs/component-dispatch.md +3 -3
- package/pipeline/multi-agent-refs/conventions-defaults.md +32 -32
- package/pipeline/multi-agent-refs/cross-cli-contract.md +10 -17
- package/pipeline/multi-agent-refs/features/autopilot-circuit-breaker.md +37 -9
- package/pipeline/multi-agent-refs/features/autopilot-operations.md +277 -0
- package/pipeline/multi-agent-refs/features/constitution.md +196 -0
- package/pipeline/multi-agent-refs/features/doctor.md +6 -3
- package/pipeline/multi-agent-refs/features/external-context-injection.md +6 -1
- package/pipeline/multi-agent-refs/features/jira-context.md +1 -1
- package/pipeline/multi-agent-refs/features/maturity-followup.md +43 -23
- package/pipeline/multi-agent-refs/features/model-fallback.md +9 -0
- package/pipeline/multi-agent-refs/features/phone-api.md +306 -0
- package/pipeline/multi-agent-refs/features/plan-critic.md +159 -0
- package/pipeline/multi-agent-refs/features/research.md +150 -0
- package/pipeline/multi-agent-refs/features/review-decision.md +185 -0
- package/pipeline/multi-agent-refs/features/scaffold.md +160 -0
- package/pipeline/multi-agent-refs/features/security-audit.md +6 -2
- package/pipeline/multi-agent-refs/features/skill-conformance.md +4 -1
- package/pipeline/multi-agent-refs/features/stack-adapters.md +116 -0
- package/pipeline/multi-agent-refs/features/unattended-gates.md +316 -0
- package/pipeline/multi-agent-refs/features/unattended-security.md +731 -0
- package/pipeline/multi-agent-refs/features/url-enrichment.md +2 -2
- package/pipeline/multi-agent-refs/features/usage-reporting.md +127 -35
- package/pipeline/multi-agent-refs/features/verify-by-test.md +1 -1
- package/pipeline/multi-agent-refs/features/visual-evidence.md +7 -7
- package/pipeline/multi-agent-refs/keychain.md +6 -11
- package/pipeline/multi-agent-refs/payload-contracts.md +2 -2
- package/pipeline/multi-agent-refs/phases/log-format.md +2 -3
- package/pipeline/multi-agent-refs/phases/modes.md +10 -12
- package/pipeline/multi-agent-refs/phases/operations.md +11 -5
- package/pipeline/multi-agent-refs/phases/phase-0-init.md +73 -81
- package/pipeline/multi-agent-refs/phases/phase-1-plan.md +22 -22
- package/pipeline/multi-agent-refs/phases/phase-2-dev.md +42 -66
- package/pipeline/multi-agent-refs/phases/phase-3-review.md +45 -79
- package/pipeline/multi-agent-refs/phases/phase-4-commit.md +28 -38
- package/pipeline/multi-agent-refs/phases/phase-5-report.md +27 -25
- package/pipeline/multi-agent-refs/phases.md +1 -1
- package/pipeline/multi-agent-refs/picker-contract.md +1 -1
- package/pipeline/multi-agent-refs/progress-contract.md +13 -16
- package/pipeline/multi-agent-refs/readiness-review.md +1 -1
- package/pipeline/multi-agent-refs/research/engine.md +91 -0
- package/pipeline/multi-agent-refs/rules.md +6 -4
- package/pipeline/multi-agent-refs/setup/repo-discovery.md +2 -2
- package/pipeline/multi-agent-refs/tracker-contract.md +2 -2
- package/pipeline/multi-agent-refs/unattended-contract.md +68 -16
- package/pipeline/rules/figma-pipeline.md +12 -12
- package/pipeline/schemas/agent-state.schema.json +480 -18
- package/pipeline/schemas/analysis-spec.schema.json +4 -4
- package/pipeline/schemas/answer-request.schema.json +24 -0
- package/pipeline/schemas/answer-result.schema.json +28 -0
- package/pipeline/schemas/autopilot-config.schema.json +111 -13
- package/pipeline/schemas/command-parameters.schema.json +99 -0
- package/pipeline/schemas/constitution.schema.json +56 -0
- package/pipeline/schemas/contract-error.schema.json +52 -0
- package/pipeline/schemas/design-check-config.schema.json +5 -1
- package/pipeline/schemas/issues.schema.json +61 -0
- package/pipeline/schemas/launch-plan.schema.json +46 -0
- package/pipeline/schemas/launch-request.schema.json +45 -0
- package/pipeline/schemas/launch.json +61 -0
- package/pipeline/schemas/launch.schema.json +84 -0
- package/pipeline/schemas/phases.json +2 -2
- package/pipeline/schemas/phases.schema.json +68 -0
- package/pipeline/schemas/phone-devices.schema.json +61 -0
- package/pipeline/schemas/phone-signed-request.schema.json +67 -0
- package/pipeline/schemas/plan-critique.schema.json +99 -0
- package/pipeline/schemas/plan-todos.schema.json +7 -7
- package/pipeline/schemas/planning-output.schema.json +5 -0
- package/pipeline/schemas/pr-request.schema.json +46 -0
- package/pipeline/schemas/prefs.schema.json +79 -8
- package/pipeline/schemas/research-output.schema.json +118 -0
- package/pipeline/schemas/review-file-exclusions.schema.json +25 -0
- package/pipeline/schemas/reviewer-output.schema.json +40 -4
- package/pipeline/schemas/run-questions.json +392 -0
- package/pipeline/schemas/run-questions.schema.json +118 -0
- package/pipeline/schemas/runs-index.schema.json +189 -0
- package/pipeline/schemas/scaffold-manifest.schema.json +43 -0
- package/pipeline/schemas/secret-patterns.schema.json +28 -0
- package/pipeline/schemas/stack-adapters.json +527 -0
- package/pipeline/schemas/stack-adapters.schema.json +184 -0
- package/pipeline/schemas/token-budget.json +1 -1
- package/pipeline/schemas/token-budget.schema.json +26 -0
- package/pipeline/schemas/triage-output.schema.json +64 -3
- package/pipeline/schemas/unattended-policy.json +139 -0
- package/pipeline/schemas/unattended-policy.schema.json +73 -0
- package/pipeline/schemas/unattended-profile.json +248 -0
- package/pipeline/schemas/unattended-profile.schema.json +198 -0
- package/pipeline/schemas/worktrees.schema.json +51 -0
- package/pipeline/scripts/README.md +1 -0
- package/pipeline/scripts/_autopilot-config.mjs +130 -0
- package/pipeline/scripts/_autopilot-ops.mjs +567 -0
- package/pipeline/scripts/_autopilot-outcomes.mjs +174 -0
- package/pipeline/scripts/_command-contract.mjs +384 -0
- package/pipeline/scripts/_cost.mjs +40 -0
- package/pipeline/scripts/_notices.mjs +160 -0
- package/pipeline/scripts/_phone-auth.mjs +485 -0
- package/pipeline/scripts/_pre-existing.mjs +294 -0
- package/pipeline/scripts/_redact.mjs +77 -0
- package/pipeline/scripts/_run-paths.mjs +4 -2
- package/pipeline/scripts/_stack-adapter.mjs +678 -0
- package/pipeline/scripts/_stack-routing.mjs +1 -1
- package/pipeline/scripts/agent-guard.py +348 -37
- package/pipeline/scripts/agent-guard.sh +41 -13
- package/pipeline/scripts/analysis-story-tree.mjs +79 -3
- package/pipeline/scripts/answer-question.mjs +181 -0
- package/pipeline/scripts/audit-log-rotate.sh +1 -4
- package/pipeline/scripts/audit-log.sh +4 -4
- package/pipeline/scripts/autopilot-arming.mjs +389 -21
- package/pipeline/scripts/autopilot-awake.mjs +255 -0
- package/pipeline/scripts/autopilot-intake.mjs +137 -36
- package/pipeline/scripts/autopilot-menubar.swift +156 -44
- package/pipeline/scripts/autopilot-publish.mjs +1625 -0
- package/pipeline/scripts/autopilot-runner.mjs +1678 -222
- package/pipeline/scripts/autopilot-status.sh +198 -33
- package/pipeline/scripts/build-lock.sh +120 -0
- package/pipeline/scripts/build-references.mjs +4 -1
- package/pipeline/scripts/build-stack-plugins.mjs +59 -22
- package/pipeline/scripts/capture-flush.sh +1 -1
- package/pipeline/scripts/capture-resume.sh +13 -9
- package/pipeline/scripts/check-derived-drift.mjs +52 -11
- package/pipeline/scripts/commands.mjs +88 -0
- package/pipeline/scripts/constitution.mjs +362 -0
- package/pipeline/scripts/contract-server.mjs +776 -0
- package/pipeline/scripts/cost-analyze.mjs +89 -39
- package/pipeline/scripts/diff-explain.mjs +12 -1
- package/pipeline/scripts/doctor.mjs +77 -28
- package/pipeline/scripts/evidence-gate.mjs +192 -12
- package/pipeline/scripts/feedback-send.mjs +4 -2
- package/pipeline/scripts/gate-ledger.mjs +449 -0
- package/pipeline/scripts/gc-abandoned.sh +132 -13
- package/pipeline/scripts/gen-facts.mjs +31 -15
- package/pipeline/scripts/gen-mode-dispatch.mjs +3 -3
- package/pipeline/scripts/github-ssh-setup.sh +140 -29
- package/pipeline/scripts/graph-mermaid.mjs +4 -1
- package/pipeline/scripts/issues.mjs +236 -0
- package/pipeline/scripts/jira-attach.sh +6 -2
- package/pipeline/scripts/jira-search.sh +4 -3
- package/pipeline/scripts/keychain-save.sh +125 -24
- package/pipeline/scripts/keychain.py +63 -93
- package/pipeline/scripts/launch-request.mjs +747 -0
- package/pipeline/scripts/localize-commands.mjs +4 -10
- package/pipeline/scripts/log-metric.sh +6 -5
- package/pipeline/scripts/maturity-followup.mjs +13 -4
- package/pipeline/scripts/memory-save.sh +25 -0
- package/pipeline/scripts/migrate-prefs.mjs +4 -3
- package/pipeline/scripts/open-questions-gate.mjs +276 -0
- package/pipeline/scripts/phase-tracker.sh +41 -27
- package/pipeline/scripts/phase0-exit-gate.mjs +22 -4
- package/pipeline/scripts/phone-devices.mjs +224 -0
- package/pipeline/scripts/plan-coverage-gate.mjs +200 -66
- package/pipeline/scripts/plan-critique-gate.mjs +591 -0
- package/pipeline/scripts/pr-request.mjs +188 -0
- package/pipeline/scripts/pre-commit-check.sh +115 -4
- package/pipeline/scripts/probe-evidence-capability.sh +44 -5
- package/pipeline/scripts/record-phase.mjs +71 -0
- package/pipeline/scripts/render-agent-log-cost.sh +17 -2
- package/pipeline/scripts/render-cost-summary.sh +1 -1
- package/pipeline/scripts/render-work-summary.sh +1 -1
- package/pipeline/scripts/require-supported-version.sh +4 -1
- package/pipeline/scripts/research-gate.mjs +704 -0
- package/pipeline/scripts/review-decision-gate.mjs +403 -0
- package/pipeline/scripts/routine-registry.mjs +5 -2
- package/pipeline/scripts/runs-index.mjs +135 -27
- package/pipeline/scripts/scaffold-gate.mjs +393 -0
- package/pipeline/scripts/skill-conformance.mjs +25 -8
- package/pipeline/scripts/skill-siblings.mjs +2 -1
- package/pipeline/scripts/smoke-cross-cli-behavior.sh +32 -6
- package/pipeline/scripts/smoke-schema-validation.sh +6 -2
- package/pipeline/scripts/spec-consistency-gate.mjs +469 -0
- package/pipeline/scripts/symbol-existence-gate.mjs +450 -0
- package/pipeline/scripts/test-gap-scan.mjs +40 -2
- package/pipeline/scripts/test-integrity-gate.mjs +20 -4
- package/pipeline/scripts/test-strength.mjs +484 -0
- package/pipeline/scripts/test-summary.mjs +651 -0
- package/pipeline/scripts/triage-memory.mjs +49 -9
- package/pipeline/scripts/unattended_policy.py +2786 -0
- package/pipeline/scripts/uninstall.mjs +10 -10
- package/pipeline/scripts/update-issue-progress.sh +1 -1
- package/pipeline/scripts/usage-identity.mjs +288 -0
- package/pipeline/scripts/usage-register.mjs +187 -67
- package/pipeline/scripts/usage-report.mjs +232 -67
- package/pipeline/scripts/validate-complaint-doc.mjs +28 -10
- package/pipeline/scripts/validate-planning.mjs +6 -0
- package/pipeline/scripts/verify-citations.mjs +151 -38
- package/pipeline/scripts/verify.mjs +58 -18
- package/pipeline/scripts/worktree-prepare.sh +126 -0
- package/pipeline/scripts/worktrees.mjs +124 -0
- package/pipeline/scripts/write-state.mjs +48 -17
- package/pipeline/skills/.skill-manifest.json +222 -226
- package/pipeline/skills/.skills-index.json +77 -88
- package/pipeline/skills/shared/README.md +44 -45
- package/pipeline/skills/shared/core/apple-archive-compliance/SKILL.md +3 -2
- package/pipeline/skills/shared/core/google-play-compliance/SKILL.md +3 -2
- package/pipeline/skills/shared/core/multi-agent/SKILL.md +10 -9
- package/pipeline/skills/shared/core/multi-agent-analysis/SKILL.md +6 -5
- package/pipeline/skills/shared/core/multi-agent-analysis-jira/SKILL.md +11 -3
- package/pipeline/skills/shared/core/multi-agent-analysis-resolve/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-autopilot/SKILL.md +4 -3
- package/pipeline/skills/shared/core/multi-agent-autopilot-off/SKILL.md +32 -6
- package/pipeline/skills/shared/core/multi-agent-autopilot-on/SKILL.md +66 -8
- package/pipeline/skills/shared/core/multi-agent-autopilot-status/SKILL.md +27 -9
- package/pipeline/skills/shared/core/multi-agent-build-optimize/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-channels/SKILL.md +7 -4
- package/pipeline/skills/shared/core/multi-agent-complaint-analysis/SKILL.md +3 -2
- package/pipeline/skills/shared/core/multi-agent-create-jira/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-design-check/SKILL.md +7 -5
- package/pipeline/skills/shared/core/multi-agent-diff-explain/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-doctor/SKILL.md +3 -2
- package/pipeline/skills/shared/core/multi-agent-feedback/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-forget/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-garbage-collect/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-graph/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-help/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-ios-coding-standard/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-issue/SKILL.md +3 -2
- package/pipeline/skills/shared/core/multi-agent-jira/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-kill/SKILL.md +7 -4
- package/pipeline/skills/shared/core/multi-agent-language/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-log/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-manual-test/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-model/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-prune-logs/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-prune-prompts/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-purge/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-refactor/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-research/SKILL.md +35 -0
- package/pipeline/skills/shared/core/multi-agent-resume/SKILL.md +7 -3
- package/pipeline/skills/shared/core/multi-agent-review/SKILL.md +7 -5
- package/pipeline/skills/shared/core/multi-agent-review-analysis/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-review-issue/SKILL.md +3 -2
- package/pipeline/skills/shared/core/multi-agent-review-jira/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-route-off/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-route-on/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-route-status/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-routines/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-save/SKILL.md +3 -2
- package/pipeline/skills/shared/core/multi-agent-scaffold/SKILL.md +30 -0
- package/pipeline/skills/shared/core/multi-agent-scan/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-search/SKILL.md +4 -3
- package/pipeline/skills/shared/core/multi-agent-security-review/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-serve/SKILL.md +60 -0
- package/pipeline/skills/shared/core/multi-agent-setup/SKILL.md +8 -8
- package/pipeline/skills/shared/core/multi-agent-stack/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-status/SKILL.md +7 -8
- package/pipeline/skills/shared/core/multi-agent-steer/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-store-ready/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-sync/SKILL.md +10 -10
- package/pipeline/skills/shared/core/multi-agent-test/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-test-accessibility/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-test-dark-mode/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-test-dynamic-type/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-test-screenshots/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-testflight-validation/SKILL.md +2 -1
- package/pipeline/skills/shared/core/multi-agent-uninstall/SKILL.md +3 -2
- package/pipeline/skills/shared/core/multi-agent-update/SKILL.md +2 -1
- package/pipeline/skills/shared/external/NOTICE-avdlee-swiftui-agent-skill.md +46 -0
- package/pipeline/skills/shared/external/NOTICE-dimillian-skills.md +9 -3
- package/pipeline/skills/shared/external/NOTICE-paul-hudson-skills.md +54 -0
- package/pipeline/skills/shared/external/NOTICE-swift-ios-skills.md +9 -11
- package/pipeline/skills/shared/external/NOTICE-vibeship-spawner-skills.md +203 -0
- package/pipeline/skills/shared/external/NOTICE-xcode-build-skills.md +10 -3
- package/pipeline/skills/shared/external/accessibility-compliance-accessibility-audit/SKILL.md +131 -25
- package/pipeline/skills/shared/external/agent-introspection-debugging/SKILL.md +4 -3
- package/pipeline/skills/shared/external/alarmkit/SKILL.md +2 -1
- package/pipeline/skills/shared/external/android-architecture/SKILL.md +85 -76
- package/pipeline/skills/shared/external/android-build-quality-gates/SKILL.md +51 -3
- package/pipeline/skills/shared/external/android-build-quality-gates/references/patterns.md +9 -0
- package/pipeline/skills/shared/external/android-datastore/SKILL.md +4 -3
- package/pipeline/skills/shared/external/android-design-tokens-codegen/SKILL.md +4 -3
- package/pipeline/skills/shared/external/android-jetpack-compose-expert/SKILL.md +106 -181
- package/pipeline/skills/shared/external/android-jetpack-compose-expert/references/patterns.md +147 -0
- package/pipeline/skills/shared/external/android-mvi-viewmodel/SKILL.md +45 -4
- package/pipeline/skills/shared/external/android-performance/SKILL.md +27 -2
- package/pipeline/skills/shared/external/android-performance/references/patterns.md +37 -37
- package/pipeline/skills/shared/external/api-patterns/SKILL.md +111 -67
- package/pipeline/skills/shared/external/api-patterns/references/contract-details.md +128 -0
- package/pipeline/skills/shared/external/api-security-best-practices/SKILL.md +136 -186
- package/pipeline/skills/shared/external/api-security-best-practices/references/abuse-controls.md +140 -0
- package/pipeline/skills/shared/external/api-security-best-practices/references/identity-and-access.md +207 -0
- package/pipeline/skills/shared/external/api-security-best-practices/references/operations.md +66 -0
- package/pipeline/skills/shared/external/api-security-best-practices/references/request-handling.md +175 -0
- package/pipeline/skills/shared/external/app-clips/SKILL.md +2 -0
- package/pipeline/skills/shared/external/app-intents/SKILL.md +2 -0
- package/pipeline/skills/shared/external/app-store-changelog/SKILL.md +4 -3
- package/pipeline/skills/shared/external/app-store-optimization/SKILL.md +2 -0
- package/pipeline/skills/shared/external/app-store-review/SKILL.md +2 -0
- package/pipeline/skills/shared/external/apple-on-device-ai/SKILL.md +2 -0
- package/pipeline/skills/shared/external/architecture/SKILL.md +106 -39
- package/pipeline/skills/shared/external/architecture/references/adr-and-review.md +76 -0
- package/pipeline/skills/shared/external/authentication/SKILL.md +2 -0
- package/pipeline/skills/shared/external/avkit/SKILL.md +2 -0
- package/pipeline/skills/shared/external/background-processing/SKILL.md +2 -1
- package/pipeline/skills/shared/external/backlog/SKILL.md +3 -2
- package/pipeline/skills/shared/external/callkit-voip/SKILL.md +2 -0
- package/pipeline/skills/shared/external/callkit-voip/evals/evals.json +1 -1
- package/pipeline/skills/shared/external/ci-cd-pipelines/SKILL.md +3 -2
- package/pipeline/skills/shared/external/clean-code/SKILL.md +192 -90
- package/pipeline/skills/shared/external/cloudkit-sync/SKILL.md +2 -1
- package/pipeline/skills/shared/external/cloudkit-sync/evals/evals.json +1 -1
- package/pipeline/skills/shared/external/compose-components/SKILL.md +4 -4
- package/pipeline/skills/shared/external/compose-navigation/SKILL.md +22 -22
- package/pipeline/skills/shared/external/compose-navigation/references/patterns.md +10 -10
- package/pipeline/skills/shared/external/compose-testing/SKILL.md +13 -6
- package/pipeline/skills/shared/external/compose-testing/references/patterns.md +59 -59
- package/pipeline/skills/shared/external/contacts-framework/SKILL.md +2 -0
- package/pipeline/skills/shared/external/context-compression/SKILL.md +118 -250
- package/pipeline/skills/shared/external/core-bluetooth/SKILL.md +2 -0
- package/pipeline/skills/shared/external/core-data/SKILL.md +2 -0
- package/pipeline/skills/shared/external/core-motion/SKILL.md +2 -0
- package/pipeline/skills/shared/external/core-nfc/SKILL.md +2 -0
- package/pipeline/skills/shared/external/coreml/SKILL.md +2 -1
- package/pipeline/skills/shared/external/council/SKILL.md +2 -1
- package/pipeline/skills/shared/external/cryptokit/SKILL.md +2 -0
- package/pipeline/skills/shared/external/css-modern/SKILL.md +3 -2
- package/pipeline/skills/shared/external/database-patterns/SKILL.md +3 -2
- package/pipeline/skills/shared/external/debugging-instruments/SKILL.md +2 -0
- package/pipeline/skills/shared/external/debugging-strategies/SKILL.md +130 -20
- package/pipeline/skills/shared/external/debugging-strategies/references/hard-cases.md +54 -0
- package/pipeline/skills/shared/external/device-integrity/SKILL.md +2 -0
- package/pipeline/skills/shared/external/docker-expert/SKILL.md +137 -381
- package/pipeline/skills/shared/external/docker-expert/references/patterns.md +98 -0
- package/pipeline/skills/shared/external/energykit/SKILL.md +2 -1
- package/pipeline/skills/shared/external/eventkit-calendar/SKILL.md +3 -1
- package/pipeline/skills/shared/external/eventkit-calendar/evals/evals.json +2 -2
- package/pipeline/skills/shared/external/fastapi-pro/SKILL.md +116 -185
- package/pipeline/skills/shared/external/fastapi-pro/references/app-structure.md +235 -0
- package/pipeline/skills/shared/external/fastapi-pro/references/testing-and-deployment.md +69 -0
- package/pipeline/skills/shared/external/firebase/SKILL.md +4 -3
- package/pipeline/skills/shared/external/github-actions-templates/SKILL.md +151 -293
- package/pipeline/skills/shared/external/github-actions-templates/references/patterns.md +96 -0
- package/pipeline/skills/shared/external/healthkit/SKILL.md +2 -0
- package/pipeline/skills/shared/external/hig-components-content/SKILL.md +69 -72
- package/pipeline/skills/shared/external/hig-components-content/references/content-views.md +111 -0
- package/pipeline/skills/shared/external/hig-components-layout/SKILL.md +77 -86
- package/pipeline/skills/shared/external/hig-components-layout/references/containers.md +98 -0
- package/pipeline/skills/shared/external/hig-components-status/SKILL.md +150 -78
- package/pipeline/skills/shared/external/hig-components-system/SKILL.md +76 -97
- package/pipeline/skills/shared/external/hig-components-system/references/surfaces.md +98 -0
- package/pipeline/skills/shared/external/hig-foundations/SKILL.md +48 -76
- package/pipeline/skills/shared/external/hig-foundations/references/foundations-detail.md +132 -0
- package/pipeline/skills/shared/external/hig-inputs/SKILL.md +147 -106
- package/pipeline/skills/shared/external/hig-patterns/SKILL.md +61 -77
- package/pipeline/skills/shared/external/hig-patterns/references/patterns.md +92 -0
- package/pipeline/skills/shared/external/hig-platforms/SKILL.md +147 -77
- package/pipeline/skills/shared/external/hig-technologies/SKILL.md +61 -121
- package/pipeline/skills/shared/external/hig-technologies/references/technologies.md +108 -0
- package/pipeline/skills/shared/external/homekit-matter/SKILL.md +2 -0
- package/pipeline/skills/shared/external/homekit-matter/evals/evals.json +1 -1
- package/pipeline/skills/shared/external/html-semantic/SKILL.md +3 -2
- package/pipeline/skills/shared/external/humanizer/SKILL.md +2 -1
- package/pipeline/skills/shared/external/ios-accessibility/SKILL.md +2 -0
- package/pipeline/skills/shared/external/ios-coding-standard/SKILL.md +2 -1
- package/pipeline/skills/shared/external/ios-coding-standard/references/STANDARD.md +14 -2
- package/pipeline/skills/shared/external/ios-coding-standard/references/rules.yml +2 -2
- package/pipeline/skills/shared/external/ios-debugger-agent/SKILL.md +4 -3
- package/pipeline/skills/shared/external/ios-localization/SKILL.md +8 -6
- package/pipeline/skills/shared/external/ios-localization/evals/evals.json +2 -2
- package/pipeline/skills/shared/external/ios-localization/references/string-catalogs.md +11 -11
- package/pipeline/skills/shared/external/ios-module-structure/SKILL.md +2 -1
- package/pipeline/skills/shared/external/ios-networking/SKILL.md +2 -0
- package/pipeline/skills/shared/external/ios-simulator/SKILL.md +2 -0
- package/pipeline/skills/shared/external/kotlin-coroutines-expert/SKILL.md +102 -193
- package/pipeline/skills/shared/external/kotlin-coroutines-expert/references/patterns.md +103 -0
- package/pipeline/skills/shared/external/live-activities/SKILL.md +4 -2
- package/pipeline/skills/shared/external/live-activities/evals/evals.json +2 -2
- package/pipeline/skills/shared/external/localization-reuse-map/SKILL.md +7 -9
- package/pipeline/skills/shared/external/localization-reuse-map/reference/sources-and-recipes.md +3 -3
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/resolve-new-values.py +2 -2
- package/pipeline/skills/shared/external/macos-menubar-tuist-app/SKILL.md +4 -3
- package/pipeline/skills/shared/external/macos-spm-app-packaging/SKILL.md +5 -3
- package/pipeline/skills/shared/external/mapkit-location/SKILL.md +2 -0
- package/pipeline/skills/shared/external/mapkit-location/evals/evals.json +1 -1
- package/pipeline/skills/shared/external/metrickit-diagnostics/SKILL.md +2 -0
- package/pipeline/skills/shared/external/metrickit-diagnostics/evals/evals.json +1 -1
- package/pipeline/skills/shared/external/monorepo-architect/SKILL.md +149 -46
- package/pipeline/skills/shared/external/monorepo-architect/references/patterns.md +70 -0
- package/pipeline/skills/shared/external/musickit-audio/SKILL.md +2 -0
- package/pipeline/skills/shared/external/musickit-audio/evals/evals.json +1 -1
- package/pipeline/skills/shared/external/natural-language/SKILL.md +2 -0
- package/pipeline/skills/shared/external/nextjs-app-router/SKILL.md +3 -2
- package/pipeline/skills/shared/external/nodejs-backend-patterns/SKILL.md +91 -21
- package/pipeline/skills/shared/external/nodejs-backend-patterns/references/runtime-patterns.md +247 -0
- package/pipeline/skills/shared/external/nodejs-backend-patterns/references/testing-and-frameworks.md +57 -0
- package/pipeline/skills/shared/external/observability-engineer/SKILL.md +155 -232
- package/pipeline/skills/shared/external/observability-engineer/references/patterns.md +75 -0
- package/pipeline/skills/shared/external/passkit-wallet/SKILL.md +2 -0
- package/pipeline/skills/shared/external/passkit-wallet/evals/evals.json +2 -2
- package/pipeline/skills/shared/external/passkit-wallet/references/wallet-passes.md +18 -18
- package/pipeline/skills/shared/external/pdfkit/SKILL.md +2 -1
- package/pipeline/skills/shared/external/pencilkit-drawing/SKILL.md +2 -0
- package/pipeline/skills/shared/external/pencilkit-drawing/evals/evals.json +1 -1
- package/pipeline/skills/shared/external/permissionkit/SKILL.md +2 -0
- package/pipeline/skills/shared/external/photos-camera-media/SKILL.md +2 -1
- package/pipeline/skills/shared/external/push-notifications/SKILL.md +2 -0
- package/pipeline/skills/shared/external/python-patterns/SKILL.md +3 -2
- package/pipeline/skills/shared/external/react-best-practices/SKILL.md +3 -2
- package/pipeline/skills/shared/external/realitykit-ar/SKILL.md +2 -2
- package/pipeline/skills/shared/external/realitykit-ar/evals/evals.json +1 -1
- package/pipeline/skills/shared/external/rest-api-design/SKILL.md +3 -2
- package/pipeline/skills/shared/external/retrofit-networking/SKILL.md +7 -7
- package/pipeline/skills/shared/external/retrofit-networking/references/patterns.md +69 -69
- package/pipeline/skills/shared/external/room-database/references/patterns.md +126 -126
- package/pipeline/skills/shared/external/search-first/SKILL.md +2 -1
- package/pipeline/skills/shared/external/security-review/SKILL.md +4 -3
- package/pipeline/skills/shared/external/shareplay-activities/SKILL.md +2 -2
- package/pipeline/skills/shared/external/signal-community/SKILL.md +1 -1
- package/pipeline/skills/shared/external/skill-creator/SKILL.md +2 -1
- package/pipeline/skills/shared/external/speech-recognition/SKILL.md +2 -1
- package/pipeline/skills/shared/external/spm-build-analysis/SKILL.md +2 -0
- package/pipeline/skills/shared/external/storekit/SKILL.md +2 -0
- package/pipeline/skills/shared/external/swift-api-design-guidelines/SKILL.md +2 -0
- package/pipeline/skills/shared/external/swift-architecture/SKILL.md +2 -1
- package/pipeline/skills/shared/external/swift-charts/SKILL.md +2 -1
- package/pipeline/skills/shared/external/swift-codable/SKILL.md +2 -0
- package/pipeline/skills/shared/external/swift-concurrency/SKILL.md +3 -1
- package/pipeline/skills/shared/external/swift-concurrency-expert/SKILL.md +5 -4
- package/pipeline/skills/shared/external/swift-concurrency-pro/SKILL.md +2 -1
- package/pipeline/skills/shared/external/swift-formatstyle/SKILL.md +2 -0
- package/pipeline/skills/shared/external/swift-language/SKILL.md +3 -1
- package/pipeline/skills/shared/external/swift-security/SKILL.md +2 -1
- package/pipeline/skills/shared/external/swift-testing/SKILL.md +2 -0
- package/pipeline/skills/shared/external/swift-testing-pro/SKILL.md +2 -1
- package/pipeline/skills/shared/external/swift-testing-pro/references/new-features.md +10 -0
- package/pipeline/skills/shared/external/swiftdata/SKILL.md +2 -0
- package/pipeline/skills/shared/external/swiftdata-pro/SKILL.md +2 -1
- package/pipeline/skills/shared/external/swiftlint/SKILL.md +2 -0
- package/pipeline/skills/shared/external/swiftui-animation/SKILL.md +2 -0
- package/pipeline/skills/shared/external/swiftui-expert-skill/SKILL.md +3 -1
- package/pipeline/skills/shared/external/swiftui-gestures/SKILL.md +2 -0
- package/pipeline/skills/shared/external/swiftui-layout-components/SKILL.md +2 -0
- package/pipeline/skills/shared/external/swiftui-liquid-glass/SKILL.md +2 -0
- package/pipeline/skills/shared/external/swiftui-navigation/SKILL.md +2 -0
- package/pipeline/skills/shared/external/swiftui-patterns/SKILL.md +3 -1
- package/pipeline/skills/shared/external/swiftui-performance/SKILL.md +3 -1
- package/pipeline/skills/shared/external/swiftui-performance-audit/SKILL.md +5 -4
- package/pipeline/skills/shared/external/swiftui-pro/SKILL.md +2 -1
- package/pipeline/skills/shared/external/swiftui-ui-patterns/SKILL.md +5 -4
- package/pipeline/skills/shared/external/swiftui-uikit-interop/SKILL.md +2 -0
- package/pipeline/skills/shared/external/swiftui-view-refactor/SKILL.md +4 -3
- package/pipeline/skills/shared/external/swiftui-webkit/SKILL.md +2 -0
- package/pipeline/skills/shared/external/tailwind-css/SKILL.md +3 -2
- package/pipeline/skills/shared/external/testing-backend/SKILL.md +3 -2
- package/pipeline/skills/shared/external/tipkit/SKILL.md +2 -0
- package/pipeline/skills/shared/external/typescript-patterns/SKILL.md +3 -2
- package/pipeline/skills/shared/external/vision-framework/SKILL.md +2 -0
- package/pipeline/skills/shared/external/vue-composition/SKILL.md +3 -2
- package/pipeline/skills/shared/external/weatherkit/SKILL.md +2 -0
- package/pipeline/skills/shared/external/web-accessibility/SKILL.md +3 -2
- package/pipeline/skills/shared/external/web-performance/SKILL.md +3 -2
- package/pipeline/skills/shared/external/web-testing/SKILL.md +3 -2
- package/pipeline/skills/shared/external/widgetkit/SKILL.md +2 -0
- package/pipeline/skills/shared/external/widgetkit/references/widgetkit-advanced.md +1 -1
- package/pipeline/skills/shared/external/xcode-build-benchmark/SKILL.md +2 -0
- package/pipeline/skills/shared/external/xcode-build-fixer/SKILL.md +2 -0
- package/pipeline/skills/shared/external/xcode-build-orchestrator/SKILL.md +2 -0
- package/pipeline/skills/shared/external/xcode-compilation-analyzer/SKILL.md +2 -0
- package/pipeline/skills/shared/external/xcode-project-analyzer/SKILL.md +2 -0
- package/pipeline/skills/skills-index.md +40 -41
- package/docs/token-budget-history.md +0 -24
- package/pipeline/skills/shared/external/agentflow/SKILL.md +0 -199
- package/pipeline/skills/shared/external/android-ui-verification/SKILL.md +0 -66
- package/pipeline/skills/shared/external/api-security-best-practices/references/auth.md +0 -299
- package/pipeline/skills/shared/external/api-security-best-practices/references/input-validation.md +0 -255
- package/pipeline/skills/shared/external/api-security-best-practices/references/rate-limiting.md +0 -167
- package/pipeline/skills/shared/external/closed-loop-delivery/SKILL.md +0 -116
- package/pipeline/skills/shared/external/ios-developer/SKILL.md +0 -216
|
@@ -112,10 +112,9 @@ export function localizeCommands(dir, mode) {
|
|
|
112
112
|
return changed;
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
//
|
|
116
|
-
//
|
|
117
|
-
//
|
|
118
|
-
// mirrored localized descriptions into the repo, the one thing it must prevent.
|
|
115
|
+
// Entry-point check: compare file URLs, never string-split a path. A false
|
|
116
|
+
// negative here makes `restore` exit 0 doing nothing, and /multi-agent:sync then
|
|
117
|
+
// mirrors localized descriptions into the repo, the one thing it must prevent.
|
|
119
118
|
const invokedDirectly = process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href;
|
|
120
119
|
if (invokedDirectly) {
|
|
121
120
|
const args = process.argv.slice(2);
|
|
@@ -124,12 +123,7 @@ if (invokedDirectly) {
|
|
|
124
123
|
console.error("usage: localize-commands.mjs <apply|restore> [--dir <commandsDir>]");
|
|
125
124
|
process.exit(2);
|
|
126
125
|
}
|
|
127
|
-
let dir = join(
|
|
128
|
-
process.env.HOME || process.env.USERPROFILE || "",
|
|
129
|
-
".claude",
|
|
130
|
-
"commands",
|
|
131
|
-
"multi-agent",
|
|
132
|
-
);
|
|
126
|
+
let dir = join(process.env.HOME || "", ".claude", "commands", "multi-agent");
|
|
133
127
|
const dirFlag = args.indexOf("--dir");
|
|
134
128
|
if (dirFlag >= 0) {
|
|
135
129
|
if (!args[dirFlag + 1]) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# log-metric.sh - append a single event to the pipeline metrics log.
|
|
3
3
|
#
|
|
4
|
-
# Append-only JSONL at $METRICS_FILE (default $HOME/.claude/logs/multi-agent
|
|
4
|
+
# Append-only JSONL at $METRICS_FILE (default $LOGS_ROOT/metrics.jsonl, LOGS_ROOT defaulting to $HOME/.claude/logs/multi-agent).
|
|
5
5
|
# One event per line. Schema:
|
|
6
6
|
# {
|
|
7
7
|
# "ts": "<ISO 8601 timestamp>",
|
|
@@ -28,9 +28,10 @@
|
|
|
28
28
|
# log-metric.sh PROJ-1234 3 rework.started iteration=2 accepted_blocking=2
|
|
29
29
|
# log-metric.sh #316 5 task.completed phases=6 review_cycles=2 lang=tr
|
|
30
30
|
#
|
|
31
|
-
# Atomic append: each call uses `>> "$file"
|
|
32
|
-
#
|
|
33
|
-
#
|
|
31
|
+
# Atomic append: each call uses `>> "$file"`, which opens with O_APPEND, and
|
|
32
|
+
# writes the whole line in one `echo`. On a local filesystem an O_APPEND write
|
|
33
|
+
# lands at the end of the file in one piece, so concurrent pipeline runs do not
|
|
34
|
+
# interleave.
|
|
34
35
|
#
|
|
35
36
|
# Failure mode: if the metrics directory is unwritable, we WARN to stderr but
|
|
36
37
|
# do NOT fail the pipeline. Telemetry is best-effort, never load-bearing.
|
|
@@ -46,7 +47,7 @@ TASK_ID="$1"; shift
|
|
|
46
47
|
PHASE="$1"; shift
|
|
47
48
|
EVENT="$1"; shift
|
|
48
49
|
|
|
49
|
-
METRICS_FILE="${METRICS_FILE:-$HOME/.claude/logs/multi-agent/metrics.jsonl}"
|
|
50
|
+
METRICS_FILE="${METRICS_FILE:-${LOGS_ROOT:-$HOME/.claude/logs/multi-agent}/metrics.jsonl}"
|
|
50
51
|
METRICS_DIR="$(dirname "$METRICS_FILE")"
|
|
51
52
|
|
|
52
53
|
mkdir -p "$METRICS_DIR" 2>/dev/null || {
|
|
@@ -10,8 +10,9 @@
|
|
|
10
10
|
* reason.
|
|
11
11
|
*
|
|
12
12
|
* This module decides the follow-up. It is PURE - no network, no git, no issue
|
|
13
|
-
* API, no clock unless one is handed to it - because the
|
|
14
|
-
* worth testing and the I/O around it is the part that
|
|
13
|
+
* API, no clock and no language unless one is handed to it - because the
|
|
14
|
+
* decision is the part worth testing and the I/O around it is the part that
|
|
15
|
+
* differs per host.
|
|
15
16
|
*
|
|
16
17
|
* THE RULE THAT SHAPES EVERYTHING: an edit is a reason to look again, never
|
|
17
18
|
* proof that the gap closed. A reply reading "will do later" moves the
|
|
@@ -27,6 +28,8 @@
|
|
|
27
28
|
* @module pipeline/scripts/maturity-followup
|
|
28
29
|
*/
|
|
29
30
|
|
|
31
|
+
import { outputLanguage } from "../lib/user-facing.mjs";
|
|
32
|
+
|
|
30
33
|
/**
|
|
31
34
|
* The first line of any comment this pipeline writes about maturity.
|
|
32
35
|
*
|
|
@@ -38,6 +41,10 @@
|
|
|
38
41
|
* BOTH a human skimming the thread and the next scan looking for its own prior
|
|
39
42
|
* comment, because posting the same question twice is how an unattended queue
|
|
40
43
|
* turns an issue into a wall of identical bot comments.
|
|
44
|
+
*
|
|
45
|
+
* It carries both languages and does not follow `outputLanguage`: it is matched,
|
|
46
|
+
* not read, and the scan that finds it may run under a different preference from
|
|
47
|
+
* the one that wrote it.
|
|
41
48
|
*/
|
|
42
49
|
export const MARKER = "multi-agent: Bu madde geliştirmeye hazır değil / not ready to develop yet";
|
|
43
50
|
|
|
@@ -232,10 +239,12 @@ export function decide({ maturity, mode, prior = null, artifact = {}, prefs = {}
|
|
|
232
239
|
* @param {string} [input.taskRef] what to point back at, e.g. `PROJ-1234`
|
|
233
240
|
* @param {string[]} [input.gaps] the codes, recorded on the item so the NEXT run
|
|
234
241
|
* can tell what was already asked without our state file
|
|
235
|
-
* @param {"tr"|"en"} [input.lang]
|
|
242
|
+
* @param {"tr"|"en"} [input.lang] - defaults to `prefs.global.outputLanguage`,
|
|
243
|
+
* which is the only value this module reads
|
|
244
|
+
* from outside its arguments.
|
|
236
245
|
* @returns {string}
|
|
237
246
|
*/
|
|
238
|
-
export function commentBody({ summary, taskRef = "", lang =
|
|
247
|
+
export function commentBody({ summary, taskRef = "", lang = outputLanguage(), gaps = [] } = {}) {
|
|
239
248
|
const body = String(summary || "").trim();
|
|
240
249
|
const codes = [...new Set((gaps || []).filter(isCode))].sort();
|
|
241
250
|
const tr = [
|
|
@@ -7,18 +7,43 @@
|
|
|
7
7
|
#
|
|
8
8
|
# Usage:
|
|
9
9
|
# memory-save.sh <project-root> <type> <slug> <body-file>
|
|
10
|
+
# memory-save.sh <project-root> --from-json <synthesis.json>
|
|
10
11
|
#
|
|
11
12
|
# type = user | feedback | project | reference
|
|
12
13
|
# slug = kebab-case filename fragment (e.g. "audit-exhaustiveness")
|
|
13
14
|
# body-file= path to a file containing the frontmatter-wrapped memory body
|
|
14
15
|
# (or "-" to read body from stdin)
|
|
15
16
|
#
|
|
17
|
+
# --from-json saves every {type, slug, body} entry of a JSON array, in order,
|
|
18
|
+
# exactly as one call per entry would. Phase 5's synthesis step uses it so the
|
|
19
|
+
# save is one command rather than a shell loop over the array.
|
|
20
|
+
#
|
|
16
21
|
# Writes to $PROJECT_ROOT/.multi-agent/memory/<type>_<slug>.md and prepends
|
|
17
22
|
# a bullet to MEMORY.md. Idempotent - overwriting an existing slug replaces
|
|
18
23
|
# the file but leaves the index entry position unchanged.
|
|
19
24
|
|
|
20
25
|
set -euo pipefail
|
|
21
26
|
|
|
27
|
+
if [ "${2:-}" = "--from-json" ]; then
|
|
28
|
+
root="${1:?usage: memory-save.sh <project-root> --from-json <synthesis.json>}"
|
|
29
|
+
syn="${3:?usage: memory-save.sh <project-root> --from-json <synthesis.json>}"
|
|
30
|
+
command -v jq >/dev/null 2>&1 || { echo "memory-save: jq is required for --from-json" >&2; exit 1; }
|
|
31
|
+
n=$(jq 'if type == "array" then length else error("not an array") end' "$syn") || {
|
|
32
|
+
echo "memory-save: $syn is not a JSON array" >&2
|
|
33
|
+
exit 1
|
|
34
|
+
}
|
|
35
|
+
rc=0
|
|
36
|
+
i=0
|
|
37
|
+
while [ "$i" -lt "$n" ]; do
|
|
38
|
+
body=$(jq -r ".[$i].body" "$syn")
|
|
39
|
+
type=$(jq -r ".[$i].type" "$syn")
|
|
40
|
+
slug=$(jq -r ".[$i].slug" "$syn")
|
|
41
|
+
printf '%s\n' "$body" | bash "${BASH_SOURCE[0]}" "$root" "$type" "$slug" - || rc=1
|
|
42
|
+
i=$((i + 1))
|
|
43
|
+
done
|
|
44
|
+
exit "$rc"
|
|
45
|
+
fi
|
|
46
|
+
|
|
22
47
|
PROJECT_ROOT="${1:?usage: memory-save.sh <project-root> <type> <slug> <body-file|->}"
|
|
23
48
|
TYPE="${2:?missing type}"
|
|
24
49
|
SLUG="${3:?missing slug}"
|
|
@@ -15,6 +15,7 @@ import path from "node:path";
|
|
|
15
15
|
import os from "node:os";
|
|
16
16
|
import { fileURLToPath } from "node:url";
|
|
17
17
|
import { runMain } from "../lib/fatal.mjs";
|
|
18
|
+
import { lockTimeoutFrom, withFileLockSync, writeJsonAtomicSync } from "../lib/json-file-lock.mjs";
|
|
18
19
|
|
|
19
20
|
const DEFAULT_FILE = path.join(os.homedir(), ".claude", "multi-agent-preferences.json");
|
|
20
21
|
|
|
@@ -522,9 +523,9 @@ function migrateReportChannels(out, changes) {
|
|
|
522
523
|
}
|
|
523
524
|
|
|
524
525
|
function atomicWrite(filePath, data) {
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
526
|
+
withFileLockSync(filePath, () => writeJsonAtomicSync(filePath, data, { mode: 0o600 }), {
|
|
527
|
+
timeoutMs: lockTimeoutFrom(process.env),
|
|
528
|
+
});
|
|
528
529
|
}
|
|
529
530
|
|
|
530
531
|
function main() {
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* open-questions-gate.mjs - an unattended run does not build on a question
|
|
4
|
+
* nobody answered.
|
|
5
|
+
*
|
|
6
|
+
* Phase 1 Step 5 asks each open Section 20 row; autopilot cannot ask, so it
|
|
7
|
+
* defers every row into `state.analysis.openQuestions[]`. An attended run then
|
|
8
|
+
* flags those rows at review. An unattended run has no reviewer who can answer
|
|
9
|
+
* them either, and development built on a guessed answer is the work most
|
|
10
|
+
* likely to be thrown away. So at the Phase 1 -> Phase 2 transition, a
|
|
11
|
+
* non-empty list parks the run instead: `waitingFor: "question"`,
|
|
12
|
+
* `status: "awaiting_input"` and a `pendingQuestion` (stepId
|
|
13
|
+
* phase-1/open-questions) that `resume <id> --answer <optionId>` or a client
|
|
14
|
+
* answers through answer-question.mjs. The runner reports it as
|
|
15
|
+
* awaiting-answer and never re-runs it on its own.
|
|
16
|
+
*
|
|
17
|
+
* Re-entry. Once the question is answered (`state.lastAnswer`, stepId
|
|
18
|
+
* phase-1/open-questions, recorded after the gate's latest `fail` entry), the
|
|
19
|
+
* re-entered step runs this gate again and the gate applies the answer, so the
|
|
20
|
+
* ledger's latest entry reflects it:
|
|
21
|
+
*
|
|
22
|
+
* assume every row moves to `state.analysis.assumptions[]`, the list is
|
|
23
|
+
* emptied, the run is no longer awaiting input: `pass`.
|
|
24
|
+
* ask-now with MULTI_AGENT_UNATTENDED=1 nobody is in the session to ask, so
|
|
25
|
+
* the run parks again on the same question: `fail`. Without it the
|
|
26
|
+
* step asks each row first and empties the list, and the gate then
|
|
27
|
+
* evaluates the list as usual.
|
|
28
|
+
* abort the run stops as verification-failed at open-questions: `fail`.
|
|
29
|
+
*
|
|
30
|
+
* Runs only while the quality gates are active (lib/unattended.mjs,
|
|
31
|
+
* gatesActive): MULTI_AGENT_UNATTENDED=1, or a run in autopilot mode, which
|
|
32
|
+
* cannot ask either. Otherwise it prints a not-applicable verdict, exits 0 and
|
|
33
|
+
* touches nothing.
|
|
34
|
+
*
|
|
35
|
+
* Usage:
|
|
36
|
+
* node open-questions-gate.mjs [--state <agent-state.json>] [--repo <dir>] [--json]
|
|
37
|
+
*
|
|
38
|
+
* Exit: 0 no open question (or not-applicable) · 1 parked, or stopped by `abort` · 2 usage ·
|
|
39
|
+
* 3 no state
|
|
40
|
+
*
|
|
41
|
+
* @module pipeline/scripts/open-questions-gate
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
45
|
+
|
|
46
|
+
import { invokedDirectly } from "../lib/invoked-directly.mjs";
|
|
47
|
+
import { attendedVerdict, isUnattended } from "../lib/unattended.mjs";
|
|
48
|
+
import { gateContext, park, recordQuietly, updateState } from "./gate-ledger.mjs";
|
|
49
|
+
|
|
50
|
+
const GATE = "open-questions";
|
|
51
|
+
export const STEP_ID = "phase-1/open-questions";
|
|
52
|
+
export const OPTIONS = Object.freeze([
|
|
53
|
+
{ id: "ask-now", label: "Ask each question in this session, then continue" },
|
|
54
|
+
{ id: "assume", label: "Continue, recording each question as a stated assumption" },
|
|
55
|
+
{ id: "abort", label: "Stop this run" },
|
|
56
|
+
]);
|
|
57
|
+
const TEXT_MAX = 2000;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* The question the run parks on, in the shape answer-question.mjs answers.
|
|
61
|
+
*
|
|
62
|
+
* @param {string[]} questions
|
|
63
|
+
*/
|
|
64
|
+
export function pendingQuestionFor(questions) {
|
|
65
|
+
const head = `${questions.length} analysis question(s) are open; development has not started.`;
|
|
66
|
+
let text = head;
|
|
67
|
+
for (const q of questions) {
|
|
68
|
+
const line = `\n- ${q}`;
|
|
69
|
+
if (text.length + line.length > TEXT_MAX) break;
|
|
70
|
+
text += line;
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
id: "open-questions",
|
|
74
|
+
stepId: STEP_ID,
|
|
75
|
+
text,
|
|
76
|
+
kind: "single-select",
|
|
77
|
+
options: OPTIONS.map((o) => ({ ...o })),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* @param {object|null} state
|
|
83
|
+
* @returns {{gate: string, verdict: string, open: number, questions: string[], reason?: string}}
|
|
84
|
+
*/
|
|
85
|
+
export function evaluateOpenQuestions(state) {
|
|
86
|
+
const list = state?.analysis?.openQuestions;
|
|
87
|
+
if (!Array.isArray(list)) {
|
|
88
|
+
return {
|
|
89
|
+
gate: GATE,
|
|
90
|
+
verdict: "not-applicable",
|
|
91
|
+
open: 0,
|
|
92
|
+
questions: [],
|
|
93
|
+
reason: "no state.analysis.openQuestions[] recorded (no Phase 1 analysis in this mode)",
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
const questions = list.map((q) =>
|
|
97
|
+
typeof q === "string" ? q : q?.question || q?.title || q?.id || JSON.stringify(q),
|
|
98
|
+
);
|
|
99
|
+
return { gate: GATE, verdict: list.length ? "fail" : "pass", open: list.length, questions };
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* The option answered for this gate's latest park, or null. An answer older
|
|
104
|
+
* than the latest `fail` entry, or one for another step, is not this park's.
|
|
105
|
+
*
|
|
106
|
+
* @param {object|null} state
|
|
107
|
+
* @returns {string|null}
|
|
108
|
+
*/
|
|
109
|
+
export function pendingAnswer(state) {
|
|
110
|
+
const a = state?.lastAnswer;
|
|
111
|
+
if (!a || a.stepId !== STEP_ID || !Array.isArray(a.optionIds)) return null;
|
|
112
|
+
const mine = (Array.isArray(state.gates) ? state.gates : []).filter((g) => g?.gate === GATE);
|
|
113
|
+
const last = mine.at(-1);
|
|
114
|
+
if (!last || last.verdict !== "fail") return null;
|
|
115
|
+
if (!(Date.parse(a.answeredAt) >= Date.parse(last.at))) return null;
|
|
116
|
+
const id = a.optionIds[0];
|
|
117
|
+
return OPTIONS.some((o) => o.id === id) ? id : null;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* The verdict once an answer is applied. Pure.
|
|
122
|
+
*
|
|
123
|
+
* @param {object} state
|
|
124
|
+
* @param {string} answer one of OPTIONS[].id
|
|
125
|
+
* @param {{unattended: boolean, now?: Date}} opts
|
|
126
|
+
* @returns {{result: object, next: object|null, stop: boolean}}
|
|
127
|
+
*/
|
|
128
|
+
export function applyOpenAnswer(state, answer, { unattended, now = new Date() }) {
|
|
129
|
+
const base = evaluateOpenQuestions(state);
|
|
130
|
+
if (answer === "abort") {
|
|
131
|
+
return {
|
|
132
|
+
result: {
|
|
133
|
+
...base,
|
|
134
|
+
verdict: "fail",
|
|
135
|
+
answer,
|
|
136
|
+
reason: "stopped by the answer abort; nothing developed",
|
|
137
|
+
},
|
|
138
|
+
next: null,
|
|
139
|
+
stop: true,
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
if (answer === "assume" && base.open > 0) {
|
|
143
|
+
const at = now.toISOString();
|
|
144
|
+
const prior = Array.isArray(state.analysis?.assumptions) ? state.analysis.assumptions : [];
|
|
145
|
+
const next = {
|
|
146
|
+
...state,
|
|
147
|
+
status: state.status === "awaiting_input" ? "in_progress" : state.status,
|
|
148
|
+
analysis: {
|
|
149
|
+
...state.analysis,
|
|
150
|
+
openQuestions: [],
|
|
151
|
+
assumptions: [
|
|
152
|
+
...prior,
|
|
153
|
+
...base.questions.map((question) => ({ question, source: STEP_ID, assumedAt: at })),
|
|
154
|
+
],
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
delete next.haltReason;
|
|
158
|
+
return {
|
|
159
|
+
result: { gate: GATE, verdict: "pass", open: 0, questions: [], answer, assumed: base.open },
|
|
160
|
+
next,
|
|
161
|
+
stop: false,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
if (answer === "ask-now" && unattended && base.open > 0) {
|
|
165
|
+
return {
|
|
166
|
+
result: {
|
|
167
|
+
...base,
|
|
168
|
+
answer,
|
|
169
|
+
reason: "ask-now needs a person in the session, and MULTI_AGENT_UNATTENDED=1 has none",
|
|
170
|
+
},
|
|
171
|
+
next: null,
|
|
172
|
+
stop: false,
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
return { result: { ...base, answer }, next: null, stop: false };
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function out(json, result) {
|
|
179
|
+
if (json) writeFileSync(1, `${JSON.stringify(result, null, 2)}\n`);
|
|
180
|
+
else if (result.verdict === "fail" && result.answer) {
|
|
181
|
+
writeFileSync(1, `open-questions: fail (${result.reason || `answer ${result.answer}`})\n`);
|
|
182
|
+
} else if (result.verdict === "fail") {
|
|
183
|
+
writeFileSync(
|
|
184
|
+
1,
|
|
185
|
+
`open-questions: ${result.open} open question(s); development does not start, the run parks awaiting an answer:\n${result.questions.map((q) => ` - ${q}`).join("\n")}\n`,
|
|
186
|
+
);
|
|
187
|
+
} else
|
|
188
|
+
writeFileSync(
|
|
189
|
+
1,
|
|
190
|
+
`open-questions: ${result.verdict}${result.reason ? ` (${result.reason})` : ""}\n`,
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
async function main(argv) {
|
|
195
|
+
const opts = { json: argv.includes("--json") };
|
|
196
|
+
for (let i = 0; i < argv.length; i++) {
|
|
197
|
+
if (argv[i] === "--json") continue;
|
|
198
|
+
if (argv[i] === "--state" || argv[i] === "--repo") {
|
|
199
|
+
if (argv[i + 1] === undefined) {
|
|
200
|
+
process.stderr.write(`open-questions-gate: ${argv[i]} needs a value\n`);
|
|
201
|
+
return 2;
|
|
202
|
+
}
|
|
203
|
+
opts[argv[i].slice(2)] = argv[++i];
|
|
204
|
+
} else {
|
|
205
|
+
process.stderr.write(`open-questions-gate: unexpected argument ${argv[i]}\n`);
|
|
206
|
+
return 2;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
const ctx = gateContext({ statePath: opts.state || null, repo: opts.repo || process.cwd() });
|
|
210
|
+
if (!ctx.active) {
|
|
211
|
+
out(opts.json, attendedVerdict(GATE));
|
|
212
|
+
return 0;
|
|
213
|
+
}
|
|
214
|
+
const path = ctx.statePath;
|
|
215
|
+
if (!path || !existsSync(path)) {
|
|
216
|
+
process.stderr.write(
|
|
217
|
+
"open-questions-gate: no run state found; cannot tell whether a question is open\n",
|
|
218
|
+
);
|
|
219
|
+
return 3;
|
|
220
|
+
}
|
|
221
|
+
let state;
|
|
222
|
+
try {
|
|
223
|
+
state = JSON.parse(readFileSync(path, "utf8"));
|
|
224
|
+
} catch (err) {
|
|
225
|
+
process.stderr.write(`open-questions-gate: ${path} is not JSON: ${err.message}\n`);
|
|
226
|
+
return 3;
|
|
227
|
+
}
|
|
228
|
+
const answer = pendingAnswer(state);
|
|
229
|
+
let result = evaluateOpenQuestions(state);
|
|
230
|
+
let stop = false;
|
|
231
|
+
if (answer) {
|
|
232
|
+
const applied = applyOpenAnswer(state, answer, { unattended: isUnattended() });
|
|
233
|
+
result = applied.result;
|
|
234
|
+
stop = applied.stop;
|
|
235
|
+
if (applied.next) {
|
|
236
|
+
const next = applied.next;
|
|
237
|
+
await updateState(path, (s) => {
|
|
238
|
+
const n = { ...s, status: next.status, analysis: next.analysis };
|
|
239
|
+
delete n.haltReason;
|
|
240
|
+
return n;
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
const repo =
|
|
245
|
+
opts.repo ||
|
|
246
|
+
(typeof state.worktreePath === "string" && existsSync(state.worktreePath)
|
|
247
|
+
? state.worktreePath
|
|
248
|
+
: process.cwd());
|
|
249
|
+
await recordQuietly(
|
|
250
|
+
GATE,
|
|
251
|
+
result.verdict,
|
|
252
|
+
{
|
|
253
|
+
open: result.open,
|
|
254
|
+
...(result.answer ? { answer: result.answer } : {}),
|
|
255
|
+
...(result.assumed ? { assumed: result.assumed } : {}),
|
|
256
|
+
...(result.reason ? { reason: result.reason } : {}),
|
|
257
|
+
},
|
|
258
|
+
{ repo, statePath: path },
|
|
259
|
+
);
|
|
260
|
+
if (stop) {
|
|
261
|
+
await park(path, { outcome: "verification-failed", gate: GATE, reason: result.reason });
|
|
262
|
+
} else if (result.verdict === "fail") {
|
|
263
|
+
await park(path, {
|
|
264
|
+
outcome: "awaiting-answer",
|
|
265
|
+
waitingFor: "question",
|
|
266
|
+
pendingQuestion: pendingQuestionFor(result.questions),
|
|
267
|
+
reason: `${result.open} open question(s) from analysis Section 20; development did not start`,
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
out(opts.json, result);
|
|
271
|
+
return result.verdict === "fail" ? 1 : 0;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
if (invokedDirectly(import.meta.url)) {
|
|
275
|
+
main(process.argv.slice(2)).then((code) => process.exit(code));
|
|
276
|
+
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
#
|
|
10
10
|
# State persists to a per-task JSON file so multiple shell invocations
|
|
11
11
|
# share the same task list:
|
|
12
|
-
# $HOME/.claude/logs/multi-agent/<task_id>/tracker-state.json
|
|
12
|
+
# ${LOGS_ROOT:-$HOME/.claude/logs/multi-agent}/<task_id>/tracker-state.json
|
|
13
13
|
# (override with $TRACKER_FILE env var)
|
|
14
14
|
#
|
|
15
15
|
# `init` writes that flat path. READS go through pipeline/lib/run-paths.sh,
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
# OTel span emission (v6.1.0+, opt-in):
|
|
34
34
|
# Set $MULTI_AGENT_OTEL_SPANS=1 to make every `update`, `sub`, and `tokens`
|
|
35
35
|
# action append one JSON line to:
|
|
36
|
-
# $HOME/.claude/logs/multi-agent/<task_id>/otel-spans.jsonl
|
|
36
|
+
# ${LOGS_ROOT:-$HOME/.claude/logs/multi-agent}/<task_id>/otel-spans.jsonl
|
|
37
37
|
# Each line is an OTLP-compatible JSON span with trace_id/span_id derived
|
|
38
38
|
# from the task_id, phase_id, and timestamp. Format intentionally simple
|
|
39
39
|
# so an OTel Collector's `filelog` receiver can tail + forward without a
|
|
@@ -59,7 +59,18 @@ set -uo pipefail
|
|
|
59
59
|
# Run-state path resolution: pipeline/lib/run-paths.sh owns both layouts.
|
|
60
60
|
_MA_RP_HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
61
61
|
# shellcheck source=/dev/null
|
|
62
|
-
|
|
62
|
+
if [ -f "$_MA_RP_HERE/../lib/run-paths.sh" ]; then . "$_MA_RP_HERE/../lib/run-paths.sh"; else . "$HOME/.claude/lib/run-paths.sh"; fi
|
|
63
|
+
# The card's column headings are script chrome and stay English; the dependency
|
|
64
|
+
# annotation inside a sub-phase name is prose, so it follows outputLanguage.
|
|
65
|
+
# shellcheck source=/dev/null
|
|
66
|
+
if [ -f "$_MA_RP_HERE/../lib/user-facing.sh" ]; then . "$_MA_RP_HERE/../lib/user-facing.sh"; else . "$HOME/.claude/lib/user-facing.sh"; fi
|
|
67
|
+
|
|
68
|
+
waiting_word() {
|
|
69
|
+
case "$(ma_output_lang)" in
|
|
70
|
+
tr) printf 'bekliyor' ;;
|
|
71
|
+
*) printf 'waiting on' ;;
|
|
72
|
+
esac
|
|
73
|
+
}
|
|
63
74
|
|
|
64
75
|
|
|
65
76
|
if [ "$#" -lt 1 ]; then
|
|
@@ -108,7 +119,7 @@ if [ -z "$TRACKER_FILE" ]; then
|
|
|
108
119
|
# `phase-tracker.sh init <other-task>`. In concurrent multi-agent runs (two terminals,
|
|
109
120
|
# two parallel pipelines), the pointer becomes the wrong task. Always pass
|
|
110
121
|
# MULTI_AGENT_TASK_ID per shell invocation for reliable per-session resolution.
|
|
111
|
-
POINTER="$HOME/.claude/logs/multi-agent/.tracker-current"
|
|
122
|
+
POINTER="${LOGS_ROOT:-$HOME/.claude/logs/multi-agent}/.tracker-current"
|
|
112
123
|
if [ -f "$POINTER" ]; then
|
|
113
124
|
TRACKER_FILE="$(cat "$POINTER")"
|
|
114
125
|
if [ "${MULTI_AGENT_QUIET:-0}" != "1" ]; then
|
|
@@ -126,7 +137,7 @@ if [ -z "$TRACKER_FILE" ]; then
|
|
|
126
137
|
# A run that does not exist yet resolves to the flat path, which is exactly
|
|
127
138
|
# where `init` will create it - so new-run behaviour is unchanged.
|
|
128
139
|
TRACKER_FILE="$(ma_resolve_run_file "$TASK_ID_FROM_ENV" tracker-state.json 2>/dev/null \
|
|
129
|
-
|| echo "$HOME/.claude/logs/multi-agent/${TASK_ID_FROM_ENV}/tracker-state.json")"
|
|
140
|
+
|| echo "${LOGS_ROOT:-$HOME/.claude/logs/multi-agent}/${TASK_ID_FROM_ENV}/tracker-state.json")"
|
|
130
141
|
fi
|
|
131
142
|
fi
|
|
132
143
|
TRACKER_DIR="$(dirname "$TRACKER_FILE")"
|
|
@@ -138,11 +149,12 @@ need_jq() {
|
|
|
138
149
|
}
|
|
139
150
|
}
|
|
140
151
|
|
|
141
|
-
# Live usage ping (best-effort). Emits one per
|
|
142
|
-
# dashboard via usage-report.mjs
|
|
143
|
-
#
|
|
144
|
-
# the
|
|
145
|
-
# unless prefs.global.usageLog.enabled; detached
|
|
152
|
+
# Live usage ping (best-effort). Emits one update per phase transition to the
|
|
153
|
+
# private dashboard via usage-report.mjs (`--event phase`). The emitter derives
|
|
154
|
+
# the run status from agent-state.json and the current phase from this tracker;
|
|
155
|
+
# the completed / halted / parked events come from the phase docs that end,
|
|
156
|
+
# halt or park a run. It no-ops unless prefs.global.usageLog.enabled; detached
|
|
157
|
+
# so it never blocks a boundary.
|
|
146
158
|
usage_live_ping() {
|
|
147
159
|
# Smoke runs exercise this script's state handling, never the live dashboard -
|
|
148
160
|
# a test gate must not leave phantom "running" rows on the timeline.
|
|
@@ -166,7 +178,7 @@ usage_live_ping() {
|
|
|
166
178
|
# user who never enabled it pays nothing per phase boundary. jq is already a
|
|
167
179
|
# hard dependency of this script.
|
|
168
180
|
jq -e '.global.usageLog.enabled == true' "$prefs" >/dev/null 2>&1 || return 0
|
|
169
|
-
( node "$script" --task-id "$task" --phase "$phase" --
|
|
181
|
+
( node "$script" --task-id "$task" --phase "$phase" --event phase >/dev/null 2>&1 & ) 2>/dev/null || true
|
|
170
182
|
}
|
|
171
183
|
|
|
172
184
|
# Decode HTML entities in a tile title.
|
|
@@ -293,8 +305,7 @@ emit_otel_span() {
|
|
|
293
305
|
# Deterministic 128-bit trace_id from task_id, 64-bit span_id from event+phase+timestamp.
|
|
294
306
|
#
|
|
295
307
|
# sha256_hex, not `shasum` directly: this runs on every phase on every host, and
|
|
296
|
-
# `shasum` is a perl script
|
|
297
|
-
# containers. Without a fallback the ids came back empty and the span was written with
|
|
308
|
+
# `shasum` is a perl script and a trimmed toolchain may lack perl. Without a fallback the ids came back empty and the span was written with
|
|
298
309
|
# blank trace/span - valid JSON, useless telemetry, and no error to notice.
|
|
299
310
|
local trace_id span_id
|
|
300
311
|
trace_id=$(printf "%s" "$task_id" | sha256_hex | awk '{print substr($1,1,32)}')
|
|
@@ -480,13 +491,13 @@ state_lock_stale() {
|
|
|
480
491
|
kill -0 "$pid" 2>/dev/null && return 1
|
|
481
492
|
return 0
|
|
482
493
|
fi
|
|
483
|
-
# GNU form first, and not because of style.
|
|
484
|
-
#
|
|
485
|
-
#
|
|
486
|
-
#
|
|
487
|
-
# no pid file
|
|
488
|
-
#
|
|
489
|
-
#
|
|
494
|
+
# GNU form first, and not because of style. GNU coreutils can sit first on PATH on a
|
|
495
|
+
# mac (Homebrew gnubin), and there `stat -f` is a valid flag meaning --file-system,
|
|
496
|
+
# where `%m` prints the MOUNT POINT - so a BSD-first chain succeeds, returns
|
|
497
|
+
# something like `/`, never reaches the `||`, and the arithmetic below fails on a
|
|
498
|
+
# path: a stale lock with no pid file would never be reclaimed. BSD `stat -c` is
|
|
499
|
+
# simply invalid, so it errors and falls through cleanly - which is why this order
|
|
500
|
+
# works with either stat.
|
|
490
501
|
mtime=$(stat -c %Y "$TRACKER_LOCK_DIR" 2>/dev/null || stat -f %m "$TRACKER_LOCK_DIR" 2>/dev/null || echo "")
|
|
491
502
|
# Guard the arithmetic anyway: a non-numeric value here must not abort the caller
|
|
492
503
|
# under `set -u`, and treating it as "not stale" is the conservative branch.
|
|
@@ -616,7 +627,7 @@ tracker_next_hint() {
|
|
|
616
627
|
# `subjects` now carries Phase 1's plan steps as indented rows, and
|
|
617
628
|
# update_plan takes the whole list anyway, so re-reading it is what puts
|
|
618
629
|
# those steps on the Codex plan without a second mechanism. Codex has no
|
|
619
|
-
# dependency concept; the "(
|
|
630
|
+
# dependency concept; the "(waiting on: ...)" suffix inside the step text is
|
|
620
631
|
# where that information survives on this host.
|
|
621
632
|
codex) mirror="update_plan: set step \"Phase $pid $name\" to $status, re-reading the FULL list from \`phase-tracker.sh subjects\` (it is not a delta, and the indented rows are plan steps that belong in it)" ;;
|
|
622
633
|
*) mirror="no task widget on this host - reprint the card above inside your reply text" ;;
|
|
@@ -785,12 +796,12 @@ subjects() {
|
|
|
785
796
|
# exactly one string per row and has no parent field - there is no nesting
|
|
786
797
|
# to ask for, so the only place a hierarchy can be expressed is the string.
|
|
787
798
|
if [ -z "$want" ] || [ "$want" = "$pid" ]; then
|
|
788
|
-
echo "$state" | jq -r --arg pid "$pid" '
|
|
799
|
+
echo "$state" | jq -r --arg pid "$pid" --arg waiting "$(waiting_word)" '
|
|
789
800
|
([.phases[] | select(.id == $pid)][0].subs) // []
|
|
790
801
|
| .[]
|
|
791
802
|
| " " + (.id // "") + " " + (.name // "")
|
|
792
803
|
+ (if ((.deps // []) | length) > 0
|
|
793
|
-
then " (
|
|
804
|
+
then " (" + $waiting + ": " + ((.deps // []) | join(", ")) + ")"
|
|
794
805
|
else "" end)'
|
|
795
806
|
fi
|
|
796
807
|
done <<< "$rows"
|
|
@@ -1053,7 +1064,7 @@ render() {
|
|
|
1053
1064
|
while IFS=$'\x1f' read -r sid sname sstatus sdeps; do
|
|
1054
1065
|
# The card is the only surface a Copilot session has, so a dependency
|
|
1055
1066
|
# that is invisible here is invisible to that user entirely.
|
|
1056
|
-
[ -n "$sdeps" ] && sname="$sname (
|
|
1067
|
+
[ -n "$sdeps" ] && sname="$sname ($(waiting_word): $sdeps)"
|
|
1057
1068
|
sg=$(glyph_for "$sstatus")
|
|
1058
1069
|
connector="├─"
|
|
1059
1070
|
if [ "$j" = "$((sub_count - 1))" ]; then connector="└─"; fi
|
|
@@ -1095,7 +1106,7 @@ case "$ACTION" in
|
|
|
1095
1106
|
# Honor an explicit $TRACKER_FILE (tests, isolated runs); only derive the
|
|
1096
1107
|
# canonical home path when the caller did not supply one.
|
|
1097
1108
|
if [ "$TRACKER_FILE_FROM_ENV" != "1" ]; then
|
|
1098
|
-
TRACKER_FILE="$HOME/.claude/logs/multi-agent/${TASK_ID}/tracker-state.json"
|
|
1109
|
+
TRACKER_FILE="${LOGS_ROOT:-$HOME/.claude/logs/multi-agent}/${TASK_ID}/tracker-state.json"
|
|
1099
1110
|
fi
|
|
1100
1111
|
TRACKER_DIR="$(dirname "$TRACKER_FILE")"
|
|
1101
1112
|
mkdir -p "$TRACKER_DIR" 2>/dev/null
|
|
@@ -1113,7 +1124,7 @@ case "$ACTION" in
|
|
|
1113
1124
|
# (Smoke isolation is handled by a sandbox HOME, so it still writes a pointer
|
|
1114
1125
|
# inside its own tree - which its later calls depend on.)
|
|
1115
1126
|
if [ "$TRACKER_FILE_FROM_ENV" != "1" ]; then
|
|
1116
|
-
echo "$TRACKER_FILE" > "$HOME/.claude/logs/multi-agent/.tracker-current"
|
|
1127
|
+
echo "$TRACKER_FILE" > "${LOGS_ROOT:-$HOME/.claude/logs/multi-agent}/.tracker-current"
|
|
1117
1128
|
fi
|
|
1118
1129
|
render
|
|
1119
1130
|
usage_live_ping "$TASK_ID" 0
|
|
@@ -1210,7 +1221,10 @@ GATE
|
|
|
1210
1221
|
emit_otel_span "phase.update" "$PID" "$STATUS" "{\"status\": \"$STATUS\"}"
|
|
1211
1222
|
render
|
|
1212
1223
|
tracker_next_hint "$PID" "$STATUS"
|
|
1213
|
-
|
|
1224
|
+
if [ "$STATUS" = "completed" ] && command -v node >/dev/null 2>&1; then
|
|
1225
|
+
node "$(dirname "$0")/record-phase.mjs" --task-id "$(basename "$TRACKER_DIR")" --phase "$PID" >/dev/null 2>&1 || true
|
|
1226
|
+
fi
|
|
1227
|
+
[ "$STATUS" = "pending" ] || usage_live_ping "$(basename "$TRACKER_DIR")" "$PID"
|
|
1214
1228
|
;;
|
|
1215
1229
|
|
|
1216
1230
|
plan)
|