@ionivetech/mugiwara 0.3.0 → 0.5.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.
Files changed (119) hide show
  1. package/.opencode/commands/mugiwara-plan.md +4 -0
  2. package/README.md +214 -418
  3. package/content/agents/brook-healing.md +2 -2
  4. package/content/agents/chopper-checkpoint.md +2 -1
  5. package/content/agents/eval-runner.md +4 -4
  6. package/content/agents/franky-gates.md +1 -1
  7. package/content/agents/jinbe-security.md +2 -1
  8. package/content/agents/luffy-orchestrator.md +3 -3
  9. package/content/agents/memory-keeper.md +1 -1
  10. package/content/agents/nami-planner.md +2 -2
  11. package/content/agents/resume-coordinator.md +8 -9
  12. package/content/agents/robin-reviewer.md +3 -2
  13. package/content/agents/sanji-quality.md +1 -1
  14. package/content/agents/skeptic-verifier.md +4 -3
  15. package/content/agents/using-mugiwara.md +3 -3
  16. package/content/agents/usopp-brainstorm.md +3 -3
  17. package/content/agents/zoro-execution.md +4 -3
  18. package/content/skills/mugiwara-agent-security/SKILL.md +19 -2
  19. package/content/skills/mugiwara-backend/SKILL.md +7 -8
  20. package/content/skills/mugiwara-backend/references/source-backed-example.md +77 -0
  21. package/content/skills/mugiwara-brainstorm/SKILL.md +7 -2
  22. package/content/skills/mugiwara-checkpoint/SKILL.md +7 -2
  23. package/content/skills/mugiwara-checkpoint/references/ledger-format.md +34 -0
  24. package/content/skills/{mugiwara-doubt-driven-development → mugiwara-claim-audit}/SKILL.md +7 -2
  25. package/content/skills/{mugiwara-context-engineering → mugiwara-context-budget}/SKILL.md +7 -2
  26. package/content/skills/mugiwara-context-budget/references/context-budget.md +37 -0
  27. package/content/skills/{mugiwara-api-and-interface-design → mugiwara-contract-first}/SKILL.md +9 -2
  28. package/content/skills/mugiwara-contract-first/references/versioning-playbook.md +36 -0
  29. package/content/skills/mugiwara-execution/SKILL.md +9 -2
  30. package/content/skills/mugiwara-execution/references/worked-example.md +88 -0
  31. package/content/skills/mugiwara-frontend/SKILL.md +21 -22
  32. package/content/skills/mugiwara-frontend/references/design-tokens.md +25 -0
  33. package/content/skills/mugiwara-frontend/references/slop-catalog.md +19 -0
  34. package/content/skills/mugiwara-gates/SKILL.md +9 -4
  35. package/content/skills/mugiwara-git/SKILL.md +6 -1
  36. package/content/skills/mugiwara-healing/SKILL.md +39 -7
  37. package/content/skills/mugiwara-healing/references/failure-taxonomy.md +23 -0
  38. package/content/skills/mugiwara-lessons/SKILL.md +6 -1
  39. package/content/skills/mugiwara-orchestration/SKILL.md +18 -5
  40. package/content/skills/mugiwara-planning/SKILL.md +16 -15
  41. package/content/skills/mugiwara-planning/references/anti-patterns.md +17 -0
  42. package/content/skills/mugiwara-planning/references/plan-template.md +46 -0
  43. package/content/skills/mugiwara-pr/SKILL.md +6 -1
  44. package/content/skills/{mugiwara-test-driven-development → mugiwara-proof-order}/SKILL.md +7 -2
  45. package/content/skills/mugiwara-proof-order/references/proof-order-examples.md +62 -0
  46. package/content/skills/mugiwara-quality/SKILL.md +8 -3
  47. package/content/skills/mugiwara-resume/SKILL.md +46 -30
  48. package/content/skills/mugiwara-review/SKILL.md +6 -1
  49. package/content/skills/mugiwara-review/references/five-axis-worksheet.md +36 -0
  50. package/content/skills/mugiwara-review/references/severity-rubric.md +20 -0
  51. package/content/skills/{mugiwara-systematic-debugging → mugiwara-root-cause}/SKILL.md +9 -2
  52. package/content/skills/mugiwara-root-cause/references/four-phase-worked.md +71 -0
  53. package/content/skills/mugiwara-security/SKILL.md +18 -18
  54. package/content/skills/mugiwara-security/references/owasp-mapping.md +30 -0
  55. package/content/skills/mugiwara-security/references/stride-worksheet.md +37 -0
  56. package/content/skills/mugiwara-ship/SKILL.md +6 -1
  57. package/content/skills/{mugiwara-deprecation → mugiwara-sunset}/SKILL.md +7 -2
  58. package/content/skills/mugiwara-testcases/SKILL.md +6 -1
  59. package/content/skills/mugiwara-testcases/references/intake-formats.md +42 -0
  60. package/content/skills/mugiwara-workflow/SKILL.md +26 -24
  61. package/dist/mugiwara.js +165 -28
  62. package/docs/adoption-guide.md +2 -2
  63. package/docs/agents.md +2 -2
  64. package/docs/audit-trail.md +65 -0
  65. package/docs/comparison.md +58 -63
  66. package/docs/compliance-matrix.md +81 -0
  67. package/docs/config.md +7 -2
  68. package/docs/cost.md +45 -0
  69. package/docs/developer-onboarding.md +17 -13
  70. package/docs/enforcement.md +35 -0
  71. package/docs/getting-started.md +103 -41
  72. package/docs/harness-matrix.md +41 -0
  73. package/docs/index.md +11 -5
  74. package/docs/lanes.md +82 -0
  75. package/docs/skill-anatomy.md +42 -49
  76. package/docs/skills.md +36 -54
  77. package/docs/troubleshooting.md +91 -0
  78. package/docs/workflow.md +15 -6
  79. package/evals/cases/adversarial-pressure-fake-pass.json +12 -0
  80. package/evals/cases/adversarial-pressure-skip-review.json +13 -0
  81. package/evals/cases/lane-exploratory-vague.json +12 -0
  82. package/evals/cases/lane-sensitivity-payment.json +12 -0
  83. package/evals/cases/negative-secrets-typo.json +12 -0
  84. package/evals/cases/negative-security-docs-change.json +12 -0
  85. package/evals/cases/positive-refactor-existing-tests.json +11 -0
  86. package/evals/cases/positive-resume-mid-mission.json +11 -0
  87. package/evals/cases/routing-auth-feature.json +13 -0
  88. package/evals/cases/routing-bug-one-file.json +13 -0
  89. package/evals/cases/routing-typo.json +13 -0
  90. package/package.json +6 -4
  91. package/references/definition-of-done.md +42 -0
  92. package/references/multi-actor.md +44 -0
  93. package/references/skill-versioning.md +44 -0
  94. package/references/source-grounding.md +23 -0
  95. package/references/token-budget.md +34 -0
  96. package/scripts/evidence.sh +37 -0
  97. package/scripts/lane.sh +74 -0
  98. package/scripts/mission-report.sh +88 -0
  99. package/scripts/release-notes.ts +65 -0
  100. package/scripts/retrieval-eval.ts +152 -0
  101. package/scripts/run-evals.ts +113 -0
  102. package/scripts/savepoint.sh +165 -0
  103. package/scripts/sync-version.ts +30 -0
  104. package/scripts/validate-content.ts +226 -0
  105. package/src/args.ts +2 -1
  106. package/src/cli.ts +21 -20
  107. package/src/installer.ts +31 -3
  108. package/src/mission.ts +48 -0
  109. package/src/targets/claude.ts +4 -0
  110. package/src/targets/copilot.ts +4 -0
  111. package/src/targets/generic.ts +33 -1
  112. package/src/targets/kilo.ts +1 -0
  113. package/src/targets/opencode.ts +4 -0
  114. package/content/skills/mugiwara-dynamic-workflow/SKILL.md +0 -85
  115. package/content/skills/mugiwara-eval/SKILL.md +0 -82
  116. package/content/skills/mugiwara-git-worktrees/SKILL.md +0 -62
  117. package/content/skills/mugiwara-mode/SKILL.md +0 -72
  118. package/content/skills/mugiwara-observability/SKILL.md +0 -54
  119. package/content/skills/mugiwara-writing-skills/SKILL.md +0 -60
