@ionivetech/mugiwara 0.5.4 → 0.6.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 (158) hide show
  1. package/.claude-plugin/marketplace.json +3 -3
  2. package/.claude-plugin/plugin.json +4 -3
  3. package/.codex-plugin/plugin.json +2 -2
  4. package/.cursor-plugin/plugin.json +2 -2
  5. package/.kimi-plugin/plugin.json +2 -2
  6. package/.opencode/commands/mugiwara-continue.md +16 -0
  7. package/.opencode/commands/mugiwara-execute.md +6 -4
  8. package/.opencode/commands/mugiwara-heal.md +6 -4
  9. package/.opencode/commands/mugiwara-plan.md +6 -4
  10. package/.opencode/commands/mugiwara-review.md +6 -4
  11. package/.opencode/commands/mugiwara-security.md +6 -4
  12. package/.opencode/commands/mugiwara-ship.md +6 -4
  13. package/.opencode/commands/mugiwara.md +4 -2
  14. package/.opencode/commands/using-mugiwara.md +7 -13
  15. package/.opencode/plugins/mugiwara.mjs +18 -6
  16. package/AGENTS.md +2 -2
  17. package/GEMINI.md +1 -1
  18. package/README.md +240 -217
  19. package/content/agents/brook-healing.md +17 -3
  20. package/content/agents/chopper-checkpoint.md +17 -3
  21. package/content/agents/eval-runner.md +17 -2
  22. package/content/agents/franky-gates.md +19 -5
  23. package/content/agents/jinbe-security.md +19 -3
  24. package/content/agents/luffy-orchestrator.md +6 -3
  25. package/content/agents/memory-keeper.md +15 -0
  26. package/content/agents/nami-planner.md +21 -6
  27. package/content/agents/onboarding-guide.md +145 -0
  28. package/content/agents/resume-coordinator.md +21 -5
  29. package/content/agents/robin-reviewer.md +18 -3
  30. package/content/agents/sanji-quality.md +19 -4
  31. package/content/agents/skeptic-verifier.md +18 -3
  32. package/content/agents/usopp-brainstorm.md +17 -3
  33. package/content/agents/zoro-execution.md +19 -5
  34. package/content/skills/mugiwara-backend/SKILL.md +1 -1
  35. package/content/skills/mugiwara-brainstorm/SKILL.md +5 -1
  36. package/content/skills/mugiwara-checkpoint/SKILL.md +2 -2
  37. package/content/skills/mugiwara-contract-first/SKILL.md +2 -36
  38. package/content/skills/mugiwara-contract-first/references/process.md +37 -0
  39. package/content/skills/mugiwara-execution/SKILL.md +30 -13
  40. package/content/skills/mugiwara-execution/references/resume-batching.md +32 -0
  41. package/content/skills/mugiwara-frontend/SKILL.md +1 -1
  42. package/content/skills/mugiwara-gates/SKILL.md +32 -30
  43. package/content/skills/mugiwara-healing/SKILL.md +1 -1
  44. package/content/skills/mugiwara-orchestration/SKILL.md +41 -25
  45. package/content/skills/mugiwara-orchestration/references/delegation-pillars.md +40 -0
  46. package/content/skills/mugiwara-orchestration/references/triage-escalation.md +96 -0
  47. package/content/skills/mugiwara-planning/SKILL.md +23 -27
  48. package/content/skills/mugiwara-planning/references/plan-template.md +42 -0
  49. package/content/skills/mugiwara-pr/SKILL.md +2 -2
  50. package/content/skills/mugiwara-quality/SKILL.md +10 -6
  51. package/content/skills/mugiwara-resume/SKILL.md +7 -2
  52. package/content/skills/mugiwara-review/SKILL.md +20 -1
  53. package/content/skills/mugiwara-review/references/code-attributes.md +38 -0
  54. package/content/skills/mugiwara-root-cause/SKILL.md +3 -30
  55. package/content/skills/mugiwara-root-cause/references/process.md +35 -0
  56. package/content/skills/mugiwara-security/SKILL.md +17 -32
  57. package/content/skills/mugiwara-security/references/owasp-top10.md +12 -0
  58. package/content/skills/mugiwara-security/references/rationalizations.md +8 -0
  59. package/content/skills/mugiwara-ship/SKILL.md +5 -4
  60. package/content/skills/mugiwara-workflow/SKILL.md +74 -77
  61. package/content/skills/mugiwara-workflow/references/workspace-layout.md +50 -0
  62. package/content/skills/using-mugiwara/SKILL.md +8 -19
  63. package/dist/mugiwara.js +206 -87
  64. package/gemini-extension.json +1 -1
  65. package/hooks/session-start.ts +1 -1
  66. package/package.json +12 -5
  67. package/plugin.json +2 -2
  68. package/references/multi-actor.md +1 -1
  69. package/scripts/evidence.sh +13 -6
  70. package/scripts/gate-selftest.ts +266 -0
  71. package/scripts/initiative.ts +248 -0
  72. package/scripts/lane.sh +15 -0
  73. package/scripts/mission-report.sh +141 -76
  74. package/scripts/onboard.ts +292 -0
  75. package/scripts/release-notes.ts +42 -13
  76. package/scripts/retrieval-eval.ts +1 -2
  77. package/scripts/run-evals.ts +1 -1
  78. package/scripts/savepoint.sh +97 -50
  79. package/scripts/validate-content.ts +84 -7
  80. package/scripts/verify-install.ts +72 -0
  81. package/src/args.ts +1 -1
  82. package/src/cli.ts +49 -22
  83. package/src/frontmatter.ts +3 -3
  84. package/src/installer.ts +44 -15
  85. package/src/mission.ts +7 -5
  86. package/src/targets/claude.ts +20 -3
  87. package/src/targets/generic.ts +1 -1
  88. package/src/targets/opencode.ts +53 -11
  89. package/docs/adoption-guide.md +0 -72
  90. package/docs/agent-anatomy.md +0 -72
  91. package/docs/agents.md +0 -53
  92. package/docs/audit-trail.md +0 -65
  93. package/docs/claude-setup.md +0 -43
  94. package/docs/codex-setup.md +0 -26
  95. package/docs/comparison.md +0 -58
  96. package/docs/compliance-matrix.md +0 -81
  97. package/docs/config.md +0 -55
  98. package/docs/copilot-setup.md +0 -29
  99. package/docs/cost.md +0 -45
  100. package/docs/cursor-setup.md +0 -25
  101. package/docs/developer-onboarding.md +0 -89
  102. package/docs/enforcement.md +0 -35
  103. package/docs/execution-model.md +0 -92
  104. package/docs/gemini-setup.md +0 -27
  105. package/docs/getting-started.md +0 -158
  106. package/docs/git-strategy.md +0 -62
  107. package/docs/harness-matrix.md +0 -41
  108. package/docs/index.md +0 -56
  109. package/docs/install-antigravity.md +0 -45
  110. package/docs/install-claude.md +0 -75
  111. package/docs/install-cli.md +0 -103
  112. package/docs/install-codex.md +0 -44
  113. package/docs/install-copilot.md +0 -45
  114. package/docs/install-cursor.md +0 -45
  115. package/docs/install-gemini.md +0 -44
  116. package/docs/install-kimi.md +0 -45
  117. package/docs/install-opencode.md +0 -129
  118. package/docs/install-pi.md +0 -46
  119. package/docs/install.md +0 -53
  120. package/docs/lanes.md +0 -82
  121. package/docs/modes.md +0 -74
  122. package/docs/opencode-setup.md +0 -54
  123. package/docs/pr-summary.md +0 -54
  124. package/docs/rule-based-setup.md +0 -31
  125. package/docs/skill-anatomy.md +0 -71
  126. package/docs/skills.md +0 -55
  127. package/docs/troubleshooting.md +0 -91
  128. package/docs/windsurf-setup.md +0 -18
  129. package/docs/workflow.md +0 -89
  130. package/evals/cases/_no-skill.json +0 -16
  131. package/evals/cases/adversarial-pressure-fake-pass.json +0 -25
  132. package/evals/cases/adversarial-pressure-skip-review.json +0 -25
  133. package/evals/cases/lane-exploratory-vague.json +0 -24
  134. package/evals/cases/lane-sensitivity-payment.json +0 -24
  135. package/evals/cases/positive-refactor-existing-tests.json +0 -25
  136. package/evals/cases/positive-resume-mid-mission.json +0 -24
  137. package/evals/cases/routing-agent-security.json +0 -25
  138. package/evals/cases/routing-auth-feature.json +0 -26
  139. package/evals/cases/routing-backend.json +0 -25
  140. package/evals/cases/routing-bug-one-file.json +0 -26
  141. package/evals/cases/routing-claim-audit.json +0 -25
  142. package/evals/cases/routing-context-budget.json +0 -25
  143. package/evals/cases/routing-contract-first.json +0 -25
  144. package/evals/cases/routing-execution.json +0 -25
  145. package/evals/cases/routing-frontend.json +0 -26
  146. package/evals/cases/routing-gates.json +0 -25
  147. package/evals/cases/routing-git.json +0 -25
  148. package/evals/cases/routing-healing.json +0 -25
  149. package/evals/cases/routing-lessons.json +0 -25
  150. package/evals/cases/routing-orchestration.json +0 -25
  151. package/evals/cases/routing-planning.json +0 -26
  152. package/evals/cases/routing-pr.json +0 -25
  153. package/evals/cases/routing-quality.json +0 -25
  154. package/evals/cases/routing-ship.json +0 -26
  155. package/evals/cases/routing-sunset.json +0 -25
  156. package/evals/cases/routing-using-mugiwara.json +0 -25
  157. package/evals/cases/routing-workflow.json +0 -25
  158. package/evals/floor.json +0 -6
