@ionivetech/mugiwara 0.5.1 → 0.5.2

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.
@@ -1,8 +1,9 @@
1
1
  // mugiwara — OpenCode plugin.
2
2
  //
3
- // Registers the Mugiwara crew (25 skills + 15 agents) with OpenCode from the
4
- // npm/git package, and announces the crew at session start. No runtime, no
5
- // deps reads the markdown source of truth (content/) at config load.
3
+ // Registers skills/agents via config hook (superpowers pattern: one plugin,
4
+ // zero file-copy), announces the crew at session start, and handles runtime
5
+ // mode switching. CLI `mugiwara install --target opencode` remains available
6
+ // as an alternative file-based path.
6
7
  //
7
8
  // Install: add to opencode.json
8
9
  // { "plugin": ["@ionivetech/mugiwara"] }
@@ -28,7 +29,7 @@ export function readMode({ projectDir = process.cwd(), home = homedir() } = {})
28
29
  for (const line of readFileSync(file, 'utf8').split(/\r?\n/)) {
29
30
  const t = line.trim();
30
31
  if (!t || t.startsWith('#')) continue;
31
- const [k, v] = t.split('=').map((s) => s.trim());
32
+ const [k, v] = line.split('=').map((s) => s.trim());
32
33
  if (k !== 'mode') continue;
33
34
  return VALID_MODES.has(v) ? v : 'INVALID';
34
35
  }
@@ -50,8 +51,6 @@ const agentsDir = join(contentDir, 'agents');
50
51
  const ANNOUNCE =
51
52
  "Mugiwara crew available. The workflow auto-activates for non-trivial requests — no need to call `/using-mugiwara` at session start (it remains an optional router). Run the crew pipeline inline in the main conversation: embody ONE crew role at a time using its skill, wait for its report, then move to the next. Never Task-dispatch a crew member — the crew runs in the main thread; subagents only for [PARALLEL] task batches, concurrent review/security, and independent re-run checks. Progress shows as checkpoint reports at wave/stage boundaries, pausing on failure or risk. Switch mode with `/mugiwara-mode` (guided|semi|auto). See skills/mugiwara-workflow.";
52
53
 