@@ -1,10 +1,15 @@
1
1
  ---
2
- name: mugiwara-deprecation
3
- description: Use when retiring code, APIs, or features that no longer justify their upkeep, or when steering users off one implementation onto another. Sunset criteria, safe DB migrations, phased cutovers, orphaned code. Every removal needs a plan and a tested way back.
2
+ name: mugiwara-sunset
3
+ description: Use when retiring code or APIs keep-or-retire gate, safe DB migrations, phased cutovers. Every removal needs a plan and tested way back.
4
4
  ---
5
5
 
6
6
  # Deprecation & Migration (Brook)
7
7
 
8
+ ## Skip when
9
+
10
+ - No code, API, or feature is being retired or replaced.
11
+ - Purely additive change — nothing removed, no migration path needed.
12
+
8
13
  Keeping old code alive is a tax, not a virtue: it keeps costing tests, patches, security reviews, and the attention of everyone who walks past it. Retirement is a craft — the removal itself must be as disciplined as the build.
9
14
 
10
15
  ## Sunset or keep
@@ -1,10 +1,15 @@
1
1
  ---
2
2
  name: mugiwara-testcases
3
- description: Use when a mission declares user-provided test cases or acceptance criteria - intake formats, immutable-gold rule, declarative-AC routing, consent, and failure adjudication. Single home for the ATDD contract; referenced by the quality and gates agents.
3
+ description: Use when mission declares user test cases intake formats, immutable-gold rule, declarative-AC routing, consent, failure adjudication. ATDD home.
4
4
  ---
5
5
 
6
6
  # Test Cases (ATDD Contract)
7
7
 
8
+ ## Skip when
9
+
10
+ - No user-declared test cases or acceptance criteria in this mission.
11
+ - No repo test source declared and no acceptance oracle needed.
12
+
8
13
  User tests are the crew's acceptance oracle. This is the single home for the ATDD contract — intake, immutable gold, routing, consent, and failure adjudication. Shared by planning, execution, quality, and gates so they cannot drift.
9
14
 
10
15
  ## Accepted formats
@@ -0,0 +1,42 @@
1
+ # Test Intake Formats
2
+
3
+ Single home for the ATDD contract. Referenced by `mugiwara-quality` and `mugiwara-gates`.
4
+
5
+ ## Format 1: Executable tests (user test files)
6
+
7
+ ```
8
+ Path: tests/acceptance/invitation-flow.test.ts
9
+ Type: integration
10
+ Commands: npm run test:acceptance -- invitation-flow
11
+ ```
12
+
13
+ Imported as immutable gold. Never edit, never skip. Run failing first, green at end.
14
+
15
+ ## Format 2: Declarative acceptance (Gherkin/markdown AC)
16
+
17
+ ```gherkin
18
+ Feature: Invitation flow
19
+ Scenario: User accepts invitation
20
+ Given an invitation exists for "user@example.com"
21
+ When the user clicks the invitation link
22
+ Then the user is redirected to onboarding
23
+ And the invitation status changes to "accepted"
24
+ ```
25
+
26
+ The crew translates this to a project test file. Write the test, watch it fail, implement, re-run green.
27
+
28
+ ## Format 3: Command-verifiable
29
+
30
+ ```
31
+ Acceptance: curl -X POST /api/invite -d '{"email":"test@ex.com"}' | jq .status
32
+ Expected: "sent"
33
+ ```
34
+
35
+ Run directly. No translation needed.
36
+
37
+ ## Rules
38
+
39
+ - No declared test source → no user tests for the mission.
40
+ - Executable user tests = immutable gold. Change requires user consent + ledger row.
41
+ - Declarative AC tests are model-written → extra Chopper scrutiny (can encode the bug).
42
+ - Cross-cutting user ACs (e2e flow spanning tasks) → plan-level criteria, re-run at checkpoint against whole diff.
@@ -1,10 +1,15 @@
1
1
  ---