package/src/installer.ts CHANGED
@@ -2,6 +2,7 @@
2
2
  import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync, copyFileSync, rmSync } from 'node:fs';
3
3
  import { dirname, join } from 'node:path';
4
4
  import { homedir } from 'node:os';
5
+ import { fileURLToPath } from 'node:url';
5
6
  import { parseFrontmatter, type FrontmatterData } from './frontmatter.ts';
6
7
  import type { Scope } from './manifest.ts';
7
8
 
@@ -10,6 +11,7 @@ export type ContentItem = {
10
11
  data: FrontmatterData;
11
12
  body: string;
12
13
  refs: { relPath: string; text: string }[];
14
+ internal?: boolean;
13
15
  };
14
16
 
15
17
  export type InstallOptions = {
@@ -34,6 +36,7 @@ export interface Target {
34
36
  label: string;
35
37
  native: boolean;
36
38
  tier?: 1 | 2 | 3;
39
+ refPointerPrefix?: string;
37
40
  paths(opts: { scope: Scope; projectDir: string; home: string }): { skillsDir: string; agentsDir: string };
38
41
  transformSkill(data: FrontmatterData, body: string): TransformOut;
39
42
  transformAgent(data: FrontmatterData, body: string): TransformOut;
@@ -43,11 +46,11 @@ export interface Target {
43
46
  postInstall?(opts: { scope: Scope; projectDir: string; home: string; dryRun: boolean; files: string[] }): { written: string[]; notes: string[] };
44
47
  }
45
48
 
46
- export const CONTENT_DIR = join(import.meta.dirname, '..', 'content');
47
- const pkg = JSON.parse(readFileSync(join(import.meta.dirname, '..', 'package.json'), 'utf8')) as { version: string };
49
+ export const CONTENT_DIR = join(dirname(fileURLToPath(import.meta.url)), '..', 'content');
50
+ const pkg = JSON.parse(readFileSync(join(dirname(fileURLToPath(import.meta.url)), '..', 'package.json'), 'utf8')) as { version: string };
48
51
  export const VERSION = pkg.version;
49
52
 
50
- export function collectContent(): { skills: ContentItem[]; agents: ContentItem[] } {
53
+ export function collectContent(): { skills: ContentItem[]; agents: ContentItem[]; sharedRefs: { relPath: string; text: string }[] } {
51
54
  const skillNames = readdirSync(join(CONTENT_DIR, 'skills'), { withFileTypes: true })
52
55
  .filter(e => e.isDirectory()).map(e => e.name);
53
56
  const skills = skillNames.map(name => {
@@ -58,9 +61,17 @@ export function collectContent(): { skills: ContentItem[]; agents: ContentItem[]
58
61
  .filter(f => f.endsWith('.md'))
59
62
  .map(f => {
60
63
  const { data, body } = parseFrontmatter(readFileSync(join(CONTENT_DIR, 'agents', f), 'utf8'));
61
- return { name: f.replace(/\.md$/, ''), data, body, refs: [] as { relPath: string; text: string }[] };
64
+ return { name: f.replace(/\.md$/, ''), data, body, refs: [] as { relPath: string; text: string }[], internal: data.internal === 'true' };
62
65
  });
63
- return { skills, agents };
66
+ const sharedRefsDir = join(dirname(CONTENT_DIR), 'references');
67
+ const sharedRefs: { relPath: string; text: string }[] = [];
68
+ if (existsSync(sharedRefsDir)) {
69
+ for (const f of readdirSync(sharedRefsDir)) {
70
+ if (!f.endsWith('.md')) continue;
71
+ sharedRefs.push({ relPath: f, text: readFileSync(join(sharedRefsDir, f), 'utf8') });
72
+ }
73
+ }
74
+ return { skills, agents, sharedRefs };
64
75
  }
65
76
 
66
77
  function collectRefs(skillDir: string): { relPath: string; text: string }[] {
@@ -73,7 +84,7 @@ function collectRefs(skillDir: string): { relPath: string; text: string }[] {
73
84
  export function installTo(target: Target, opts: InstallOptions): InstallResult {
74
85
  const { scope, projectDir, dryRun = false, force = false } = opts;
75
86
  const home = opts.home ?? homedir();
76
- const { skills, agents } = collectContent();
87
+ const { skills, agents, sharedRefs } = collectContent();
77
88
  const dirs = target.paths({ scope, projectDir, home });
78
89
  const backupRoot = join(scope === 'global' ? home : projectDir, '.mugiwara');
79
90
  const result: InstallResult = { written: [], skipped: [], backedUp: [], notes: [] };
@@ -87,8 +98,10 @@ export function installTo(target: Target, opts: InstallOptions): InstallResult {
87
98
  return;
88
99
  }
89
100
  const ts = new Date().toISOString().replace(/[:.]/g, '-');
90
- const backupFile = join(backupRoot, 'backup', ts, absPath.replace(/[^a-zA-Z0-9]+/g, '_'));
91
- if (!dryRun) { mkdirSync(dirname(backupFile), { recursive: true }); copyFileSync(absPath, backupFile); }
101
+ const fileName = absPath.replace(/[^a-zA-Z0-9]+/g, '_');
102
+ const backupDir = join(backupRoot, 'backup', `${ts}-${target.id}`);
103
+ const backupFile = join(backupDir, fileName);
104
+ if (!dryRun) { mkdirSync(backupDir, { recursive: true }); copyFileSync(absPath, backupFile); }
92
105
  result.backedUp.push(absPath);
93
106
  }
94
107
  if (!dryRun) { mkdirSync(dirname(absPath), { recursive: true }); writeFileSync(absPath, text); }
@@ -97,10 +110,22 @@ export function installTo(target: Target, opts: InstallOptions): InstallResult {
97
110
 
98
111
  for (const s of skills) {
99
112
  const out = target.transformSkill(s.data, s.body);
100
- if (out) writeOne(join(dirs.skillsDir, out.relPath), out.text);
113
+ if (out) {
114
+ let text = out.text;
115
+ if (target.refPointerPrefix !== undefined && target.refPointerPrefix !== '') {
116
+ text = text.replace(/`_shared\/references\//g, '`' + target.refPointerPrefix + '_shared/references/');
117
+ }
118
+ writeOne(join(dirs.skillsDir, out.relPath), text);
119
+ }
101
120
  if (target.transformSkillFull) {
102
121
  const full = target.transformSkillFull(s.data, s.body);
103
- if (full && target.refsDir) writeOne(join(target.refsDir({ scope, projectDir, home }, s.name), full.relPath), full.text);
122
+ if (full && target.refsDir) {
123
+ let text = full.text;
124
+ if (target.refPointerPrefix !== undefined && target.refPointerPrefix !== '') {
125
+ text = text.replace(/`_shared\/references\//g, '`' + target.refPointerPrefix + '_shared/references/');
126
+ }
127
+ writeOne(join(target.refsDir({ scope, projectDir, home }, s.name), full.relPath), text);
128
+ }
104
129
  }
105
130
  if (s.refs.length && target.refsDir) {
106
131
  const refsRoot = target.refsDir({ scope, projectDir, home }, s.name);
@@ -108,7 +133,7 @@ export function installTo(target: Target, opts: InstallOptions): InstallResult {
108
133
  }
109
134
  }
110
135
  for (const a of agents) {
111
- const out = target.transformAgent(a.data, a.body);
136
+ const out = target.transformAgent({ ...a.data, ...(a.internal ? { 'internal-agent': 'true' } : {}) }, a.body);
112
137
  if (out) writeOne(join(dirs.agentsDir, out.relPath), out.text);
113
138
  if (target.transformAgentFull) {
114
139
  const full = target.transformAgentFull(a.data, a.body);
@@ -116,6 +141,11 @@ export function installTo(target: Target, opts: InstallOptions): InstallResult {
116
141
  }
117
142
  }
118
143
 
144
+ if (sharedRefs.length) {
145
+ const sharedRoot = join(dirs.skillsDir, '_shared', 'references');
146
+ for (const r of sharedRefs) writeOne(join(sharedRoot, r.relPath), r.text);
147
+ }
148
+
119
149
  if (target.postInstall) {
120
150
  const post = target.postInstall({ scope, projectDir, home, dryRun, files: result.written });
121
151
  result.written.push(...post.written);
@@ -133,10 +163,9 @@ export function removeInstalled(manifest: { files: string[] }, { dryRun = false
133
163
  for (const f of manifest.files) {
134
164
  let d = dirname(f);
135
165
  while (existsSync(d) && readdirSync(d).length === 0) {
136
- rmSync(d, { recursive: true });
137
- const parent = dirname(d);
138
- if (parent === d) break;
139
- d = parent;
166
+ if (d.endsWith('/.mugiwara') || d === dirname(d)) break;
167
+ rmSync(d, { recursive: true, force: true });
168
+ d = dirname(d);
140
169
  }
141
170
  }
142
171
  }
package/src/mission.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  // src/mission.ts
2
2
  // Mission-state helpers for the mugiwara CLI (installer + reset only).
3
- import { existsSync, rmSync, readFileSync } from 'node:fs';
3
+ import { existsSync, rmSync, readFileSync, readdirSync } from 'node:fs';
4
4
  import { join } from 'node:path';
5
5
 
6
6
  function activeActor(projectDir: string): string | null {
@@ -30,10 +30,12 @@ export function resetMission(projectDir: string, keepLogs: boolean, force?: bool
30
30
  const p = join(root, dir);
31
31
  if (existsSync(p)) { rmSync(p, { recursive: true, force: true }); removed.push(dir); }
32
32
  }
33
- // mission state files
34
- for (const f of ['state.json']) {
35
- const p = join(root, f);
36
- if (existsSync(p)) { rmSync(p); removed.push(f); }
33
+ // mission state files — state.json + branch-specific state-*.json
34
+ for (const f of readdirSync(root)) {
35
+ if (/^state(-.+)?\.json$/.test(f)) {
36
+ const p = join(root, f);
37
+ if (existsSync(p)) { rmSync(p); removed.push(f); }
38
+ }
37
39
  }
38
40
  if (!keepLogs) {
39
41
  const p = join(root, 'logs');
@@ -1,5 +1,5 @@
1
1
  // src/targets/claude.ts
2
- import { existsSync, readFileSync, mkdirSync, copyFileSync } from 'node:fs';
2
+ import { existsSync, readFileSync, mkdirSync, copyFileSync, chmodSync, readdirSync } from 'node:fs';
3
3
  import { dirname, join } from 'node:path';
4
4
  import { fileURLToPath } from 'node:url';
5
5
  import { stringifyFrontmatter, type FrontmatterData } from '../frontmatter.ts';
@@ -7,11 +7,13 @@ import type { Target } from '../installer.ts';
7
7
 
8
8
  const here = dirname(fileURLToPath(import.meta.url));
9
9
  const HOOK_SRC = join(here, '..', '..', 'hooks', 'session-start.ts');
10
+ const COMMANDS_SRC = join(here, '..', '..', '.claude', 'commands');
10
11
 
11
12
  export const target: Target = {
12
13
  id: 'claude',
13
14
  label: 'Claude Code',
14
15
  native: true,
16
+ refPointerPrefix: '../',
15
17
  paths({ scope, projectDir, home }) {
16
18
  const root = scope === 'global' ? join(home, '.claude') : join(projectDir, '.claude');
17
19
  return { skillsDir: join(root, 'skills'), agentsDir: join(root, 'agents') };
@@ -35,12 +37,27 @@ export const target: Target = {
35
37
  // Wire the SessionStart hook (inline doctrine) into the installed .claude dir.
36
38
  const root = scope === 'global' ? join(home, '.claude') : join(projectDir, '.claude');
37
39
  const hookFile = join(root, 'hooks', 'session-start.ts');
40
+ const written: string[] = [];
41
+ const notes: string[] = [];
38
42
  if (dryRun) return { written: [], notes: [] };
39
43
  if (existsSync(HOOK_SRC) && !existsSync(hookFile)) {
40
44
  mkdirSync(dirname(hookFile), { recursive: true });
41
45
  copyFileSync(HOOK_SRC, hookFile);
42
- return { written: [hookFile], notes: [] };
46
+ chmodSync(hookFile, 0o755);
47
+ written.push(hookFile);
43
48
  }
44
- return { written: [], notes: [] };
49
+ // Port the /mugiwara commands into the installed .claude dir.
50
+ if (existsSync(COMMANDS_SRC)) {
51
+ const dstDir = join(root, 'commands');
52
+ mkdirSync(dstDir, { recursive: true });
53
+ for (const f of readdirSync(COMMANDS_SRC)) {
54
+ if (!f.endsWith('.md')) continue;
55
+ const src = join(COMMANDS_SRC, f);
56
+ const dst = join(dstDir, f);
57
+ if (!existsSync(dst)) { copyFileSync(src, dst); written.push(dst); }
58
+ else notes.push(`existing command kept: ${dst}`);
59
+ }
60
+ }
61
+ return { written, notes };
45
62
  },
46
63
  };
@@ -44,7 +44,7 @@ export function makeGeneric(opts: {
44
44
  if (stubOnly) {
45
45
  return {
46
46
  relPath: `agent-${data.name}.md`,
47
- text: `# Agent: ${data.name}\n\n> ${data.description}\n\nSkills: ${data.skills ?? ''}. Read \`.mugiwara/refs/${data.name}.md\` when embodying this role.`,
47
+ text: `# Agent: ${data.name}\n\n> ${data.description}\n\nSkills: ${data.skills ?? ''}. Read \`.mugiwara/refs/${data.name}.md\` when embodying this role.\n\nOnly zoro-execution and brook-healing may modify source code.\nReturn your output to luffy-orchestrator; do not choose the next step.`,
48
48
  };
49
49
  }
50
50
  return { relPath: `agent-${data.name}.md`, text: `# Agent: ${data.name}\n\n> ${data.description}\n\nSkills used: ${data.skills ?? ''}\n\n${body}` };
@@ -1,8 +1,13 @@
1
1
  // src/targets/opencode.ts
2
- import { join } from 'node:path';
2
+ import { existsSync, readdirSync, copyFileSync, mkdirSync } from 'node:fs';
3
+ import { dirname, join } from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
3
5
  import { stringifyFrontmatter, type FrontmatterData } from '../frontmatter.ts';
4
6
  import type { Target } from '../installer.ts';
5
7
 
8
+ const here = dirname(fileURLToPath(import.meta.url));
9
+ const COMMANDS_SRC = join(here, '..', '..', '.opencode', 'commands');
10
+
6
11
  type CrewConfig = {
7
12
  color: string;
8
13
  temperature: number;
@@ -15,26 +20,45 @@ const CREW: Record<string, CrewConfig> = {
15
20
  'usopp-brainstorm': { color: '#f59e0b', temperature: 0.6, steps: 15 },
16
21
  'nami-planner': { color: '#f97316', temperature: 0.2, steps: 15 },
17
22
  'zoro-execution': { color: '#22c55e', temperature: 0.1, steps: 30 },
18
- 'chopper-checkpoint': { color: '#3b82f6', temperature: 0.1, permission: { edit: 'deny' }, steps: 15 },
19
- 'sanji-quality': { color: '#a855f7', temperature: 0.1, permission: { edit: 'deny' }, steps: 10 },
20
- 'franky-gates': { color: '#06b6d4', temperature: 0.1, permission: { edit: 'deny' }, steps: 10 },
21
- 'robin-reviewer': { color: '#8b5cf6', temperature: 0.2, permission: { edit: 'deny' }, steps: 15 },
22
- 'jinbe-security': { color: '#6366f1', temperature: 0.2, permission: { edit: 'deny' }, steps: 15 },
23
+ 'chopper-checkpoint': { color: '#3b82f6', temperature: 0.1, steps: 15 },
24
+ 'sanji-quality': { color: '#a855f7', temperature: 0.1, steps: 10 },
25
+ 'franky-gates': { color: '#06b6d4', temperature: 0.1, steps: 10 },
26
+ 'robin-reviewer': { color: '#8b5cf6', temperature: 0.2, steps: 15 },
27
+ 'jinbe-security': { color: '#6366f1', temperature: 0.2, steps: 15 },
23
28
  'brook-healing': { color: '#ec4899', temperature: 0.1, steps: 20 },
24
- 'skeptic-verifier': { color: '#64748b', temperature: 0.1, permission: { edit: 'deny' }, steps: 12 },
29
+ 'skeptic-verifier': { color: '#64748b', temperature: 0.1, steps: 12 },
25
30
  'eval-runner': { color: '#14b8a6', temperature: 0.2, steps: 15 },
26
31
  'resume-coordinator': { color: '#d97706', temperature: 0.2, steps: 10 },
27
32
  'memory-keeper': { color: '#d946ef', temperature: 0.2, steps: 8 },
28
33
  };
29
34
 
30
- function agentFrontmatter(name: string, description: string) {
35
+ // write-scope is the single source of truth (content/agents/*.md frontmatter).
36
+ // The path boundary (artifacts vs source) IS expressible in opencode:
37
+ // permission.edit accepts glob/pattern -> action, last match wins. Artifacts
38
+ // agents get deny-all-edit except .mugiwara/**; source agents (zoro, brook)
39
+ // get full edit allow. Derived at install time from the frontmatter field.
40
+ function permissionFromScope(scope: string | undefined): Record<string, string | Record<string, string>> | undefined {
41
+ if (scope === 'source') return { edit: 'allow' };
42
+ if (scope === 'artifacts') return { edit: { '*': 'deny', '.mugiwara/**': 'allow' } };
43
+ return undefined;
44
+ }
45
+
46
+ function agentFrontmatter(name: string, description: string, writeScope?: string) {
31
47
  const crew = CREW[name];
32
48
  const lines = [`description: ${description}`, `mode: all`];
33
49
  if (crew) {
34
50
  lines.push(`color: '${crew.color}'`, `temperature: ${crew.temperature}`, `steps: ${crew.steps}`);
35
- if (crew.permission) {
51
+ const perm = permissionFromScope(writeScope);
52
+ if (perm) {
36
53
  lines.push('permission:');
37
- for (const [k, v] of Object.entries(crew.permission)) lines.push(` ${k}: ${v}`);
54
+ for (const [k, v] of Object.entries(perm)) {
55
+ if (typeof v === 'string') {
56
+ lines.push(` ${k}: ${v}`);
57
+ } else {
58
+ lines.push(` ${k}:`);
59
+ for (const [pk, pv] of Object.entries(v)) lines.push(` "${pk}": ${pv}`);
60
+ }
61
+ }
38
62
  }
39
63
  }
40
64
  return lines.join('\n');
@@ -44,6 +68,7 @@ export const target: Target = {
44
68
  id: 'opencode',
45
69
  label: 'opencode',
46
70
  native: true,
71
+ refPointerPrefix: '../',
47
72
  paths({ scope, projectDir, home }) {
48
73
  const root = scope === 'global' ? join(home, '.config', 'opencode') : join(projectDir, '.opencode');
49
74
  return { skillsDir: join(root, 'skills'), agentsDir: join(root, 'agents') };
@@ -55,11 +80,28 @@ export const target: Target = {
55
80
  };
56
81
  },
57
82
  transformAgent(data: FrontmatterData, body: string) {
58
- const fm = agentFrontmatter(data.name, data.description);
83
+ const desc = data['internal-agent'] === 'true' ? `[INTERNAL] ${data.description}` : data.description;
84
+ const fm = agentFrontmatter(data.name, desc, data['write-scope']);
59
85
  return { relPath: `${data.name}.md`, text: `---\n${fm}\n---\n${body}` };
60
86
  },
61
87
  refsDir({ scope, projectDir, home }, skillName: string) {
62
88
  const root = scope === 'global' ? join(home, '.config', 'opencode') : join(projectDir, '.opencode');
63
89
  return join(root, 'skills', skillName, 'references');
64
90
  },
91
+ postInstall({ scope, projectDir, home, dryRun }) {
92
+ const root = scope === 'global' ? join(home, '.config', 'opencode') : join(projectDir, '.opencode');
93
+ const dstDir = join(root, 'commands');
94
+ if (dryRun) return { written: [], notes: [] };
95
+ if (!existsSync(COMMANDS_SRC)) return { written: [], notes: [] };
96
+ mkdirSync(dstDir, { recursive: true });
97
+ const written: string[] = [];
98
+ for (const f of readdirSync(COMMANDS_SRC)) {
99
+ if (!f.endsWith('.md')) continue;
100
+ const src = join(COMMANDS_SRC, f);
101
+ const dst = join(dstDir, f);
102
+ copyFileSync(src, dst);
103
+ written.push(dst);
104
+ }
105
+ return { written, notes: [] };
106
+ },
65
107
  };
@@ -1,72 +0,0 @@
1
- # Adoption Guide
2
-
3
- How to take the crew into your workflow without fighting it.
4
-
5
- ## Pick your harness
6
-
7
- The crew ships native skills + agents where the harness supports them, and
8
- markdown rule files everywhere else.
9
-
10
- | Situation | Pick |
11
- |-----------|------|
12
- | You live in Claude Code or opencode | Native install — agents + skills + (Claude) session hook |
13
- | You want the full crew pipeline | Claude Code, opencode |
14
- | You want skills-only, any tool | `npx skills add ionivetech/mugiwara` (agentskills.io layout) |
15
- | You only use one niche tool | Its per-harness guide (index → install by harness) |
16
-
17
- Native targets (Claude Code, opencode, Copilot) register the 14 agents directly.
18
- Rule-based targets (Gemini, Codex, Cursor, Windsurf, Cline, Kilo, Antigravity)
19
- get the same 32 skills as markdown rules plus a bootstrap pointer, so the crew
20
- is still steered even where subagents don't exist.
21
-
22
- ## Pick your mode
23
-
24
- Modes live in `.mugiwara/config` (project) or `~/.mugiwara/config` (global):
25
-
26
- ```
27
- mode=guided
28
- branch=feature/{type}-{issue}-{slug}
29
- commit=conventional
30
- ```
31
-
32
- | Level | What it asks you |
33
- |-------|------------------|
34
- | `guided` | Plan GO, branch, commits, ambiguities, check-ins — everything |
35
- | `semi` | Plan GO only; branch/commits/ambiguities self-answer and log |
36
- | `auto` | Nothing, unless a high-risk task exists (auto-GO is gated) |
37
-
38
- State-mutating tests against shared state (real DB writes, network, browsers)
39
- always need your explicit consent — in every mode. That consent is not a knob.
40
-
41
- Missing config on read = `guided`. A flip applies from the next wave, never
42
- mid-wave.
43
-
44
- ## Fit the crew to your workflow
45
-
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
- - **Medium features** run the standard pipeline: triage → plan → execute →
49
- checkpoint → quality → gates → review → closure.
50
- - **High-stakes work** (money, security, data, public API) always gets the full
51
- pipeline, including Skeptic's adversarial pass and Brook's heal loop.
52
- - **Repos the crew has touched before** read the lessons ledger at triage, so
53
- every mission stands on the previous ones.
54
-
55
- ## The execution model, in one sentence
56
-
57
- The crew runs **inline in your main conversation**; subagents are used only for
58
- independent `[PARALLEL]` task batches and background checks. You see every wave
59
- as it happens. See [execution-model.md](execution-model.md).
60
-
61
- ## What the crew will never do
62
-
63
- - Merge a PR, or deploy. It pushes the branch and hands you the verdict file —
64
- PR review is the terminal gate.
65
- - Auto-react to review comments or CI.
66
- - Let a wave pass on a spoken claim — evidence or it didn't happen.
67
- - Work around a blocker silently — everything lands in the ledger.
68
-
69
- ## Going further
70
-
71
- - [Developer onboarding](developer-onboarding.md) if you want to contribute.
72
- - [Comparison](comparison.md) if you're weighing mugiwara against alternatives.
@@ -1,72 +0,0 @@
1
- # Agent Anatomy
2
-
3
- Every mugiwara agent is a portable markdown file that names a crew member's
4
- persona, rules, and output contract. Agents are harness-native where supported
5
- (Claude Code, opencode) and markdown rule files elsewhere.
6
-
7
- ## File structure
8
-
9
- ```
10
- agents/<name>.md
11
- ```
12
-
13
- ```markdown
14
- ---
15
- name: chopper-checkpoint
16
- description: Dispatch after each execution wave to audit results against the plan - re-runs every acceptance criterion, verifies commit hygiene and parallel-file safety, classifies failures honestly, appends ledger rows, and issues a Definition-of-Done verdict. Auditor only; never fixes code.
17
- skills: mugiwara-checkpoint
18
- ---
19
-
20
- # Chopper — Checkpoint (Auditor)
21
-
22
- ## Role
23
- ...
24
- ```
25
-
26
- ## Frontmatter
27
-
28
- | Field | Required | Notes |
29
- |-------|----------|-------|
30
- | `name` | yes | lowercase, hyphen-separated; matches the file name |
31
- | `description` | yes | ≥20 chars; what this agent does and when to summon it |
32
- | `skills` | no | the crew skills this member holds, comma-separated |
33
-
34
- Harness-specific agents (opencode) may add `mode`, `permission`, `model`, etc.
35
- in their own installation copy — the content stays portable.
36
-
37
- ## The body — house style
38
-
39
- Agents follow a fixed skeleton so every member reads the same way:
40
-
41
- 1. **Role** — one paragraph: what the member does and the boundary it never
42
- crosses ("Auditor, not fixer", "never implements code").
43
- 2. **Experience** — a one-line persona so the model adopts the right instincts
44
- ("QA lead who has caught 'works on my machine' for 20 years").
45
- 3. **When dispatched** — which wave of `mugiwara-workflow` and with what inputs.
46
- 4. **Rules** — numbered, each an action bound to its reason, deferring to the
47
- held skill for the full protocol.
48
- 5. **Output** — where the artifact lands (`.mugiwara/results/...`) and how it
49
- routes.
50
- 6. **Red flags** — behaviors that mean the member stopped doing its job.
51
-
52
- ## Agent vs skill
53
-
54
- - A **skill** is the reusable playbook ("how to audit a wave").
55
- - An **agent** is the persona that applies it ("Chopper is the auditor; Chopper
56
- never fixes code").
57
-
58
- One agent holds many skills (Zoro holds `mugiwara-execution`, `mugiwara-git`,
59
- `mugiwara-mode`, `mugiwara-testcases`, `mugiwara-backend`). When the crew runs
60
- inline, the main thread loads the member's skills and embodies the persona.
61
-
62
- ## Validation
63
-
64
- Agents are validated alongside skills on check-in (name, description length,
65
- sync between `content/` and the repo-root plugin copies). Run:
66
-
67
- ```bash
68
- bun run validate
69
- bun run validate --check-sync
70
- ```
71
-
72
- See [developer-onboarding.md](developer-onboarding.md).
package/docs/agents.md DELETED
@@ -1,53 +0,0 @@
1
- # The Crew — 14 Agents
2
-
3
- Every agent is a focused specialist. The main thread embodies each role inline
4
- using its skill; you can also summon any member directly. "Dispatch" below
5
- means "route the mission to this role."
6
-
7
- The front door is the `using-mugiwara` skill — load it for crew overview.
8
- Slash command: `/using-mugiwara`.
9
-
10
- | Agent | Crew member | Role | Summon for |
11
- |-------|-------------|------|------------|
12
- | `luffy-orchestrator` | Luffy | Captain — 5-way triage, check-ins, decisions, closure | mission start, wave boundaries, escalations |
13
- | `usopp-brainstorm` | Usopp | Critical friend — interrogates, researches, no rubber-stamps | vague ideas, direction, options |
14
- | `nami-planner` | Nami | Planner — interview-first, full-context scan, scaled plans | turning an idea into an execution plan |
15
- | `zoro-execution` | Zoro | Executor — inline sequential tasks, parallel worker batches, evidence per task | executing an approved plan |
16
- | `chopper-checkpoint` | Chopper | Auditor — verify-everything, deduped re-runs, failure ledger | auditing a wave's results |
17
- | `sanji-quality` | Sanji | Quality — discover real tooling, format/lint/test | after checkpoint passes |
18
- | `franky-gates` | Franky | Gates — coverage, build, Definition of Done, binary verdicts | after quality checks |
19
- | `robin-reviewer` | Robin | Reviewer — doubt-driven diff review, breaking-change map first | after gates pass |
20
- | `jinbe-security` | Jinbe | Security — STRIDE, OWASP, secrets, injection, dependencies | security audit of a diff |
21
- | `brook-healing` | Brook | Healer — reads the ledger, root-cause fixes, ≤3 cycles | any wave produced failures |
22
- | `skeptic-verifier` | Skeptic | Adversarial verifier — doubts every output, does NOT validate | high-stakes verdicts, plans, reviews |
23
- | `eval-runner` | Eval Runner | Harness tester — task suites, judge-agent comparison | verifying mugiwara itself works |
24
- | `resume-coordinator` | Resume Coordinator | Resumer — rebuilds state from `.mugiwara/`, continues never restarts | context loss, new session mid-mission |
25
- | `memory-keeper` | Memory Keeper | Institutional memory — surfaces past lessons, captures new ones | mission start + closure |
26
-
27
- ## How to summon
28
-
29
- Say a crew member's name in your request:
30
-
31
- ```
32
- > Chopper, audit the last wave against the plan
33
- > Nami, plan this out
34
- ```
35
-
36
- Luffy still records the route and its reason, and direct calls do not skip
37
- check-ins. The harness stays coherent either way.
38
-
39
- ## Who never does what
40
-
41
- - **Luffy** never implements code.
42
- - **Chopper** never fixes findings — reports them.
43
- - **Skeptic** never validates — doubts.
44
- - **Robin/Jinbe** never implement — findings to Brook.
45
- - Crew members never dispatch each other. Workers are subagents, never crew.
46
-
47
- ## The crew ships whole
48
-
49
- Every install gets all 14 agents and all 26 skills. No project-type selection —
50
- the harness routes each task to the right specialist.
51
-
52
- See [skills.md](skills.md) for the 26 techniques, or
53
- [workflow.md](workflow.md) for the pipeline.
@@ -1,65 +0,0 @@
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.
@@ -1,43 +0,0 @@
1
- # Claude Code Setup
2
-
3
- Claude Code is a fully supported target — native skills + agents + SessionStart
4
- hook.
5
-
6
- ## Install via the marketplace
7
-
8
- ```bash
9
- /plugin marketplace add ionivetech/mugiwara
10
- /plugin install mugiwara
11
- ```
12
-
13
- ## Install via CLI (global or per project)
14
-
15
- ```bash
16
- # global Claude Code install
17
- npx @ionivetech/mugiwara@latest --global --target claude --yes
18
-
19
- # project install
20
- npx @ionivetech/mugiwara@latest --project ./my-app --target claude --yes
21
- ```
22
-
23
- **Update** — re-install from the marketplace (or `mugiwara update` via CLI).
24
-
25
- **Uninstall** — `/plugin uninstall mugiwara`, or `mugiwara uninstall` via CLI.
26
-
27
- ## What you get
28
-
29
- - 32 skills in `~/.claude/skills/` (global) or `.claude/skills/` (project).
30
- - 14 agents in `~/.claude/agents/` or `.claude/agents/`.
31
- - A SessionStart hook that announces the crew and auto-activates the workflow —
32
- a non-trivial request runs the pipeline by itself. `/using-mugiwara` is an
33
- optional explicit router if you want to hand-route a mission.
34
-
35
- ## Use it
36
-
37
- ```
38
- > add dark mode to the settings page
39
- ```
40
-
41
- The crew runs inline in your main conversation; subagents only for parallel
42
- batches. At closure the crew pushes the branch and hands you the PR verdict
43
- file with a ready PR summary block — you open the PR, in every mode.