53
- // OpenCode per-agent tuning. Content stays portable markdown; these knobs
54
- // (color, temperature, permission, steps) are opencode-only.
55
54
  const CREW = {
56
55
  'using-mugiwara': { color: '#84cc16', temperature: 0.2, steps: 10 },
57
56
  'luffy-orchestrator': { color: '#ef4444', temperature: 0.2, steps: 15 },
@@ -173,6 +172,8 @@ export function applyModeChange(mode, { projectDir = process.cwd(), home = homed
173
172
  }
174
173
 
175
174
  export default async () => ({
175
+ dispose: () => {},
176
+
176
177
  config: (config) => {
177
178
  config.skills = config.skills || {};
178
179
  config.skills.paths = config.skills.paths || [];
@@ -185,8 +186,6 @@ export default async () => ({
185
186
  }
186
187
  },
187
188
 
188
- // Intercept user messages to detect `/mugiwara-mode` and natural-language
189
- // mode toggles; write `.mugiwara/config` so the next wave reads the new level.
190
189
  'chat.message': async (_input, output) => {
191
190
  if (!output) return;
192
191
  if (typeof output === 'string') {
@@ -204,9 +203,6 @@ export default async () => ({
204
203
  }
205
204
  },
206
205
 
207
- // ponytail-proven hook; appends the announce string to the system prompt.
208
- // Dedupes: repeated transforms (model switch/compaction) must not grow the
209
- // prompt unbounded — only append once per string content.
210
206
  'experimental.chat.system.transform': async (_input, output) => {
211
207
  if (!output.system.some((s) => s.includes('Mugiwara crew available'))) {
212
208
  if (output.system.length > 0) {
package/dist/mugiwara.js CHANGED
@@ -152,6 +152,37 @@ var target = {
152
152
 
153
153
  // src/targets/opencode.ts
154
154
  import { join as join2 } from "node:path";
155
+ var CREW = {
156
+ "using-mugiwara": { color: "#84cc16", temperature: 0.2, steps: 10 },
157
+ "luffy-orchestrator": { color: "#ef4444", temperature: 0.2, steps: 15 },
158
+ "usopp-brainstorm": { color: "#f59e0b", temperature: 0.6, steps: 15 },
159
+ "nami-planner": { color: "#f97316", temperature: 0.2, steps: 15 },
160
+ "zoro-execution": { color: "#22c55e", temperature: 0.1, steps: 30 },
161
+ "chopper-checkpoint": { color: "#3b82f6", temperature: 0.1, permission: { edit: "deny" }, steps: 15 },
162
+ "sanji-quality": { color: "#a855f7", temperature: 0.1, permission: { edit: "deny" }, steps: 10 },
163
+ "franky-gates": { color: "#06b6d4", temperature: 0.1, permission: { edit: "deny" }, steps: 10 },
164
+ "robin-reviewer": { color: "#8b5cf6", temperature: 0.2, permission: { edit: "deny" }, steps: 15 },
165
+ "jinbe-security": { color: "#6366f1", temperature: 0.2, permission: { edit: "deny" }, steps: 15 },
166
+ "brook-healing": { color: "#ec4899", temperature: 0.1, steps: 20 },
167
+ "skeptic-verifier": { color: "#64748b", temperature: 0.1, permission: { edit: "deny" }, steps: 12 },
168
+ "eval-runner": { color: "#14b8a6", temperature: 0.2, steps: 15 },
169
+ "resume-coordinator": { color: "#d97706", temperature: 0.2, steps: 10 },
170
+ "memory-keeper": { color: "#d946ef", temperature: 0.2, steps: 8 }
171
+ };
172
+ function agentFrontmatter(name, description) {
173
+ const crew = CREW[name];
174
+ const lines = [`description: ${description}`, `mode: all`];
175
+ if (crew) {
176
+ lines.push(`color: '${crew.color}'`, `temperature: ${crew.temperature}`, `steps: ${crew.steps}`);
177
+ if (crew.permission) {
178
+ lines.push("permission:");
179
+ for (const [k, v] of Object.entries(crew.permission))
180
+ lines.push(` ${k}: ${v}`);
181
+ }
182
+ }
183
+ return lines.join(`
184
+ `);
185
+ }
155
186
  var target2 = {
156
187
  id: "opencode",
157
188
  label: "opencode",
@@ -167,10 +198,11 @@ var target2 = {
167
198
  };
168
199
  },
169
200
  transformAgent(data, body) {
170
- const fm = { name: data.name, description: data.description };
171
- if (data.tools)
172
- fm.tools = data.tools;
173
- return { relPath: `${data.name}.md`, text: stringifyFrontmatter(fm, body) };
201
+ const fm = agentFrontmatter(data.name, data.description);
202
+ return { relPath: `${data.name}.md`, text: `---
203
+ ${fm}
204
+ ---
205
+ ${body}` };
174
206
  },
175
207
  refsDir({ scope, projectDir, home }, skillName) {
176
208
  const root = scope === "global" ? join2(home, ".config", "opencode") : join2(projectDir, ".opencode");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ionivetech/mugiwara",
3
- "version": "0.5.1",
3
+ "version": "0.5.2",
4
4
  "description": "The Straw Hat crew of AI agents and skills: brainstorm, plan, execute, checkpoint, quality, gates, review, security, self-healing. Installs into Claude Code, opencode, Copilot, Gemini, Codex, Cursor, Kimi, pi, Windsurf, Cline, Kilo, Antigravity.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -3,6 +3,44 @@ import { join } from 'node:path';
3
3
  import { stringifyFrontmatter, type FrontmatterData } from '../frontmatter.ts';
4
4
  import type { Target } from '../installer.ts';
5
5
 
6
+ type CrewConfig = {
7
+ color: string;
8
+ temperature: number;
9
+ steps: number;
10
+ permission?: Record<string, string>;
11
+ };
12
+
13
+ const CREW: Record<string, CrewConfig> = {
14
+ 'using-mugiwara': { color: '#84cc16', temperature: 0.2, steps: 10 },
15
+ 'luffy-orchestrator': { color: '#ef4444', temperature: 0.2, steps: 15 },
16
+ 'usopp-brainstorm': { color: '#f59e0b', temperature: 0.6, steps: 15 },
17
+ 'nami-planner': { color: '#f97316', temperature: 0.2, steps: 15 },
18
+ 'zoro-execution': { color: '#22c55e', temperature: 0.1, steps: 30 },
19
+ 'chopper-checkpoint': { color: '#3b82f6', temperature: 0.1, permission: { edit: 'deny' }, steps: 15 },
20
+ 'sanji-quality': { color: '#a855f7', temperature: 0.1, permission: { edit: 'deny' }, steps: 10 },
21
+ 'franky-gates': { color: '#06b6d4', temperature: 0.1, permission: { edit: 'deny' }, steps: 10 },
22
+ 'robin-reviewer': { color: '#8b5cf6', temperature: 0.2, permission: { edit: 'deny' }, steps: 15 },
23
+ 'jinbe-security': { color: '#6366f1', temperature: 0.2, permission: { edit: 'deny' }, steps: 15 },
24
+ 'brook-healing': { color: '#ec4899', temperature: 0.1, steps: 20 },
25
+ 'skeptic-verifier': { color: '#64748b', temperature: 0.1, permission: { edit: 'deny' }, steps: 12 },
26
+ 'eval-runner': { color: '#14b8a6', temperature: 0.2, steps: 15 },
27
+ 'resume-coordinator': { color: '#d97706', temperature: 0.2, steps: 10 },
28
+ 'memory-keeper': { color: '#d946ef', temperature: 0.2, steps: 8 },
29
+ };
30
+
31
+ function agentFrontmatter(name: string, description: string) {
32
+ const crew = CREW[name];
33
+ const lines = [`description: ${description}`, `mode: all`];
34
+ if (crew) {
35
+ lines.push(`color: '${crew.color}'`, `temperature: ${crew.temperature}`, `steps: ${crew.steps}`);
36
+ if (crew.permission) {
37
+ lines.push('permission:');
38
+ for (const [k, v] of Object.entries(crew.permission)) lines.push(` ${k}: ${v}`);
39
+ }
40
+ }
41
+ return lines.join('\n');
42
+ }
43
+
6
44
  export const target: Target = {
7
45
  id: 'opencode',
8
46
  label: 'opencode',
@@ -18,9 +56,8 @@ export const target: Target = {
18
56
  };
19
57
  },
20
58
  transformAgent(data: FrontmatterData, body: string) {
21
- const fm: FrontmatterData = { name: data.name, description: data.description };
22
- if (data.tools) fm.tools = data.tools;
23
- return { relPath: `${data.name}.md`, text: stringifyFrontmatter(fm, body) };
59
+ const fm = agentFrontmatter(data.name, data.description);
60
+ return { relPath: `${data.name}.md`, text: `---\n${fm}\n---\n${body}` };
24
61
  },
25
62
  refsDir({ scope, projectDir, home }, skillName: string) {
26
63
  const root = scope === 'global' ? join(home, '.config', 'opencode') : join(projectDir, '.opencode');