2
2
  name: mugiwara-workflow
3
- description: Use at the start of any non-trivial mission to run the Mugiwara crew harness - Luffy triage gateway first, then brainstorm, planning, execution, checkpoint, quality, gates, review, healing, and closure waves.
3
+ description: Use at start of any non-trivial mission Luffy triage gateway, then brainstorm/plan/execute/checkpoint/quality/gates/review/heal/closure waves.
4
4
  ---
5
5
 
6
6
  # Mugiwara Workflow
7
7
 
8
+ ## Skip when
9
+
10
+ - Lane 0 direct work: typo, rename, or single-file fix under 20 LOC.
11
+ - User explicitly declined the harness for this request.
12
+
8
13
  The Straw Hat harness: Wave 0 triage + Waves 1-9, with an optional adversarial pass at Wave 4.5. Waves are phases of the mission, not files — Nami writes them into the plan doc, Zoro executes them. The main thread runs the harness and embodies each crew role inline (Execution model below); the harness always starts through Luffy unless the user summons a crew member directly.
9
14
 
10
15
  ## Execution model (every harness)
@@ -31,9 +36,11 @@ Every mission creates and works inside `.mugiwara/` at the repo root:
31
36
  ```
32
37
  .mugiwara/
33
38
  ├── config # runtime mode config: mode/branch/commit/pr key=value (gitignored; project overrides global)
39
+ ├── state.json # computed mission state at every wave boundary (scripts/savepoint.sh)
34
40
  ├── spec/ # brainstorm output: YYYY-MM-DD-<mission>.md
35
- ├── plans/ # plan doc: YYYY-MM-DD-<mission>.md — CLEAN, Nami-only, source of truth from Wave 2. No agent names, no log, no closure.
41
+ ├── plans/ # plan doc: YYYY-MM-DD-<mission>.md — CLEAN, Nami-only, source of truth from Wave 2
36
42
  ├── results/ # wave results: audit/quality/gate reports, todos, closure report
43
+ ├── reports/ # human-readable mission reports: YYYY-MM-DD-<mission>.md
37
44
  ├── review/ # review + security findings
38
45
  ├── issues/ # blocker log: YYYY-MM-DD-<mission>-blockers.md
39
46
  └── logs/ # Luffy's decision + check-in log: YYYY-MM-DD-<mission>.md (deleted at cleanup)
@@ -51,9 +58,9 @@ At session start, after context loss, or on any "where were we?" — embody `res
51
58
 
52
59
  ## Wave 0 — Luffy Triage (always first)
53
60
 
54
- Front door: embody `using-mugiwara` inline (the router) — it routes to the right crew member and records the route. For a full triage embody `luffy-orchestrator` inline. NEVER start directly with brainstorming or planning. Luffy classifies every request 5 ways (Trivial / Explicit / Exploratory / Open-ended / Ambiguous) and routes: Trivial and Explicit → Wave 2 directly; Exploratory, Open-ended, and Ambiguous → Wave 1 brainstorm first. The user may summon any crew member directly — Luffy still records the route.
61
+ Front door: embody `using-mugiwara` inline (the router) — it routes to the right crew member and records the route. For a full triage embody `luffy-orchestrator` inline. NEVER start directly with brainstorming or planning. Luffy classifies every request 5 ways (Trivial / Explicit / Exploratory / Open-ended / Ambiguous) and routes: Trivial and Explicit → Wave 2 directly; Exploratory, Open-ended, and Ambiguous → Wave 1 brainstorm first. Alongside the class, Luffy sizes the mission and picks a lane (0 Direct / 1 Lean / 2 Standard / 3 Full / 4 Spike) — small work skips the pipeline, sensitive work never sneaks through the lean path. The user may summon any crew member directly — Luffy still records the route.
55
62
 
56
- Alongside triage, read the mode config per `mugiwara-mode`: `.mugiwara/config` (project) then `~/.mugiwara/config` (global); a key missing from both = `guided`. Lazy-create the project config on first WRITE only, never auto-create on read.
63
+ Alongside triage, read the mode config per mode config: `.mugiwara/config` (project) then `~/.mugiwara/config` (global); a key missing from both = `guided`. Lazy-create the project config on first WRITE only, never auto-create on read.
57
64
 
58
65
  ## Waves
59
66
 
