@mmerterden/multi-agent-pipeline 20.2.1 → 20.3.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/CHANGELOG.md +912 -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 +616 -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/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 +185 -65
- package/pipeline/scripts/usage-report.mjs +230 -66
- 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
|
@@ -25,7 +25,11 @@ set -uo pipefail
|
|
|
25
25
|
JSON=0
|
|
26
26
|
[ "${1:-}" = "--json" ] && JSON=1
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
_MA_CR_HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
29
|
+
# shellcheck source=/dev/null
|
|
30
|
+
if [ -f "$_MA_CR_HERE/../lib/user-facing.sh" ]; then . "$_MA_CR_HERE/../lib/user-facing.sh"; else . "$HOME/.claude/lib/user-facing.sh"; fi
|
|
31
|
+
|
|
32
|
+
LOGS="${LOGS_ROOT:-$HOME/.claude/logs/multi-agent}"
|
|
29
33
|
PIPELINE_MEM="$HOME/.claude/memory/multi-agent/_pipeline"
|
|
30
34
|
REVIEW_DAYS=7
|
|
31
35
|
|
|
@@ -131,19 +135,19 @@ fi
|
|
|
131
135
|
# "13 runs" call for different reactions and the old line could not tell them
|
|
132
136
|
# apart.
|
|
133
137
|
if [ "$AWAITING_N" -gt 0 ]; then
|
|
134
|
-
printf 'multi-agent: %s run(s) waiting on you, oldest %s at Phase %s -
|
|
135
|
-
"$AWAITING_N" "$AWAITING_TASK" "$AWAITING_PHASE"
|
|
138
|
+
printf 'multi-agent: %s run(s) waiting on you, oldest %s at Phase %s - `%s` to finish.\n' \
|
|
139
|
+
"$AWAITING_N" "$AWAITING_TASK" "$AWAITING_PHASE" "$(ma_command resume)"
|
|
136
140
|
fi
|
|
137
141
|
if [ "$DIED_N" -gt 0 ]; then
|
|
138
|
-
printf 'multi-agent: %s run(s) stopped mid-development, oldest %s at Phase %s -
|
|
139
|
-
"$DIED_N" "$DIED_TASK" "$DIED_PHASE"
|
|
142
|
+
printf 'multi-agent: %s run(s) stopped mid-development, oldest %s at Phase %s - `%s` or `%s`.\n' \
|
|
143
|
+
"$DIED_N" "$DIED_TASK" "$DIED_PHASE" "$(ma_command resume)" "$(ma_command kill)"
|
|
140
144
|
fi
|
|
141
145
|
if [ "$UNSTARTED_N" -gt 0 ]; then
|
|
142
|
-
printf 'multi-agent: %s run(s) left at a Phase 0 question, nothing built -
|
|
143
|
-
"$UNSTARTED_N"
|
|
146
|
+
printf 'multi-agent: %s run(s) left at a Phase 0 question, nothing built - `%s --abandoned` to clear.\n' \
|
|
147
|
+
"$UNSTARTED_N" "$(ma_command garbage-collect)"
|
|
144
148
|
fi
|
|
145
149
|
if [ "$REVIEW_DUE" -eq 1 ]; then
|
|
146
|
-
printf 'multi-agent: %s open pipeline observation(s), last review %s+ days ago -
|
|
147
|
-
"$OPEN_OBS" "$REVIEW_DAYS"
|
|
150
|
+
printf 'multi-agent: %s open pipeline observation(s), last review %s+ days ago - `%s backlog` when convenient.\n' \
|
|
151
|
+
"$OPEN_OBS" "$REVIEW_DAYS" "$(ma_command refactor)"
|
|
148
152
|
fi
|
|
149
153
|
exit 0
|
|
@@ -69,6 +69,48 @@ function versionFrom(manifest, pluginName) {
|
|
|
69
69
|
return manifest.version ?? null;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
function fetchAge(root) {
|
|
73
|
+
try {
|
|
74
|
+
const fetchHead = join(root, ".git", "FETCH_HEAD");
|
|
75
|
+
return existsSync(fetchHead)
|
|
76
|
+
? Math.floor((Date.now() - statSync(fetchHead).mtimeMs) / 86_400_000)
|
|
77
|
+
: null;
|
|
78
|
+
} catch {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// An upstream that ships no manifest (an app repo whose standards live in a
|
|
84
|
+
// few directories) is versioned by commit. The recorded version is the commit
|
|
85
|
+
// the port was taken from; drift is any later commit on the ref that touches
|
|
86
|
+
// one of the named paths, so unrelated app commits never count.
|
|
87
|
+
function fromGitPaths(entry) {
|
|
88
|
+
if (!entry.upstreamLocalClone || !Array.isArray(entry.upstreamPaths)) return null;
|
|
89
|
+
const root = expandHome(entry.upstreamLocalClone);
|
|
90
|
+
const ref = entry.upstreamRef || "origin/main";
|
|
91
|
+
const git = (...args) =>
|
|
92
|
+
execFileSync("git", ["-C", root, ...args], {
|
|
93
|
+
encoding: "utf-8",
|
|
94
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
95
|
+
}).trim();
|
|
96
|
+
try {
|
|
97
|
+
const recorded = git("rev-parse", "--verify", `${entry.derivedFromVersion}^{commit}`);
|
|
98
|
+
const later = git("rev-list", "--count", `${recorded}..${ref}`, "--", ...entry.upstreamPaths);
|
|
99
|
+
const version =
|
|
100
|
+
Number(later) === 0
|
|
101
|
+
? entry.derivedFromVersion
|
|
102
|
+
: git("log", "-1", "--format=%h", ref, "--", ...entry.upstreamPaths);
|
|
103
|
+
return {
|
|
104
|
+
version,
|
|
105
|
+
source: `local clone ${ref}`,
|
|
106
|
+
authoritative: true,
|
|
107
|
+
fetchAgeDays: fetchAge(root),
|
|
108
|
+
};
|
|
109
|
+
} catch {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
72
114
|
function fromLocalClone(entry) {
|
|
73
115
|
if (!entry.upstreamLocalClone) return null;
|
|
74
116
|
const root = expandHome(entry.upstreamLocalClone);
|
|
@@ -89,16 +131,12 @@ function fromLocalClone(entry) {
|
|
|
89
131
|
if (version) {
|
|
90
132
|
// origin/main is only as fresh as the last fetch. Surface fetch age so a
|
|
91
133
|
// months-old ref is not silently trusted.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
} catch {
|
|
99
|
-
fetchAgeDays = null;
|
|
100
|
-
}
|
|
101
|
-
return { version, source: "local clone origin/main", authoritative: true, fetchAgeDays };
|
|
134
|
+
return {
|
|
135
|
+
version,
|
|
136
|
+
source: "local clone origin/main",
|
|
137
|
+
authoritative: true,
|
|
138
|
+
fetchAgeDays: fetchAge(root),
|
|
139
|
+
};
|
|
102
140
|
}
|
|
103
141
|
} catch {
|
|
104
142
|
// No origin/main ref (not a git checkout, or unfetched): fall through to
|
|
@@ -163,7 +201,10 @@ if (entries.length === 0) {
|
|
|
163
201
|
|
|
164
202
|
const rows = [];
|
|
165
203
|
for (const entry of entries) {
|
|
166
|
-
const resolved =
|
|
204
|
+
const resolved =
|
|
205
|
+
entry.upstreamVersionSource === "git-paths"
|
|
206
|
+
? fromGitPaths(entry)
|
|
207
|
+
: fromLocalClone(entry) || fromRepoApi(entry) || fromCache(entry);
|
|
167
208
|
if (!resolved) {
|
|
168
209
|
rows.push({
|
|
169
210
|
label: entry.label,
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* @file commands.mjs - the command catalog a client renders from.
|
|
4
|
+
*
|
|
5
|
+
* Prints every /multi-agent:<id> command with its declared parameters, its
|
|
6
|
+
* surface (button, form, hidden) and whether it needs a confirmation, read from
|
|
7
|
+
* the SKILL.md frontmatter by the same reader lint-skills.mjs holds to the
|
|
8
|
+
* contract. Shape: pipeline/schemas/command-parameters.schema.json.
|
|
9
|
+
*
|
|
10
|
+
* Nothing in the catalog is machine- or person-specific, so `--redact` is
|
|
11
|
+
* accepted for symmetry with the other contract outputs and changes nothing.
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* node commands.mjs --json [--redact] [--dir <commandsDir>]
|
|
15
|
+
*
|
|
16
|
+
* The directory defaults to the source tree beside this script, then to the
|
|
17
|
+
* installed copy under ~/.claude/commands/multi-agent.
|
|
18
|
+
*
|
|
19
|
+
* Exit: 0 printed, 2 usage error or no command tree found.
|
|
20
|
+
*
|
|
21
|
+
* @module pipeline/scripts/commands
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import { existsSync } from "node:fs";
|
|
25
|
+
import { homedir } from "node:os";
|
|
26
|
+
import { join } from "node:path";
|
|
27
|
+
import { fileURLToPath } from "node:url";
|
|
28
|
+
import { CONTRACT_VERSION, loadCatalog } from "./_command-contract.mjs";
|
|
29
|
+
import { runMain } from "../lib/fatal.mjs";
|
|
30
|
+
import { invokedDirectly } from "../lib/invoked-directly.mjs";
|
|
31
|
+
|
|
32
|
+
export function commandsDir(explicit) {
|
|
33
|
+
if (explicit) return explicit;
|
|
34
|
+
const here = fileURLToPath(new URL(".", import.meta.url));
|
|
35
|
+
for (const cand of [
|
|
36
|
+
join(here, "..", "commands", "multi-agent"),
|
|
37
|
+
join(homedir(), ".claude", "commands", "multi-agent"),
|
|
38
|
+
]) {
|
|
39
|
+
if (existsSync(cand)) return cand;
|
|
40
|
+
}
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* The catalog as printed, or null when no command tree exists. The CLI and
|
|
46
|
+
* contract-server.mjs both render this one object.
|
|
47
|
+
*
|
|
48
|
+
* @param {string|null} [dir]
|
|
49
|
+
*/
|
|
50
|
+
export function catalog(dir = null) {
|
|
51
|
+
const root = commandsDir(dir);
|
|
52
|
+
if (!root || !existsSync(root)) return null;
|
|
53
|
+
return { contractVersion: CONTRACT_VERSION, commands: loadCatalog(root) };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function main(argv) {
|
|
57
|
+
let json = false;
|
|
58
|
+
let dir = null;
|
|
59
|
+
for (let i = 0; i < argv.length; i++) {
|
|
60
|
+
const a = argv[i];
|
|
61
|
+
if (a === "--json") json = true;
|
|
62
|
+
else if (a === "--redact") continue;
|
|
63
|
+
else if (a === "--dir") dir = argv[++i];
|
|
64
|
+
else {
|
|
65
|
+
process.stderr.write(`commands: unknown argument ${a}\n`);
|
|
66
|
+
return 2;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const out = catalog(dir);
|
|
70
|
+
if (!out) {
|
|
71
|
+
process.stderr.write("commands: no command tree found\n");
|
|
72
|
+
return 2;
|
|
73
|
+
}
|
|
74
|
+
if (json) process.stdout.write(JSON.stringify(out, null, 2) + "\n");
|
|
75
|
+
else {
|
|
76
|
+
for (const c of out.commands) {
|
|
77
|
+
const mark = c.destructive ? " (destructive)" : "";
|
|
78
|
+
process.stdout.write(`${c.id.padEnd(24)} ${c.gui.padEnd(7)} ${c.argumentHint}${mark}\n`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return 0;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (invokedDirectly(import.meta.url)) {
|
|
85
|
+
runMain("commands", () => {
|
|
86
|
+
process.exitCode = main(process.argv.slice(2));
|
|
87
|
+
});
|
|
88
|
+
}
|
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* constitution.mjs - where a project's constitution lives, what makes one
|
|
4
|
+
* valid, and which repository files it may be derived from.
|
|
5
|
+
*
|
|
6
|
+
* A constitution is the short list of rules every requirement and task of one
|
|
7
|
+
* project is held to: security, accessibility, architecture, licensing. The
|
|
8
|
+
* analysis flow writes it (multi-agent-refs/features/constitution.md) as
|
|
9
|
+
* `constitution.md` for people and `constitution.json` for
|
|
10
|
+
* spec-consistency-gate.mjs, in the project's knowledge store beside
|
|
11
|
+
* code-graph.json: ~/.claude/knowledge/<project>/. `<project>` is the main
|
|
12
|
+
* checkout's directory name, resolved through git's common dir so a linked
|
|
13
|
+
* worktree finds the same file; a run with no repository keys it on the
|
|
14
|
+
* analysis name.
|
|
15
|
+
*
|
|
16
|
+
* Every rule carries one source with the research engine's labels
|
|
17
|
+
* (multi-agent-refs/research/engine.md): `repo` cites a file in the
|
|
18
|
+
* repository, `evidence` a fetched document or tracker item, `inference` a
|
|
19
|
+
* one-line rationale. An inference-sourced rule is proposed and never binding:
|
|
20
|
+
* reasoning can suggest a rule, only a source or a person can make one.
|
|
21
|
+
*
|
|
22
|
+
* Usage:
|
|
23
|
+
* constitution.mjs path [--repo <dir>] [--feature <name>]
|
|
24
|
+
* constitution.mjs check <constitution.json> [--repo <dir>] [--json]
|
|
25
|
+
* constitution.mjs evidence --repo <dir> [--json]
|
|
26
|
+
*
|
|
27
|
+
* Exit: 0 ok / valid · 1 invalid (check) or no path resolvable (path) · 2 usage · 3 unreadable
|
|
28
|
+
*
|
|
29
|
+
* @module pipeline/scripts/constitution
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
import { spawnSync } from "node:child_process";
|
|
33
|
+
import { existsSync, readdirSync, readFileSync, realpathSync, writeFileSync } from "node:fs";
|
|
34
|
+
import { homedir } from "node:os";
|
|
35
|
+
import { basename, dirname, isAbsolute, join } from "node:path";
|
|
36
|
+
|
|
37
|
+
import { invokedDirectly } from "../lib/invoked-directly.mjs";
|
|
38
|
+
import { resolveStack } from "./_stack-adapter.mjs";
|
|
39
|
+
|
|
40
|
+
export const CATEGORY_PREFIX = Object.freeze({
|
|
41
|
+
security: "SEC",
|
|
42
|
+
accessibility: "A11Y",
|
|
43
|
+
architecture: "ARCH",
|
|
44
|
+
licensing: "LIC",
|
|
45
|
+
});
|
|
46
|
+
export const LABELS = ["evidence", "repo", "inference"];
|
|
47
|
+
export const STATUSES = ["binding", "proposed"];
|
|
48
|
+
export const RULE_ID = /^CON-(SEC|A11Y|ARCH|LIC)-\d{2,3}$/;
|
|
49
|
+
export const FILE_NAME = "constitution.json";
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* The knowledge-store key of the repository at `dir`: the main checkout's
|
|
53
|
+
* directory name, the same from every linked worktree. Null outside git.
|
|
54
|
+
*
|
|
55
|
+
* @param {string} dir
|
|
56
|
+
* @returns {string|null}
|
|
57
|
+
*/
|
|
58
|
+
export function projectName(dir) {
|
|
59
|
+
if (!dir || !existsSync(dir)) return null;
|
|
60
|
+
const r = spawnSync(
|
|
61
|
+
"git",
|
|
62
|
+
["-C", dir, "rev-parse", "--path-format=absolute", "--git-common-dir"],
|
|
63
|
+
{
|
|
64
|
+
encoding: "utf8",
|
|
65
|
+
timeout: 20000,
|
|
66
|
+
},
|
|
67
|
+
);
|
|
68
|
+
if (r.status !== 0) return null;
|
|
69
|
+
let common = r.stdout.trim();
|
|
70
|
+
try {
|
|
71
|
+
common = realpathSync(common);
|
|
72
|
+
} catch {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
return basename(common) === ".git"
|
|
76
|
+
? basename(dirname(common))
|
|
77
|
+
: basename(common).replace(/\.git$/, "");
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/** The analysis name as a directory name. */
|
|
81
|
+
export function slug(name) {
|
|
82
|
+
return String(name)
|
|
83
|
+
.toLowerCase()
|
|
84
|
+
.replace(/ı/g, "i")
|
|
85
|
+
.normalize("NFKD")
|
|
86
|
+
.replace(/[̀-ͯ]/g, "")
|
|
87
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
88
|
+
.replace(/^-+|-+$/g, "");
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Where the constitution of a repository, or of a repo-less analysis, lives.
|
|
93
|
+
*
|
|
94
|
+
* @param {{repo?: string|null, feature?: string|null, home?: string}} [opts]
|
|
95
|
+
* @returns {string|null}
|
|
96
|
+
*/
|
|
97
|
+
export function constitutionPath({ repo = null, feature = null, home = homedir() } = {}) {
|
|
98
|
+
const project = (repo && projectName(repo)) || (feature ? slug(feature) : "") || null;
|
|
99
|
+
return project ? join(home, ".claude", "knowledge", project, FILE_NAME) : null;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function parseRef(ref) {
|
|
103
|
+
const m = String(ref).match(/^(.*?)(?::(\d+))?$/);
|
|
104
|
+
return { file: m[1], line: m[2] ? Number(m[2]) : null };
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function checkRepoRef(id, ref, repo, errors) {
|
|
108
|
+
const { file, line } = parseRef(ref);
|
|
109
|
+
if (!file || isAbsolute(file) || file.split("/").includes("..")) {
|
|
110
|
+
errors.push(`${id}: repo ref "${ref}" is not a path inside the repository`);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const full = join(repo, file);
|
|
114
|
+
if (!existsSync(full)) {
|
|
115
|
+
errors.push(`${id}: repo ref "${ref}" names a file the repository does not have`);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (line !== null) {
|
|
119
|
+
let count;
|
|
120
|
+
try {
|
|
121
|
+
count = readFileSync(full, "utf8").split("\n").length;
|
|
122
|
+
} catch {
|
|
123
|
+
errors.push(`${id}: repo ref "${ref}" is not a readable file`);
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
if (line < 1 || line > count)
|
|
127
|
+
errors.push(`${id}: repo ref "${ref}" is past the end of the file`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Structural validity, plus with `repo` that every repo-labelled ref resolves.
|
|
133
|
+
*
|
|
134
|
+
* @param {object} doc
|
|
135
|
+
* @param {{repo?: string|null}} [opts]
|
|
136
|
+
* @returns {{ok: boolean, errors: string[], rules: object[]}}
|
|
137
|
+
*/
|
|
138
|
+
export function checkConstitution(doc, { repo = null } = {}) {
|
|
139
|
+
const errors = [];
|
|
140
|
+
if (!doc || typeof doc !== "object" || Array.isArray(doc)) {
|
|
141
|
+
return { ok: false, errors: ["the constitution is not a JSON object"], rules: [] };
|
|
142
|
+
}
|
|
143
|
+
if (doc.version !== 1) errors.push(`version must be 1, got ${JSON.stringify(doc.version)}`);
|
|
144
|
+
if (!Array.isArray(doc.rules)) {
|
|
145
|
+
errors.push("rules must be an array");
|
|
146
|
+
return { ok: false, errors, rules: [] };
|
|
147
|
+
}
|
|
148
|
+
const seen = new Set();
|
|
149
|
+
doc.rules.forEach((r, i) => {
|
|
150
|
+
const id = typeof r?.id === "string" ? r.id : `rules[${i}]`;
|
|
151
|
+
if (!RULE_ID.test(r?.id ?? "")) {
|
|
152
|
+
errors.push(`${id}: id must match CON-<SEC|A11Y|ARCH|LIC>-NN`);
|
|
153
|
+
} else if (seen.has(r.id)) {
|
|
154
|
+
errors.push(`duplicate rule id ${r.id}`);
|
|
155
|
+
}
|
|
156
|
+
seen.add(r?.id);
|
|
157
|
+
const prefix = CATEGORY_PREFIX[r?.category];
|
|
158
|
+
if (!prefix) {
|
|
159
|
+
errors.push(`${id}: category must be one of ${Object.keys(CATEGORY_PREFIX).join(", ")}`);
|
|
160
|
+
} else if (RULE_ID.test(r.id) && r.id.split("-")[1] !== prefix) {
|
|
161
|
+
errors.push(`${id}: the id prefix does not match category ${r.category} (CON-${prefix}-NN)`);
|
|
162
|
+
}
|
|
163
|
+
if (typeof r?.text !== "string" || !r.text.trim()) errors.push(`${id}: text is empty`);
|
|
164
|
+
const label = r?.source?.label;
|
|
165
|
+
const ref = r?.source?.ref;
|
|
166
|
+
if (!LABELS.includes(label))
|
|
167
|
+
errors.push(`${id}: source.label must be one of ${LABELS.join(", ")}`);
|
|
168
|
+
if (typeof ref !== "string" || !ref.trim()) errors.push(`${id}: source.ref is empty`);
|
|
169
|
+
if (!STATUSES.includes(r?.status)) {
|
|
170
|
+
errors.push(`${id}: status must be one of ${STATUSES.join(", ")}`);
|
|
171
|
+
} else if (label === "inference" && r.status !== "proposed") {
|
|
172
|
+
errors.push(`${id}: an inference-sourced rule is proposed, never ${r.status}`);
|
|
173
|
+
}
|
|
174
|
+
if (label === "repo" && doc.greenfield === true) {
|
|
175
|
+
errors.push(`${id}: a greenfield constitution has no repository to cite`);
|
|
176
|
+
} else if (label === "repo" && repo && typeof ref === "string" && ref.trim()) {
|
|
177
|
+
checkRepoRef(id, ref.trim(), repo, errors);
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
return { ok: errors.length === 0, errors, rules: doc.rules };
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* The constitution a gate should read. An explicit path must exist; the default
|
|
185
|
+
* location may be empty, which is a constitution that does not exist yet.
|
|
186
|
+
*
|
|
187
|
+
* @param {{explicit?: string|null, repo?: string|null, feature?: string|null, home?: string}} opts
|
|
188
|
+
* @returns {{path: string|null, doc: object|null, error: string|null}}
|
|
189
|
+
*/
|
|
190
|
+
export function resolveConstitution({ explicit = null, repo = null, feature = null, home } = {}) {
|
|
191
|
+
const path = explicit || constitutionPath({ repo, feature, home });
|
|
192
|
+
if (!path || (!explicit && !existsSync(path))) return { path: null, doc: null, error: null };
|
|
193
|
+
let doc;
|
|
194
|
+
try {
|
|
195
|
+
doc = JSON.parse(readFileSync(path, "utf8"));
|
|
196
|
+
} catch (err) {
|
|
197
|
+
return { path, doc: null, error: `constitution ${path} is unreadable: ${err.message}` };
|
|
198
|
+
}
|
|
199
|
+
const { errors } = checkConstitution(doc);
|
|
200
|
+
if (errors.length) {
|
|
201
|
+
return { path, doc: null, error: `constitution ${path} is invalid: ${errors.join("; ")}` };
|
|
202
|
+
}
|
|
203
|
+
return { path, doc, error: null };
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const LICENSES = [
|
|
207
|
+
[/GNU AFFERO GENERAL PUBLIC LICENSE/i, "AGPL-3.0"],
|
|
208
|
+
[/GNU LESSER GENERAL PUBLIC LICENSE/i, "LGPL"],
|
|
209
|
+
[/GNU GENERAL PUBLIC LICENSE[\s\S]*Version 3/i, "GPL-3.0"],
|
|
210
|
+
[/GNU GENERAL PUBLIC LICENSE[\s\S]*Version 2/i, "GPL-2.0"],
|
|
211
|
+
[/Apache License[\s\S]*Version 2\.0/i, "Apache-2.0"],
|
|
212
|
+
[/Mozilla Public License[\s\S]*2\.0/i, "MPL-2.0"],
|
|
213
|
+
[/^\s*MIT License/i, "MIT"],
|
|
214
|
+
[/^\s*ISC License/i, "ISC"],
|
|
215
|
+
[/BSD \d-Clause|Redistribution and use in source and binary forms/i, "BSD"],
|
|
216
|
+
[/This is free and unencumbered software released into the public domain/i, "Unlicense"],
|
|
217
|
+
];
|
|
218
|
+
const LICENSE_FILES = ["LICENSE", "LICENSE.md", "LICENSE.txt", "COPYING"];
|
|
219
|
+
const INSTRUCTION_FILES = [
|
|
220
|
+
"CLAUDE.md",
|
|
221
|
+
"AGENTS.md",
|
|
222
|
+
".github/copilot-instructions.md",
|
|
223
|
+
"SECURITY.md",
|
|
224
|
+
];
|
|
225
|
+
const LINT_FILES = [
|
|
226
|
+
".swiftlint.yml",
|
|
227
|
+
".swiftformat",
|
|
228
|
+
".eslintrc",
|
|
229
|
+
".eslintrc.json",
|
|
230
|
+
".eslintrc.js",
|
|
231
|
+
".eslintrc.cjs",
|
|
232
|
+
".eslintrc.yml",
|
|
233
|
+
"eslint.config.js",
|
|
234
|
+
"eslint.config.mjs",
|
|
235
|
+
"eslint.config.cjs",
|
|
236
|
+
"eslint.config.ts",
|
|
237
|
+
"biome.json",
|
|
238
|
+
".stylelintrc.json",
|
|
239
|
+
"detekt.yml",
|
|
240
|
+
"config/detekt/detekt.yml",
|
|
241
|
+
".editorconfig",
|
|
242
|
+
"ruff.toml",
|
|
243
|
+
".ruff.toml",
|
|
244
|
+
".flake8",
|
|
245
|
+
".golangci.yml",
|
|
246
|
+
".golangci.yaml",
|
|
247
|
+
"clippy.toml",
|
|
248
|
+
".rubocop.yml",
|
|
249
|
+
];
|
|
250
|
+
|
|
251
|
+
function licenseOf(text) {
|
|
252
|
+
const head = text.slice(0, 4000);
|
|
253
|
+
return LICENSES.find(([re]) => re.test(head))?.[1] ?? null;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* The repository files a rule labelled `repo` may cite, found by name at fixed
|
|
258
|
+
* places, never by a tree walk: license, agent instructions, lint and format
|
|
259
|
+
* configs, and the stack manifest the adapter table resolved.
|
|
260
|
+
*
|
|
261
|
+
* @param {string} dir
|
|
262
|
+
* @returns {{kind: "license"|"instructions"|"lint"|"stack", file: string, detail: string|null}[]}
|
|
263
|
+
*/
|
|
264
|
+
export function repoEvidence(dir) {
|
|
265
|
+
const out = [];
|
|
266
|
+
for (const f of LICENSE_FILES) {
|
|
267
|
+
const p = join(dir, f);
|
|
268
|
+
if (!existsSync(p)) continue;
|
|
269
|
+
let detail = null;
|
|
270
|
+
try {
|
|
271
|
+
detail = licenseOf(readFileSync(p, "utf8"));
|
|
272
|
+
} catch {
|
|
273
|
+
/* listed without a detail */
|
|
274
|
+
}
|
|
275
|
+
out.push({ kind: "license", file: f, detail });
|
|
276
|
+
}
|
|
277
|
+
for (const f of INSTRUCTION_FILES) {
|
|
278
|
+
if (existsSync(join(dir, f))) out.push({ kind: "instructions", file: f, detail: null });
|
|
279
|
+
}
|
|
280
|
+
const rulesDir = join(dir, ".claude", "rules");
|
|
281
|
+
if (existsSync(rulesDir)) {
|
|
282
|
+
for (const f of readdirSync(rulesDir)
|
|
283
|
+
.filter((n) => n.endsWith(".md"))
|
|
284
|
+
.sort()) {
|
|
285
|
+
out.push({ kind: "instructions", file: `.claude/rules/${f}`, detail: null });
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
for (const f of LINT_FILES) {
|
|
289
|
+
if (existsSync(join(dir, f))) out.push({ kind: "lint", file: f, detail: null });
|
|
290
|
+
}
|
|
291
|
+
const stack = resolveStack(dir);
|
|
292
|
+
for (const a of stack.adapters) {
|
|
293
|
+
const why = stack.coarse.why.match(new RegExp(`(?:^|\\s)${a.id}<-(\\S+)`));
|
|
294
|
+
const plus = a.evidence.split(" + ").find((e) => !e.startsWith("stack-detect:"));
|
|
295
|
+
out.push({ kind: "stack", file: plus || why?.[1] || "", detail: a.id });
|
|
296
|
+
}
|
|
297
|
+
return out;
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
function main(argv) {
|
|
301
|
+
const mode = argv[0];
|
|
302
|
+
const flag = (name) => {
|
|
303
|
+
const i = argv.indexOf(name);
|
|
304
|
+
return i === -1 ? undefined : argv[i + 1];
|
|
305
|
+
};
|
|
306
|
+
const json = argv.includes("--json");
|
|
307
|
+
if (mode === "path") {
|
|
308
|
+
const p = constitutionPath({
|
|
309
|
+
repo: flag("--repo") ?? null,
|
|
310
|
+
feature: flag("--feature") ?? null,
|
|
311
|
+
});
|
|
312
|
+
if (!p) {
|
|
313
|
+
process.stderr.write("constitution: no repository and no --feature, so there is no path\n");
|
|
314
|
+
return 1;
|
|
315
|
+
}
|
|
316
|
+
writeFileSync(1, `${p}\n`);
|
|
317
|
+
return 0;
|
|
318
|
+
}
|
|
319
|
+
if (mode === "check") {
|
|
320
|
+
const file = argv[1];
|
|
321
|
+
if (!file || file.startsWith("--")) {
|
|
322
|
+
process.stderr.write("usage: constitution.mjs check <constitution.json> [--repo <dir>]\n");
|
|
323
|
+
return 2;
|
|
324
|
+
}
|
|
325
|
+
let doc;
|
|
326
|
+
try {
|
|
327
|
+
doc = JSON.parse(readFileSync(file, "utf8"));
|
|
328
|
+
} catch (err) {
|
|
329
|
+
process.stderr.write(`constitution: cannot read ${file}: ${err.message}\n`);
|
|
330
|
+
return 3;
|
|
331
|
+
}
|
|
332
|
+
const r = checkConstitution(doc, { repo: flag("--repo") ?? null });
|
|
333
|
+
if (json) writeFileSync(1, `${JSON.stringify({ ok: r.ok, errors: r.errors }, null, 2)}\n`);
|
|
334
|
+
else if (r.ok) writeFileSync(1, `constitution: ${r.rules.length} rule(s), valid\n`);
|
|
335
|
+
else writeFileSync(2, `${r.errors.map((e) => `constitution: ${e}`).join("\n")}\n`);
|
|
336
|
+
return r.ok ? 0 : 1;
|
|
337
|
+
}
|
|
338
|
+
if (mode === "evidence") {
|
|
339
|
+
const dir = flag("--repo");
|
|
340
|
+
if (!dir) {
|
|
341
|
+
process.stderr.write("usage: constitution.mjs evidence --repo <dir> [--json]\n");
|
|
342
|
+
return 2;
|
|
343
|
+
}
|
|
344
|
+
const ev = repoEvidence(dir);
|
|
345
|
+
if (json) writeFileSync(1, `${JSON.stringify(ev, null, 2)}\n`);
|
|
346
|
+
else {
|
|
347
|
+
writeFileSync(
|
|
348
|
+
1,
|
|
349
|
+
`${ev.map((e) => `${e.kind.padEnd(12)} ${e.file}${e.detail ? ` (${e.detail})` : ""}`).join("\n")}\n`,
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
return 0;
|
|
353
|
+
}
|
|
354
|
+
process.stderr.write(
|
|
355
|
+
"usage: constitution.mjs path|check|evidence [--repo <dir>] [--feature <name>] [--json]\n",
|
|
356
|
+
);
|
|
357
|
+
return 2;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
if (invokedDirectly(import.meta.url)) {
|
|
361
|
+
process.exitCode = main(process.argv.slice(2));
|
|
362
|
+
}
|