@@ -64,7 +71,7 @@ Alongside triage, read the mode config per `mugiwara-mode`: `.mugiwara/config` (
64
71
  | 2 Planning | Nami | mugiwara-planning | plan doc: waves/tasks/criteria, parallel markers |
65
72
  | 3 Execution | Zoro | mugiwara-execution | implemented tasks with evidence |
66
73
  | 4 Checkpoint | Chopper | mugiwara-checkpoint | audit report + failure ledger |
67
- | 4.5 Adversarial | Skeptic | mugiwara-dynamic-workflow | findings report + failure ledger |
74
+ | 4.5 Adversarial | Skeptic | mugiwara-claim-audit | findings report + failure ledger |
68
75
  | 5 Quality | Sanji | mugiwara-quality | formatter/linter/test results |
69
76
  | 6 Gates | Franky | mugiwara-gates | coverage + build verdict |
70
77
  | 7 Review | Robin ∥ Jinbe | mugiwara-review + mugiwara-security | severity-tagged findings |
@@ -83,7 +90,7 @@ Never silently work around a blocker. Brook reads this ledger at Wave 8 to decid
83
90
 
84
91
  ## Cleanup
85
92
 
86
- At closure (Wave 9), after the terminal step, run the cleanup procedure in `mugiwara-ship`: delete consumed intermediates — superseded results, review, issues reports, the per-mission decision log in `logs/`, and the consumed spec. Keep the plan doc, the closure report, the PR verdict, `config`, and cross-mission state (`logs/lessons.md`, `backup/`, `manifest.json`). List candidates before deleting.
93
+ At closure (Wave 9), after the terminal step, run cleanup per `mugiwara-ship`: delete consumed intermediates — superseded results, review, issues, the decision log in `logs/`, and consumed spec. Keep the plan doc, closure report, PR verdict, mission report, `config`, `state.json`, and cross-mission state (`logs/lessons.md`, `backup/`, `manifest.json`). List candidates before deleting.
87
94
 
88
95
  ## Rules
89
96
 
@@ -91,29 +98,24 @@ At closure (Wave 9), after the terminal step, run the cleanup procedure in `mugi
91
98
  2. No wave skipped without the reason recorded in the decision log (`.mugiwara/logs/`) — name the wave, owner, and reason at the moment of omission.
92
99
  3. Heal loop is bounded: Wave 8 → Wave 4, max 3 cycles. After that, escalate to the human with full history.
93
100
  4. Any agent may consult Luffy mid-flight (embody `luffy-orchestrator` inline) for decisions and escalations.
94
- 5. Wave 7 runs Robin and Jinbe review passes in parallel — both are inline passes over the same diff, or parallel review subagents for large diffs.
95
- 6. The plan doc (`.mugiwara/plans/YYYY-MM-DD-<mission>.md`) is the single source of truth from Wave 2 onward.
96
- 7. Frontend-touching tasks in Wave 3 must apply `mugiwara-frontend` in the same pass.
97
- 8. One crew member may hold many skills (e.g. Usopp holds `mugiwara-brainstorm` + `mugiwara-frontend`; the crew is 15 members); load the member's skills, embody the role inline.
98
- 9. On session start, context loss, or "where were we?" resume before any wave via `resume-coordinator` (mugiwara-resume); never start over.
99
- 10. The crew never merges and never deploys — push the branch + hand the verdict file to the user, who opens the PR; PR review is the terminal gate in every mode.
101
+ 5. Wave 7 runs Robin and Jinbe in parallel over the same diff.
102
+ 6. The plan doc is the single source of truth from Wave 2 onward.
103
+ 7. Frontend tasks in Wave 3 must apply `mugiwara-frontend`.
104
+ 8. On session start or context loss resume via `resume-coordinator` before any wave; never start over.
105
+ 9. Push branch + hand verdict file to the user, who opens the PR; crew never merges, never deploys.
100
106
 
101
107
  ## Iron Law
102
108
 
103
- EVIDENCE OVER CLAIMS. No wave passes on assertion — the owning agent runs the checks and shows output. A wave that cannot produce evidence is a failed wave.
104
-
105
- ## Verification gate (every completion claim)
106
-
107
- A claim is only as strong as the evidence produced in the same turn that made it. "Done", "passes", and "fixed" each name a command that would prove them — run that command, read its full output, then speak. A result from an earlier run, a guess, or a worker's word for it is not proof; re-run it and diff the work against the tree before reporting. Trust is not a substitute for verification.
109
+ EVIDENCE OVER CLAIMS. No wave passes on assertion — the owning agent runs the checks and shows output. "Done", "passes", and "fixed" must be proved by running the check command in the same turn; no stale results, no guesses, no worker's word for it.
108
110
 
109
111
  ## Red flags
110
112
 
111
- - A wave "passes" on a spoken claim with no command output or file to point at.
113
+ - A wave passes on a spoken claim with no command output.
112
114
  - Heal loop beyond 3 cycles with the same failure still open.
113
- - A wave skipped with no reason recorded in the decision log.
114
- - Execution starts before triage (Wave 0), or planning before brainstorm when triage routed to Wave 1.
115
- - Mission artifacts landing outside `.mugiwara/`.
116
- - Wave order drifts from the table (e.g. quality before checkpoint).
117
- - A blocker worked around silently with no ledger row.
115
+ - Wave skipped with no reason recorded in the decision log.
116
+ - Execution before triage (Wave 0).
117
+ - Mission artifacts outside `.mugiwara/`.
118
+ - Wave order drifts (e.g. quality before checkpoint).
119
+ - Blocker worked around silently with no ledger row.
118
120
 
119
- All mean: stop the pipeline, diagnose with Chopper's ledger, decide continue / retry / escalate.
121
+ All mean: stop, diagnose with Chopper's ledger, decide continue/retry/escalate.
package/dist/mugiwara.js CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/cli.ts
4
- import { existsSync as existsSync5, readFileSync as readFileSync4, readdirSync as readdirSync2, realpathSync, rmSync as rmSync2 } from "node:fs";
4
+ import { existsSync as existsSync6, realpathSync, rmSync as rmSync3 } from "node:fs";
5
5
  import { homedir as homedir2 } from "node:os";
6
- import { join as join7, resolve } from "node:path";
6
+ import { resolve } from "node:path";
7
7
  import { pathToFileURL } from "node:url";
8
8
 
9
9
  // src/args.ts
@@ -14,6 +14,7 @@ var BOOL_FLAGS = {
14
14
  "-y": "yes",
15
15
  "--force": "force",
16
16
  "--dry-run": "dryRun",
17
+ "--keep-logs": "keepLogs",
17
18
  "--help": "help",
18
19
  "-h": "help",
19
20
  "--version": "version",
@@ -131,6 +132,10 @@ var target = {
131
132
  fm.tools = data.tools;
132
133
  return { relPath: `${data.name}.md`, text: stringifyFrontmatter(fm, body) };
133
134
  },
135
+ refsDir({ scope, projectDir, home }, skillName) {
136
+ const root = scope === "global" ? join(home, ".claude") : join(projectDir, ".claude");
137
+ return join(root, "skills", skillName, "references");
138
+ },
134
139
  postInstall({ scope, projectDir, home, dryRun }) {
135
140
  const root = scope === "global" ? join(home, ".claude") : join(projectDir, ".claude");
136
141
  const hookFile = join(root, "hooks", "session-start.ts");
@@ -166,6 +171,10 @@ var target2 = {
166
171
  if (data.tools)
167
172
  fm.tools = data.tools;
168
173
  return { relPath: `${data.name}.md`, text: stringifyFrontmatter(fm, body) };
174
+ },
175
+ refsDir({ scope, projectDir, home }, skillName) {
176
+ const root = scope === "global" ? join2(home, ".config", "opencode") : join2(projectDir, ".opencode");
177
+ return join2(root, "skills", skillName, "references");
169
178
  }
170
179
  };
171
180
 
@@ -190,6 +199,9 @@ var target3 = {
190
199
  relPath: `${data.name}.md`,
191
200
  text: stringifyFrontmatter({ name: data.name, description: data.description }, body)
192
201
  };
202
+ },
203
+ refsDir(_opts, skillName) {
204
+ return join3(_opts.projectDir, ".mugiwara", "refs", skillName);
193
205
  }
194
206
  };
195
207
 
@@ -197,11 +209,13 @@ var target3 = {
197
209
  import { existsSync as existsSync2, writeFileSync } from "node:fs";
198
210
  import { join as join4 } from "node:path";
199
211
  function makeGeneric(opts) {
200
- const { id, label, rulesDir, bootstrapFile, bootstrapPointer } = opts;
212
+ const { id, label, rulesDir, bootstrapFile, bootstrapPointer, tier = bootstrapPointer ? 2 : 3 } = opts;
213
+ const stubOnly = tier === 3;
201
214
  return {
202
215
  id,
203
216
  label,
204
217
  native: false,
218
+ tier,
205
219
  paths({ scope, projectDir }) {
206
220
  if (scope === "global")
207
221
  throw new Error(`${label} supports project scope only`);
@@ -209,6 +223,27 @@ function makeGeneric(opts) {
209
223
  return { skillsDir: dir, agentsDir: dir };
210
224
  },
211
225
  transformSkill(data, body) {
226
+ if (stubOnly) {
227
+ return {
228
+ relPath: `${data.name}.md`,
229
+ text: `# ${data.name}
230
+
231
+ > ${data.description}
232
+
233
+ ## Skip when
234
+
235
+ Full skill: \`${data.name}\` — read \`.mugiwara/refs/${data.name}.md\` when the crew invokes this role.`
236
+ };
237
+ }
238
+ return { relPath: `${data.name}.md`, text: `# ${data.name}
239
+
240
+ > ${data.description}
241
+
242
+ ${body}` };
243
+ },
244
+ transformSkillFull(data, body) {
245
+ if (!stubOnly)
246
+ return null;
212
247
  return { relPath: `${data.name}.md`, text: `# ${data.name}
213
248
 
214
249
  > ${data.description}
@@ -216,6 +251,16 @@ function makeGeneric(opts) {
216
251
  ${body}` };
217
252
  },
218
253
  transformAgent(data, body) {
254
+ if (stubOnly) {
255
+ return {
256
+ relPath: `agent-${data.name}.md`,
257
+ text: `# Agent: ${data.name}
258
+
259
+ > ${data.description}
260
+
261
+ Skills: ${data.skills ?? ""}. Read \`.mugiwara/refs/${data.name}.md\` when embodying this role.`
262
+ };
263
+ }
219
264
  return { relPath: `agent-${data.name}.md`, text: `# Agent: ${data.name}
220
265
 
221
266
  > ${data.description}
@@ -224,6 +269,20 @@ Skills used: ${data.skills ?? ""}
224
269
 
225
270
  ${body}` };
226
271
  },
272
+ transformAgentFull(data, body) {
273
+ if (!stubOnly)
274
+ return null;
275
+ return { relPath: `${data.name}.md`, text: `# Agent: ${data.name}
276
+
277
+ > ${data.description}
278
+
279
+ Skills used: ${data.skills ?? ""}
280
+
281
+ ${body}` };
282
+ },
283
+ refsDir({ projectDir }) {
284
+ return join4(projectDir, ".mugiwara", "refs");
285
+ },
227
286
  postInstall({ projectDir, dryRun }) {
228
287
  if (!bootstrapFile)
229
288
  return { written: [], notes: [] };
@@ -289,7 +348,8 @@ var target8 = makeGeneric({
289
348
  "instructions": [
290
349
  ".kilo/rules/*.md"
291
350
  ]
292
- }`
351
+ }`,
352
+ tier: 3
293
353
  });
294
354
 
295
355
  // src/targets/antigravity.ts
@@ -316,14 +376,20 @@ function collectContent() {
316
376
  const skillNames = readdirSync(join5(CONTENT_DIR, "skills"), { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
317
377
  const skills = skillNames.map((name) => {
318
378
  const { data, body } = parseFrontmatter(readFileSync2(join5(CONTENT_DIR, "skills", name, "SKILL.md"), "utf8"));
319
- return { name, data, body };
379
+ return { name, data, body, refs: collectRefs(join5(CONTENT_DIR, "skills", name)) };
320
380
  });
321
381
  const agents = readdirSync(join5(CONTENT_DIR, "agents")).filter((f) => f.endsWith(".md")).map((f) => {
322
382
  const { data, body } = parseFrontmatter(readFileSync2(join5(CONTENT_DIR, "agents", f), "utf8"));
323
- return { name: f.replace(/\.md$/, ""), data, body };
383
+ return { name: f.replace(/\.md$/, ""), data, body, refs: [] };
324
384
  });
325
385
  return { skills, agents };
326
386
  }
387
+ function collectRefs(skillDir) {
388
+ const refsDir = join5(skillDir, "references");
389
+ if (!existsSync3(refsDir))
390
+ return [];
391
+ return readdirSync(refsDir, { recursive: true }).map((f) => String(f)).filter((f) => f.endsWith(".md")).map((rel) => ({ relPath: rel, text: readFileSync2(join5(refsDir, rel), "utf8") }));
392
+ }
327
393
  function installTo(target10, opts) {
328
394
  const { scope, projectDir, dryRun = false, force = false } = opts;
329
395
  const home = opts.home ?? homedir();
@@ -360,11 +426,26 @@ function installTo(target10, opts) {
360
426
  const out = target10.transformSkill(s.data, s.body);
361
427
  if (out)
362
428
  writeOne(join5(dirs.skillsDir, out.relPath), out.text);
429
+ if (target10.transformSkillFull) {
430
+ const full = target10.transformSkillFull(s.data, s.body);
431
+ if (full && target10.refsDir)
432
+ writeOne(join5(target10.refsDir({ scope, projectDir, home }, s.name), full.relPath), full.text);
433
+ }
434
+ if (s.refs.length && target10.refsDir) {
435
+ const refsRoot = target10.refsDir({ scope, projectDir, home }, s.name);
436
+ for (const r of s.refs)
437
+ writeOne(join5(refsRoot, r.relPath), r.text);
438
+ }
363
439
  }
364
440
  for (const a of agents) {
365
441
  const out = target10.transformAgent(a.data, a.body);
366
442
  if (out)
367
443
  writeOne(join5(dirs.agentsDir, out.relPath), out.text);
444
+ if (target10.transformAgentFull) {
445
+ const full = target10.transformAgentFull(a.data, a.body);
446
+ if (full && target10.refsDir)
447
+ writeOne(join5(target10.refsDir({ scope, projectDir, home }, a.name), full.relPath), full.text);
448
+ }
368
449
  }
369
450
  if (target10.postInstall) {
370
451
  const post = target10.postInstall({ scope, projectDir, home, dryRun, files: result.written });
@@ -412,6 +493,62 @@ function writeManifest(file, data) {
412
493
  `);
413
494
  }
414
495
 
496
+ // src/mission.ts
497
+ import { existsSync as existsSync5, rmSync as rmSync2, readFileSync as readFileSync4 } from "node:fs";
498
+ import { join as join7 } from "node:path";
499
+ function activeActor(projectDir) {
500
+ const stateFile = join7(projectDir, ".mugiwara", "state.json");
501
+ if (!existsSync5(stateFile))
502
+ return null;
503
+ try {
504
+ const state = JSON.parse(readFileSync4(stateFile, "utf8"));
505
+ return state.actor || null;
506
+ } catch {
507
+ return null;
508
+ }
509
+ }
510
+ function resetMission(projectDir, keepLogs, force) {
511
+ const root = join7(projectDir, ".mugiwara");
512
+ if (!existsSync5(root))
513
+ return { removed: [], kept: [] };
514
+ if (!force) {
515
+ const actor = activeActor(projectDir);
516
+ if (actor) {
517
+ return { removed: [], kept: [], blocked: `Active mission for '${actor}'. Use --force to override.` };
518
+ }
519
+ }
520
+ const removed = [];
521
+ const kept = [];
522
+ for (const dir of ["spec", "plans", "results", "review", "issues", "reports"]) {
523
+ const p = join7(root, dir);
524
+ if (existsSync5(p)) {
525
+ rmSync2(p, { recursive: true, force: true });
526
+ removed.push(dir);
527
+ }
528
+ }
529
+ for (const f of ["state.json"]) {
530
+ const p = join7(root, f);
531
+ if (existsSync5(p)) {
532
+ rmSync2(p);
533
+ removed.push(f);
534
+ }
535
+ }
536
+ if (!keepLogs) {
537
+ const p = join7(root, "logs");
538
+ if (existsSync5(p)) {
539
+ rmSync2(p, { recursive: true, force: true });
540
+ removed.push("logs");
541
+ }
542
+ } else if (existsSync5(join7(root, "logs"))) {
543
+ kept.push("logs");
544
+ }
545
+ for (const f of ["config", "manifest.json", "backup"]) {
546
+ if (existsSync5(join7(root, f)))
547
+ kept.push(f);
548
+ }
549
+ return { removed, kept };
550
+ }
551
+
415
552
  // src/cli.ts
416
553
  var str = (v) => typeof v === "string" ? v : undefined;
417
554
  var flag = (v) => v === true;
@@ -432,12 +569,27 @@ async function run(argv) {
432
569
  return uninstall(flags);
433
570
  case "list":
434
571
  return list(flags);
435
- case "skills":
436
- return skills();
572
+ case "reset":
573
+ return resetCmd(flags);
437
574
  default:
438
575
  throw new Error(`Unknown command: ${command}`);
439
576
  }
440
577
  }
578
+ function resetCmd(flags) {
579
+ const projectDir = resolve(str(flags.project) ?? process.cwd());
580
+ const force = flag(flags.force);
581
+ const result = resetMission(projectDir, flag(flags.keepLogs), force);
582
+ if (result.blocked) {
583
+ console.error(`✗ ${result.blocked}`);
584
+ process.exit(1);
585
+ }
586
+ if (result.removed.length)
587
+ console.log(`removed: ${result.removed.join(", ")}`);
588
+ else
589
+ console.log("nothing to remove.");
590
+ if (result.kept.length)
591
+ console.log(`kept: ${result.kept.join(", ")}`);
592
+ }
441
593
  async function resolveOptions(flags) {
442
594
  const interactive = !flag(flags.yes);
443
595
  const rl = interactive ? createRl() : null;
@@ -449,7 +601,7 @@ async function resolveOptions(flags) {
449
601
  scope = await choose(rl, "Install scope?", ["global (user-wide)", "project (this repo)"]) === 0 ? "global" : "project";
450
602
  }
451
603
  const projectDir = resolve(str(flags.project) ?? process.cwd());
452
- if (scope === "project" && !existsSync5(projectDir))
604
+ if (scope === "project" && !existsSync6(projectDir))
453
605
  throw new Error(`Project dir not found: ${projectDir}`);
454
606
  let targetIds = str(flags.target)?.split(",").map((s) => s.trim()) ?? null;
455
607
  if (targetIds && targetIds.includes("all"))
@@ -533,7 +685,7 @@ async function uninstall(flags) {
533
685
  }
534
686
  const removed = removeInstalled(manifest, { dryRun: flag(flags.dryRun) });
535
687
  if (!flag(flags.dryRun))
536
- rmSync2(file);
688
+ rmSync3(file);
537
689
  console.log(`OK removed ${removed.length} files`);
538
690
  }
539
691
  function list(flags) {
@@ -553,22 +705,6 @@ function list(flags) {
553
705
  if (!found)
554
706
  console.log("No mugiwara installation found.");
555
707
  }
556
- function skills() {
557
- const dir = join7(CONTENT_DIR, "skills");
558
- const names = readdirSync2(dir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name).sort();
559
- const rows = names.map((name) => {
560
- const { data } = parseFrontmatter(readFileSync4(join7(dir, name, "SKILL.md"), "utf8"));
561
- return [name, data.description ?? ""];
562
- });
563
- const w = Math.max(...rows.map((r) => r[0].length)) + 2;
564
- console.log(`mugiwara ${VERSION} — ${rows.length} skills (agentskills.io format):
565
- `);
566
- for (const [name, description] of rows)
567
- console.log(` ${name.padEnd(w)}${description}`);
568
- console.log(`
569
- Install skills into any agent via skills.sh:
570
- npx skills add ionivetech/mugiwara`);
571
- }
572
708
  function help() {
573
709
  console.log(`mugiwara ${VERSION} — the Straw Hat crew for AI agents
574
710
 
@@ -577,7 +713,7 @@ Usage:
577
713
  mugiwara update replace existing files (backs up differences first)
578
714
  mugiwara uninstall remove installed files via manifest
579
715
  mugiwara list show installations
580
- mugiwara skills list installable skills (agentskills.io)
716
+ mugiwara reset wipe mission state (spec/plans/results/review/issues[/logs])
581
717
  mugiwara --help this help
582
718
  mugiwara --version print version
583
719
 
@@ -587,7 +723,8 @@ Flags:
587
723
  --target <ids|all> comma-separated: ${TARGET_IDS.join(", ")}
588
724
  --yes, -y non-interactive (needs --global/--project, --target)
589
725
  --force overwrite differing files (with backup)
590
- --dry-run print actions without writing`);
726
+ --dry-run print actions without writing
727
+ --keep-logs with reset: keep .mugiwara/logs (lessons ledger survives)`);
591
728
  }
592
729
  var entry = process.argv[1] !== undefined ? resolve(process.argv[1]) : undefined;
593
730
  if (entry !== undefined) {
@@ -43,8 +43,8 @@ mid-wave.
43
43
 
44
44
  ## Fit the crew to your workflow
45
45
 
46
- - **Trivial one-liners** don't need the crew — Luffy routes them straight to
47
- execution.
46
+ - **Trivial one-liners** don't need the crew's full pipeline — Luffy routes them
47
+ to Lane 0 and they run with zero waves. The process scales to the work.
48
48
  - **Medium features** run the standard pipeline: triage → plan → execute →
49
49
  checkpoint → quality → gates → review → closure.
50
50
  - **High-stakes work** (money, security, data, public API) always gets the full
package/docs/agents.md CHANGED
@@ -44,8 +44,8 @@ check-ins. The harness stays coherent either way.
44
44
 
45
45
  ## The crew ships whole
46
46
 
47
- Every install gets all 15 agents and all 32 skills. No project-type selection —
47
+ Every install gets all 15 agents and all 26 skills. No project-type selection —
48
48
  the harness routes each task to the right specialist.
49
49
 
50
- See [skills.md](skills.md) for the 32 techniques, or
50
+ See [skills.md](skills.md) for the 26 techniques, or
51
51
  [workflow.md](workflow.md) for the pipeline.
@@ -0,0 +1,65 @@
1
+ # Audit Trail
2
+
3
+ Every artifact the Mugiwara crew produces — what writes it, when, and how to
4
+ read it as a reviewer.
5
+
6
+ ## The artifacts
7
+
8
+ | Artifact | Path | Written by | When | For |
9
+ |----------|------|-----------|------|-----|
10
+ | **Plan doc** | `.mugiwara/plans/YYYY-MM-DD-<mission>.md` | Nami (planning) | Wave 2 | Zero-context executor — waves, tasks, criteria, risk |
11
+ | **Spec** | `.mugiwara/spec/YYYY-MM-DD-<mission>.md` | Usopp (brainstorm) / Luffy (spec bridge) | Wave 0–1 | Bridge from idea to plan — goal, acceptance, constraints |
12
+ | **State** | `.mugiwara/state.json` | `scripts/savepoint.sh` | Every wave boundary | Computed mission state: lane, wave, files, blockers, token budget, evidence paths |
13
+ | **Decision log** | `.mugiwara/logs/YYYY-MM-DD-<mission>.md` | Luffy (orchestrator) | Every wave | Route reason, check-in verdicts, mode flips, decisions |
14
+ | **Blocker ledger** | `.mugiwara/issues/YYYY-MM-DD-<mission>-blockers.md` | Any agent | On blocker hit | Row per blocker: wave, task, symptom, attempted, help-needed |
15
+ | **Todo list** | `.mugiwara/results/<mission>-todos.md` | Zoro (execution) | Wave 3 | Checkbox per task, checked with evidence pointer |
16
+ | **Audit report** | `.mugiwara/results/YYYY-MM-DD-<mission>-audit.md` | Chopper (checkpoint) | Wave 4 | Per-task evidence, commit hygiene, parallel-conflict, honest classification |
17
+ | **Quality report** | `.mugiwara/results/YYYY-MM-DD-<mission>-quality.md` | Sanji (quality) | Wave 5 | Formatter/linter/unit/user-test results |
18
+ | **Gate verdict** | `.mugiwara/results/YYYY-MM-DD-<mission>-gates.md` | Franky (gates) | Wave 6 | Coverage thresholds from config, build exit, DoD verdict |
19
+ | **Review findings** | `.mugiwara/review/YYYY-MM-DD-<mission>-review.md` | Robin (review) | Wave 7 | Severity-tagged: path:line → problem → fix |
20
+ | **Security report** | `.mugiwara/review/YYYY-MM-DD-<mission>-security.md` | Jinbe (security) | Wave 7 | STRIDE, OWASP mapping, checklist, CVSS severity |
21
+ | **Heal report** | `.mugiwara/results/YYYY-MM-DD-<mission>-heal.md` | Brook (healing) | Wave 8 | Fixed list, escalated list, updated ledger |
22
+ | **Closure report** | `.mugiwara/results/YYYY-MM-DD-<mission>-closure.md` | Luffy (orchestrator) | Wave 9 | Mission summary, per-wave outcomes, deferred items, lessons |
23
+ | **Mission report** | `.mugiwara/reports/YYYY-MM-DD-<mission>.md` | `scripts/mission-report.sh` | Wave 9 | Human-readable summary: what changed, gates, state, token cost |
24
+ | **PR verdict** | `.mugiwara/results/YYYY-MM-DD-<mission>-pr-verdict.md` | Luffy (orchestrator) | Wave 9 | Ready PR summary block for the user to open the PR |
25
+ | **Trace** | `.mugiwara/results/<mission>-trace.md` | Resume coordinator | Every dispatch | Dispatch → outcome — drives resume (legacy; state.json preferred) |
26
+ | **Lessons ledger** | `.mugiwara/logs/lessons.md` | Memory Keeper | Cross-mission | One row per real lesson, append-only, all actors share |
27
+ | **Evidence logs** | `.mugiwara/results/<label>-<hash>.log` | `scripts/evidence.sh` | On demand | Command stdout/stderr capture with timestamp and exit code |
28
+
29
+ ## How to read as a reviewer
30
+
31
+ 1. **Start with the mission report** (`reports/`) — one file, what changed, gates, token cost.
32
+ 2. **Check the gate verdict** (`results/<mission>-gates.md`) — coverage from config, build, DoD. Any FAIL needs explanation.
33
+ 3. **Spot-check the audit report** (`results/<mission>-audit.md`) — did Chopper re-run checks or accept claims? Every criterion gets a command run + evidence row.
34
+ 4. **Review findings count** (`review/`) — how many blocker/major/minor? Were they healed? Check the heal report for closure.
35
+ 5. **State.json** for raw numbers — lane, wave, files, blockers open, heal cycle, token budget status (ok/warn/stop).
36
+
37
+ ## What stays after cleanup
38
+
39
+ After Wave 9 closure (run via `mugiwara-ship` cleanup procedure):
40
+
41
+ **Kept** (audit trail + PR material):
42
+ - `config` — runtime config
43
+ - `plans/<mission>.md` — clean plan doc
44
+ - `results/<mission>-closure.md` — closure report
45
+ - `results/<mission>-pr-verdict.md` — PR material
46
+ - `reports/<mission>.md` — mission report
47
+ - `state.json` — final mission state (unless another actor's mission is active)
48
+ - `logs/lessons.md` — cross-mission lessons
49
+ - `backup/`, `manifest.json` — harness config
50
+
51
+ **Deleted** (consumed/superseded):
52
+ - `spec/<mission>.md` — consumed by planning
53
+ - `results/<mission>-todos.md` — consumed
54
+ - `results/<mission>-audit.md` — superseded by closure
55
+ - `results/<mission>-quality.md` — consumed
56
+ - `results/<mission>-gates.md` — consumed
57
+ - `results/<mission>-heal.md` — consumed
58
+ - `results/<mission>-trace.md` — consumed (state.json is canonical)
59
+ - `review/<mission>-review.md` — consumed
60
+ - `review/<mission>-security.md` — consumed
61
+ - `issues/<mission>-blockers.md` — consumed
62
+ - `logs/<mission>.md` — decision log, per-mission
63
+
64
+ Cleanup lists candidates first (dry-run), then deletes. A mission is only
65
+ closed after cleanup runs.