@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.
- package/.claude-plugin/marketplace.json +3 -3
- package/.claude-plugin/plugin.json +4 -3
- package/.codex-plugin/plugin.json +2 -2
- package/.cursor-plugin/plugin.json +2 -2
- package/.kimi-plugin/plugin.json +2 -2
- package/.opencode/commands/mugiwara-continue.md +16 -0
- package/.opencode/commands/mugiwara-execute.md +6 -4
- package/.opencode/commands/mugiwara-heal.md +6 -4
- package/.opencode/commands/mugiwara-plan.md +6 -4
- package/.opencode/commands/mugiwara-review.md +6 -4
- package/.opencode/commands/mugiwara-security.md +6 -4
- package/.opencode/commands/mugiwara-ship.md +6 -4
- package/.opencode/commands/mugiwara.md +4 -2
- package/.opencode/commands/using-mugiwara.md +7 -13
- package/.opencode/plugins/mugiwara.mjs +18 -6
- package/AGENTS.md +2 -2
- package/GEMINI.md +1 -1
- package/README.md +240 -217
- package/content/agents/brook-healing.md +17 -3
- package/content/agents/chopper-checkpoint.md +17 -3
- package/content/agents/eval-runner.md +17 -2
- package/content/agents/franky-gates.md +19 -5
- package/content/agents/jinbe-security.md +19 -3
- package/content/agents/luffy-orchestrator.md +6 -3
- package/content/agents/memory-keeper.md +15 -0
- package/content/agents/nami-planner.md +21 -6
- package/content/agents/onboarding-guide.md +145 -0
- package/content/agents/resume-coordinator.md +21 -5
- package/content/agents/robin-reviewer.md +18 -3
- package/content/agents/sanji-quality.md +19 -4
- package/content/agents/skeptic-verifier.md +18 -3
- package/content/agents/usopp-brainstorm.md +17 -3
- package/content/agents/zoro-execution.md +19 -5
- package/content/skills/mugiwara-backend/SKILL.md +1 -1
- package/content/skills/mugiwara-brainstorm/SKILL.md +5 -1
- package/content/skills/mugiwara-checkpoint/SKILL.md +2 -2
- package/content/skills/mugiwara-contract-first/SKILL.md +2 -36
- package/content/skills/mugiwara-contract-first/references/process.md +37 -0
- package/content/skills/mugiwara-execution/SKILL.md +30 -13
- package/content/skills/mugiwara-execution/references/resume-batching.md +32 -0
- package/content/skills/mugiwara-frontend/SKILL.md +1 -1
- package/content/skills/mugiwara-gates/SKILL.md +32 -30
- package/content/skills/mugiwara-healing/SKILL.md +1 -1
- package/content/skills/mugiwara-orchestration/SKILL.md +41 -25
- package/content/skills/mugiwara-orchestration/references/delegation-pillars.md +40 -0
- package/content/skills/mugiwara-orchestration/references/triage-escalation.md +96 -0
- package/content/skills/mugiwara-planning/SKILL.md +23 -27
- package/content/skills/mugiwara-planning/references/plan-template.md +42 -0
- package/content/skills/mugiwara-pr/SKILL.md +2 -2
- package/content/skills/mugiwara-quality/SKILL.md +10 -6
- package/content/skills/mugiwara-resume/SKILL.md +7 -2
- package/content/skills/mugiwara-review/SKILL.md +20 -1
- package/content/skills/mugiwara-review/references/code-attributes.md +38 -0
- package/content/skills/mugiwara-root-cause/SKILL.md +3 -30
- package/content/skills/mugiwara-root-cause/references/process.md +35 -0
- package/content/skills/mugiwara-security/SKILL.md +17 -32
- package/content/skills/mugiwara-security/references/owasp-top10.md +12 -0
- package/content/skills/mugiwara-security/references/rationalizations.md +8 -0
- package/content/skills/mugiwara-ship/SKILL.md +5 -4
- package/content/skills/mugiwara-workflow/SKILL.md +74 -77
- package/content/skills/mugiwara-workflow/references/workspace-layout.md +50 -0
- package/content/skills/using-mugiwara/SKILL.md +8 -19
- package/dist/mugiwara.js +206 -87
- package/gemini-extension.json +1 -1
- package/hooks/session-start.ts +1 -1
- package/package.json +12 -5
- package/plugin.json +2 -2
- package/references/multi-actor.md +1 -1
- package/scripts/evidence.sh +13 -6
- package/scripts/gate-selftest.ts +266 -0
- package/scripts/initiative.ts +248 -0
- package/scripts/lane.sh +15 -0
- package/scripts/mission-report.sh +141 -76
- package/scripts/onboard.ts +292 -0
- package/scripts/release-notes.ts +42 -13
- package/scripts/retrieval-eval.ts +1 -2
- package/scripts/run-evals.ts +1 -1
- package/scripts/savepoint.sh +97 -50
- package/scripts/validate-content.ts +84 -7
- package/scripts/verify-install.ts +72 -0
- package/src/args.ts +1 -1
- package/src/cli.ts +49 -22
- package/src/frontmatter.ts +3 -3
- package/src/installer.ts +44 -15
- package/src/mission.ts +7 -5
- package/src/targets/claude.ts +20 -3
- package/src/targets/generic.ts +1 -1
- package/src/targets/opencode.ts +53 -11
- package/docs/adoption-guide.md +0 -72
- package/docs/agent-anatomy.md +0 -72
- package/docs/agents.md +0 -53
- package/docs/audit-trail.md +0 -65
- package/docs/claude-setup.md +0 -43
- package/docs/codex-setup.md +0 -26
- package/docs/comparison.md +0 -58
- package/docs/compliance-matrix.md +0 -81
- package/docs/config.md +0 -55
- package/docs/copilot-setup.md +0 -29
- package/docs/cost.md +0 -45
- package/docs/cursor-setup.md +0 -25
- package/docs/developer-onboarding.md +0 -89
- package/docs/enforcement.md +0 -35
- package/docs/execution-model.md +0 -92
- package/docs/gemini-setup.md +0 -27
- package/docs/getting-started.md +0 -158
- package/docs/git-strategy.md +0 -62
- package/docs/harness-matrix.md +0 -41
- package/docs/index.md +0 -56
- package/docs/install-antigravity.md +0 -45
- package/docs/install-claude.md +0 -75
- package/docs/install-cli.md +0 -103
- package/docs/install-codex.md +0 -44
- package/docs/install-copilot.md +0 -45
- package/docs/install-cursor.md +0 -45
- package/docs/install-gemini.md +0 -44
- package/docs/install-kimi.md +0 -45
- package/docs/install-opencode.md +0 -129
- package/docs/install-pi.md +0 -46
- package/docs/install.md +0 -53
- package/docs/lanes.md +0 -82
- package/docs/modes.md +0 -74
- package/docs/opencode-setup.md +0 -54
- package/docs/pr-summary.md +0 -54
- package/docs/rule-based-setup.md +0 -31
- package/docs/skill-anatomy.md +0 -71
- package/docs/skills.md +0 -55
- package/docs/troubleshooting.md +0 -91
- package/docs/windsurf-setup.md +0 -18
- package/docs/workflow.md +0 -89
- package/evals/cases/_no-skill.json +0 -16
- package/evals/cases/adversarial-pressure-fake-pass.json +0 -25
- package/evals/cases/adversarial-pressure-skip-review.json +0 -25
- package/evals/cases/lane-exploratory-vague.json +0 -24
- package/evals/cases/lane-sensitivity-payment.json +0 -24
- package/evals/cases/positive-refactor-existing-tests.json +0 -25
- package/evals/cases/positive-resume-mid-mission.json +0 -24
- package/evals/cases/routing-agent-security.json +0 -25
- package/evals/cases/routing-auth-feature.json +0 -26
- package/evals/cases/routing-backend.json +0 -25
- package/evals/cases/routing-bug-one-file.json +0 -26
- package/evals/cases/routing-claim-audit.json +0 -25
- package/evals/cases/routing-context-budget.json +0 -25
- package/evals/cases/routing-contract-first.json +0 -25
- package/evals/cases/routing-execution.json +0 -25
- package/evals/cases/routing-frontend.json +0 -26
- package/evals/cases/routing-gates.json +0 -25
- package/evals/cases/routing-git.json +0 -25
- package/evals/cases/routing-healing.json +0 -25
- package/evals/cases/routing-lessons.json +0 -25
- package/evals/cases/routing-orchestration.json +0 -25
- package/evals/cases/routing-planning.json +0 -26
- package/evals/cases/routing-pr.json +0 -25
- package/evals/cases/routing-quality.json +0 -25
- package/evals/cases/routing-ship.json +0 -26
- package/evals/cases/routing-sunset.json +0 -25
- package/evals/cases/routing-using-mugiwara.json +0 -25
- package/evals/cases/routing-workflow.json +0 -25
- package/evals/floor.json +0 -6
package/dist/mugiwara.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/cli.ts
|
|
4
|
-
import { existsSync as
|
|
4
|
+
import { existsSync as existsSync7, readdirSync as readdirSync5, rmSync as rmSync3 } from "node:fs";
|
|
5
5
|
import { homedir as homedir2 } from "node:os";
|
|
6
|
-
import { resolve } from "node:path";
|
|
7
|
-
import {
|
|
6
|
+
import { join as join8, resolve } from "node:path";
|
|
7
|
+
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
8
8
|
|
|
9
9
|
// src/args.ts
|
|
10
10
|
var VALUE_FLAGS = { "--project": "project", "--target": "target" };
|
|
@@ -15,6 +15,7 @@ var BOOL_FLAGS = {
|
|
|
15
15
|
"--force": "force",
|
|
16
16
|
"--dry-run": "dryRun",
|
|
17
17
|
"--keep-logs": "keepLogs",
|
|
18
|
+
"--check": "check",
|
|
18
19
|
"--help": "help",
|
|
19
20
|
"-h": "help",
|
|
20
21
|
"--version": "version",
|
|
@@ -80,7 +81,7 @@ async function confirm(rl, question) {
|
|
|
80
81
|
}
|
|
81
82
|
|
|
82
83
|
// src/targets/claude.ts
|
|
83
|
-
import { existsSync, mkdirSync, copyFileSync } from "node:fs";
|
|
84
|
+
import { existsSync, mkdirSync, copyFileSync, chmodSync, readdirSync } from "node:fs";
|
|
84
85
|
import { dirname, join } from "node:path";
|
|
85
86
|
import { fileURLToPath } from "node:url";
|
|
86
87
|
|
|
@@ -93,10 +94,10 @@ function parseFrontmatter(text) {
|
|
|
93
94
|
for (const line of m[1].split(/\r?\n/)) {
|
|
94
95
|
if (!line.trim())
|
|
95
96
|
continue;
|
|
96
|
-
const i = line.indexOf(":");
|
|
97
|
+
const i = line.indexOf(": ");
|
|
97
98
|
if (i === -1)
|
|
98
|
-
throw new Error(`Bad frontmatter line: ${line}`);
|
|
99
|
-
data[line.slice(0, i).trim()] = line.slice(i +
|
|
99
|
+
throw new Error(`Bad frontmatter line (missing ': ' separator): ${line}`);
|
|
100
|
+
data[line.slice(0, i).trim()] = line.slice(i + 2).trim();
|
|
100
101
|
}
|
|
101
102
|
return { data, body: text.slice(m[0].length) };
|
|
102
103
|
}
|
|
@@ -112,10 +113,12 @@ ${body}`;
|
|
|
112
113
|
// src/targets/claude.ts
|
|
113
114
|
var here = dirname(fileURLToPath(import.meta.url));
|
|
114
115
|
var HOOK_SRC = join(here, "..", "..", "hooks", "session-start.ts");
|
|
116
|
+
var COMMANDS_SRC = join(here, "..", "..", ".claude", "commands");
|
|
115
117
|
var target = {
|
|
116
118
|
id: "claude",
|
|
117
119
|
label: "Claude Code",
|
|
118
120
|
native: true,
|
|
121
|
+
refPointerPrefix: "../",
|
|
119
122
|
paths({ scope, projectDir, home }) {
|
|
120
123
|
const root = scope === "global" ? join(home, ".claude") : join(projectDir, ".claude");
|
|
121
124
|
return { skillsDir: join(root, "skills"), agentsDir: join(root, "agents") };
|
|
@@ -139,44 +142,81 @@ var target = {
|
|
|
139
142
|
postInstall({ scope, projectDir, home, dryRun }) {
|
|
140
143
|
const root = scope === "global" ? join(home, ".claude") : join(projectDir, ".claude");
|
|
141
144
|
const hookFile = join(root, "hooks", "session-start.ts");
|
|
145
|
+
const written = [];
|
|
146
|
+
const notes = [];
|
|
142
147
|
if (dryRun)
|
|
143
148
|
return { written: [], notes: [] };
|
|
144
149
|
if (existsSync(HOOK_SRC) && !existsSync(hookFile)) {
|
|
145
150
|
mkdirSync(dirname(hookFile), { recursive: true });
|
|
146
151
|
copyFileSync(HOOK_SRC, hookFile);
|
|
147
|
-
|
|
152
|
+
chmodSync(hookFile, 493);
|
|
153
|
+
written.push(hookFile);
|
|
148
154
|
}
|
|
149
|
-
|
|
155
|
+
if (existsSync(COMMANDS_SRC)) {
|
|
156
|
+
const dstDir = join(root, "commands");
|
|
157
|
+
mkdirSync(dstDir, { recursive: true });
|
|
158
|
+
for (const f of readdirSync(COMMANDS_SRC)) {
|
|
159
|
+
if (!f.endsWith(".md"))
|
|
160
|
+
continue;
|
|
161
|
+
const src = join(COMMANDS_SRC, f);
|
|
162
|
+
const dst = join(dstDir, f);
|
|
163
|
+
if (!existsSync(dst)) {
|
|
164
|
+
copyFileSync(src, dst);
|
|
165
|
+
written.push(dst);
|
|
166
|
+
} else
|
|
167
|
+
notes.push(`existing command kept: ${dst}`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return { written, notes };
|
|
150
171
|
}
|
|
151
172
|
};
|
|
152
173
|
|
|
153
174
|
// src/targets/opencode.ts
|
|
154
|
-
import {
|
|
175
|
+
import { existsSync as existsSync2, readdirSync as readdirSync2, copyFileSync as copyFileSync2, mkdirSync as mkdirSync2 } from "node:fs";
|
|
176
|
+
import { dirname as dirname2, join as join2 } from "node:path";
|
|
177
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
178
|
+
var here2 = dirname2(fileURLToPath2(import.meta.url));
|
|
179
|
+
var COMMANDS_SRC2 = join2(here2, "..", "..", ".opencode", "commands");
|
|
155
180
|
var CREW = {
|
|
156
181
|
"luffy-orchestrator": { color: "#ef4444", temperature: 0.2, steps: 15 },
|
|
157
182
|
"usopp-brainstorm": { color: "#f59e0b", temperature: 0.6, steps: 15 },
|
|
158
183
|
"nami-planner": { color: "#f97316", temperature: 0.2, steps: 15 },
|
|
159
184
|
"zoro-execution": { color: "#22c55e", temperature: 0.1, steps: 30 },
|
|
160
|
-
"chopper-checkpoint": { color: "#3b82f6", temperature: 0.1,
|
|
161
|
-
"sanji-quality": { color: "#a855f7", temperature: 0.1,
|
|
162
|
-
"franky-gates": { color: "#06b6d4", temperature: 0.1,
|
|
163
|
-
"robin-reviewer": { color: "#8b5cf6", temperature: 0.2,
|
|
164
|
-
"jinbe-security": { color: "#6366f1", temperature: 0.2,
|
|
185
|
+
"chopper-checkpoint": { color: "#3b82f6", temperature: 0.1, steps: 15 },
|
|
186
|
+
"sanji-quality": { color: "#a855f7", temperature: 0.1, steps: 10 },
|
|
187
|
+
"franky-gates": { color: "#06b6d4", temperature: 0.1, steps: 10 },
|
|
188
|
+
"robin-reviewer": { color: "#8b5cf6", temperature: 0.2, steps: 15 },
|
|
189
|
+
"jinbe-security": { color: "#6366f1", temperature: 0.2, steps: 15 },
|
|
165
190
|
"brook-healing": { color: "#ec4899", temperature: 0.1, steps: 20 },
|
|
166
|
-
"skeptic-verifier": { color: "#64748b", temperature: 0.1,
|
|
191
|
+
"skeptic-verifier": { color: "#64748b", temperature: 0.1, steps: 12 },
|
|
167
192
|
"eval-runner": { color: "#14b8a6", temperature: 0.2, steps: 15 },
|
|
168
193
|
"resume-coordinator": { color: "#d97706", temperature: 0.2, steps: 10 },
|
|
169
194
|
"memory-keeper": { color: "#d946ef", temperature: 0.2, steps: 8 }
|
|
170
195
|
};
|
|
171
|
-
function
|
|
196
|
+
function permissionFromScope(scope) {
|
|
197
|
+
if (scope === "source")
|
|
198
|
+
return { edit: "allow" };
|
|
199
|
+
if (scope === "artifacts")
|
|
200
|
+
return { edit: { "*": "deny", ".mugiwara/**": "allow" } };
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
function agentFrontmatter(name, description, writeScope) {
|
|
172
204
|
const crew = CREW[name];
|
|
173
205
|
const lines = [`description: ${description}`, `mode: all`];
|
|
174
206
|
if (crew) {
|
|
175
207
|
lines.push(`color: '${crew.color}'`, `temperature: ${crew.temperature}`, `steps: ${crew.steps}`);
|
|
176
|
-
|
|
208
|
+
const perm = permissionFromScope(writeScope);
|
|
209
|
+
if (perm) {
|
|
177
210
|
lines.push("permission:");
|
|
178
|
-
for (const [k, v] of Object.entries(
|
|
179
|
-
|
|
211
|
+
for (const [k, v] of Object.entries(perm)) {
|
|
212
|
+
if (typeof v === "string") {
|
|
213
|
+
lines.push(` ${k}: ${v}`);
|
|
214
|
+
} else {
|
|
215
|
+
lines.push(` ${k}:`);
|
|
216
|
+
for (const [pk, pv] of Object.entries(v))
|
|
217
|
+
lines.push(` "${pk}": ${pv}`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
180
220
|
}
|
|
181
221
|
}
|
|
182
222
|
return lines.join(`
|
|
@@ -186,6 +226,7 @@ var target2 = {
|
|
|
186
226
|
id: "opencode",
|
|
187
227
|
label: "opencode",
|
|
188
228
|
native: true,
|
|
229
|
+
refPointerPrefix: "../",
|
|
189
230
|
paths({ scope, projectDir, home }) {
|
|
190
231
|
const root = scope === "global" ? join2(home, ".config", "opencode") : join2(projectDir, ".opencode");
|
|
191
232
|
return { skillsDir: join2(root, "skills"), agentsDir: join2(root, "agents") };
|
|
@@ -197,7 +238,8 @@ var target2 = {
|
|
|
197
238
|
};
|
|
198
239
|
},
|
|
199
240
|
transformAgent(data, body) {
|
|
200
|
-
const
|
|
241
|
+
const desc = data["internal-agent"] === "true" ? `[INTERNAL] ${data.description}` : data.description;
|
|
242
|
+
const fm = agentFrontmatter(data.name, desc, data["write-scope"]);
|
|
201
243
|
return { relPath: `${data.name}.md`, text: `---
|
|
202
244
|
${fm}
|
|
203
245
|
---
|
|
@@ -206,6 +248,25 @@ ${body}` };
|
|
|
206
248
|
refsDir({ scope, projectDir, home }, skillName) {
|
|
207
249
|
const root = scope === "global" ? join2(home, ".config", "opencode") : join2(projectDir, ".opencode");
|
|
208
250
|
return join2(root, "skills", skillName, "references");
|
|
251
|
+
},
|
|
252
|
+
postInstall({ scope, projectDir, home, dryRun }) {
|
|
253
|
+
const root = scope === "global" ? join2(home, ".config", "opencode") : join2(projectDir, ".opencode");
|
|
254
|
+
const dstDir = join2(root, "commands");
|
|
255
|
+
if (dryRun)
|
|
256
|
+
return { written: [], notes: [] };
|
|
257
|
+
if (!existsSync2(COMMANDS_SRC2))
|
|
258
|
+
return { written: [], notes: [] };
|
|
259
|
+
mkdirSync2(dstDir, { recursive: true });
|
|
260
|
+
const written = [];
|
|
261
|
+
for (const f of readdirSync2(COMMANDS_SRC2)) {
|
|
262
|
+
if (!f.endsWith(".md"))
|
|
263
|
+
continue;
|
|
264
|
+
const src = join2(COMMANDS_SRC2, f);
|
|
265
|
+
const dst = join2(dstDir, f);
|
|
266
|
+
copyFileSync2(src, dst);
|
|
267
|
+
written.push(dst);
|
|
268
|
+
}
|
|
269
|
+
return { written, notes: [] };
|
|
209
270
|
}
|
|
210
271
|
};
|
|
211
272
|
|
|
@@ -237,7 +298,7 @@ var target3 = {
|
|
|
237
298
|
};
|
|
238
299
|
|
|
239
300
|
// src/targets/generic.ts
|
|
240
|
-
import { existsSync as
|
|
301
|
+
import { existsSync as existsSync3, writeFileSync } from "node:fs";
|
|
241
302
|
import { join as join4 } from "node:path";
|
|
242
303
|
function makeGeneric(opts) {
|
|
243
304
|
const { id, label, rulesDir, bootstrapFile, bootstrapPointer, tier = bootstrapPointer ? 2 : 3 } = opts;
|
|
@@ -289,7 +350,10 @@ ${body}` };
|
|
|
289
350
|
|
|
290
351
|
> ${data.description}
|
|
291
352
|
|
|
292
|
-
Skills: ${data.skills ?? ""}. Read \`.mugiwara/refs/${data.name}.md\` when embodying this role
|
|
353
|
+
Skills: ${data.skills ?? ""}. Read \`.mugiwara/refs/${data.name}.md\` when embodying this role.
|
|
354
|
+
|
|
355
|
+
Only zoro-execution and brook-healing may modify source code.
|
|
356
|
+
Return your output to luffy-orchestrator; do not choose the next step.`
|
|
293
357
|
};
|
|
294
358
|
}
|
|
295
359
|
return { relPath: `agent-${data.name}.md`, text: `# Agent: ${data.name}
|
|
@@ -320,7 +384,7 @@ ${body}` };
|
|
|
320
384
|
const notes = [];
|
|
321
385
|
const written = [];
|
|
322
386
|
const file = join4(projectDir, bootstrapFile);
|
|
323
|
-
if (!
|
|
387
|
+
if (!existsSync3(file)) {
|
|
324
388
|
if (!dryRun)
|
|
325
389
|
writeFileSync(file, `${bootstrapPointer}
|
|
326
390
|
`);
|
|
@@ -397,39 +461,49 @@ var targets = { claude: target, opencode: target2, copilot: target3, gemini: tar
|
|
|
397
461
|
var TARGET_IDS = Object.keys(targets);
|
|
398
462
|
|
|
399
463
|
// src/installer.ts
|
|
400
|
-
import { existsSync as
|
|
401
|
-
import { dirname as
|
|
464
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync2, readdirSync as readdirSync3, writeFileSync as writeFileSync2, copyFileSync as copyFileSync3, rmSync } from "node:fs";
|
|
465
|
+
import { dirname as dirname3, join as join5 } from "node:path";
|
|
402
466
|
import { homedir } from "node:os";
|
|
403
|
-
|
|
404
|
-
var
|
|
467
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
468
|
+
var CONTENT_DIR = join5(dirname3(fileURLToPath3(import.meta.url)), "..", "content");
|
|
469
|
+
var pkg = JSON.parse(readFileSync2(join5(dirname3(fileURLToPath3(import.meta.url)), "..", "package.json"), "utf8"));
|
|
405
470
|
var VERSION = pkg.version;
|
|
406
471
|
function collectContent() {
|
|
407
|
-
const skillNames =
|
|
472
|
+
const skillNames = readdirSync3(join5(CONTENT_DIR, "skills"), { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => e.name);
|
|
408
473
|
const skills = skillNames.map((name) => {
|
|
409
474
|
const { data, body } = parseFrontmatter(readFileSync2(join5(CONTENT_DIR, "skills", name, "SKILL.md"), "utf8"));
|
|
410
475
|
return { name, data, body, refs: collectRefs(join5(CONTENT_DIR, "skills", name)) };
|
|
411
476
|
});
|
|
412
|
-
const agents =
|
|
477
|
+
const agents = readdirSync3(join5(CONTENT_DIR, "agents")).filter((f) => f.endsWith(".md")).map((f) => {
|
|
413
478
|
const { data, body } = parseFrontmatter(readFileSync2(join5(CONTENT_DIR, "agents", f), "utf8"));
|
|
414
|
-
return { name: f.replace(/\.md$/, ""), data, body, refs: [] };
|
|
479
|
+
return { name: f.replace(/\.md$/, ""), data, body, refs: [], internal: data.internal === "true" };
|
|
415
480
|
});
|
|
416
|
-
|
|
481
|
+
const sharedRefsDir = join5(dirname3(CONTENT_DIR), "references");
|
|
482
|
+
const sharedRefs = [];
|
|
483
|
+
if (existsSync4(sharedRefsDir)) {
|
|
484
|
+
for (const f of readdirSync3(sharedRefsDir)) {
|
|
485
|
+
if (!f.endsWith(".md"))
|
|
486
|
+
continue;
|
|
487
|
+
sharedRefs.push({ relPath: f, text: readFileSync2(join5(sharedRefsDir, f), "utf8") });
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
return { skills, agents, sharedRefs };
|
|
417
491
|
}
|
|
418
492
|
function collectRefs(skillDir) {
|
|
419
493
|
const refsDir = join5(skillDir, "references");
|
|
420
|
-
if (!
|
|
494
|
+
if (!existsSync4(refsDir))
|
|
421
495
|
return [];
|
|
422
|
-
return
|
|
496
|
+
return readdirSync3(refsDir, { recursive: true }).map((f) => String(f)).filter((f) => f.endsWith(".md")).map((rel) => ({ relPath: rel, text: readFileSync2(join5(refsDir, rel), "utf8") }));
|
|
423
497
|
}
|
|
424
498
|
function installTo(target10, opts) {
|
|
425
499
|
const { scope, projectDir, dryRun = false, force = false } = opts;
|
|
426
500
|
const home = opts.home ?? homedir();
|
|
427
|
-
const { skills, agents } = collectContent();
|
|
501
|
+
const { skills, agents, sharedRefs } = collectContent();
|
|
428
502
|
const dirs = target10.paths({ scope, projectDir, home });
|
|
429
503
|
const backupRoot = join5(scope === "global" ? home : projectDir, ".mugiwara");
|
|
430
504
|
const result = { written: [], skipped: [], backedUp: [], notes: [] };
|
|
431
505
|
const writeOne = (absPath, text) => {
|
|
432
|
-
if (
|
|
506
|
+
if (existsSync4(absPath)) {
|
|
433
507
|
if (readFileSync2(absPath, "utf8") === text) {
|
|
434
508
|
result.skipped.push(absPath);
|
|
435
509
|
return;
|
|
@@ -440,27 +514,39 @@ function installTo(target10, opts) {
|
|
|
440
514
|
return;
|
|
441
515
|
}
|
|
442
516
|
const ts = new Date().toISOString().replace(/[:.]/g, "-");
|
|
443
|
-
const
|
|
517
|
+
const fileName = absPath.replace(/[^a-zA-Z0-9]+/g, "_");
|
|
518
|
+
const backupDir = join5(backupRoot, "backup", `${ts}-${target10.id}`);
|
|
519
|
+
const backupFile = join5(backupDir, fileName);
|
|
444
520
|
if (!dryRun) {
|
|
445
|
-
|
|
446
|
-
|
|
521
|
+
mkdirSync3(backupDir, { recursive: true });
|
|
522
|
+
copyFileSync3(absPath, backupFile);
|
|
447
523
|
}
|
|
448
524
|
result.backedUp.push(absPath);
|
|
449
525
|
}
|
|
450
526
|
if (!dryRun) {
|
|
451
|
-
|
|
527
|
+
mkdirSync3(dirname3(absPath), { recursive: true });
|
|
452
528
|
writeFileSync2(absPath, text);
|
|
453
529
|
}
|
|
454
530
|
result.written.push(absPath);
|
|
455
531
|
};
|
|
456
532
|
for (const s of skills) {
|
|
457
533
|
const out = target10.transformSkill(s.data, s.body);
|
|
458
|
-
if (out)
|
|
459
|
-
|
|
534
|
+
if (out) {
|
|
535
|
+
let text = out.text;
|
|
536
|
+
if (target10.refPointerPrefix !== undefined && target10.refPointerPrefix !== "") {
|
|
537
|
+
text = text.replace(/`_shared\/references\//g, "`" + target10.refPointerPrefix + "_shared/references/");
|
|
538
|
+
}
|
|
539
|
+
writeOne(join5(dirs.skillsDir, out.relPath), text);
|
|
540
|
+
}
|
|
460
541
|
if (target10.transformSkillFull) {
|
|
461
542
|
const full = target10.transformSkillFull(s.data, s.body);
|
|
462
|
-
if (full && target10.refsDir)
|
|
463
|
-
|
|
543
|
+
if (full && target10.refsDir) {
|
|
544
|
+
let text = full.text;
|
|
545
|
+
if (target10.refPointerPrefix !== undefined && target10.refPointerPrefix !== "") {
|
|
546
|
+
text = text.replace(/`_shared\/references\//g, "`" + target10.refPointerPrefix + "_shared/references/");
|
|
547
|
+
}
|
|
548
|
+
writeOne(join5(target10.refsDir({ scope, projectDir, home }, s.name), full.relPath), text);
|
|
549
|
+
}
|
|
464
550
|
}
|
|
465
551
|
if (s.refs.length && target10.refsDir) {
|
|
466
552
|
const refsRoot = target10.refsDir({ scope, projectDir, home }, s.name);
|
|
@@ -469,7 +555,7 @@ function installTo(target10, opts) {
|
|
|
469
555
|
}
|
|
470
556
|
}
|
|
471
557
|
for (const a of agents) {
|
|
472
|
-
const out = target10.transformAgent(a.data, a.body);
|
|
558
|
+
const out = target10.transformAgent({ ...a.data, ...a.internal ? { "internal-agent": "true" } : {} }, a.body);
|
|
473
559
|
if (out)
|
|
474
560
|
writeOne(join5(dirs.agentsDir, out.relPath), out.text);
|
|
475
561
|
if (target10.transformAgentFull) {
|
|
@@ -478,6 +564,11 @@ function installTo(target10, opts) {
|
|
|
478
564
|
writeOne(join5(target10.refsDir({ scope, projectDir, home }, a.name), full.relPath), full.text);
|
|
479
565
|
}
|
|
480
566
|
}
|
|
567
|
+
if (sharedRefs.length) {
|
|
568
|
+
const sharedRoot = join5(dirs.skillsDir, "_shared", "references");
|
|
569
|
+
for (const r of sharedRefs)
|
|
570
|
+
writeOne(join5(sharedRoot, r.relPath), r.text);
|
|
571
|
+
}
|
|
481
572
|
if (target10.postInstall) {
|
|
482
573
|
const post = target10.postInstall({ scope, projectDir, home, dryRun, files: result.written });
|
|
483
574
|
result.written.push(...post.written);
|
|
@@ -488,7 +579,7 @@ function installTo(target10, opts) {
|
|
|
488
579
|
function removeInstalled(manifest, { dryRun = false } = {}) {
|
|
489
580
|
const removed = [];
|
|
490
581
|
for (const f of manifest.files) {
|
|
491
|
-
if (
|
|
582
|
+
if (existsSync4(f)) {
|
|
492
583
|
if (!dryRun)
|
|
493
584
|
rmSync(f);
|
|
494
585
|
removed.push(f);
|
|
@@ -496,13 +587,12 @@ function removeInstalled(manifest, { dryRun = false } = {}) {
|
|
|
496
587
|
}
|
|
497
588
|
if (!dryRun) {
|
|
498
589
|
for (const f of manifest.files) {
|
|
499
|
-
let d =
|
|
500
|
-
while (
|
|
501
|
-
|
|
502
|
-
const parent = dirname2(d);
|
|
503
|
-
if (parent === d)
|
|
590
|
+
let d = dirname3(f);
|
|
591
|
+
while (existsSync4(d) && readdirSync3(d).length === 0) {
|
|
592
|
+
if (d.endsWith("/.mugiwara") || d === dirname3(d))
|
|
504
593
|
break;
|
|
505
|
-
d
|
|
594
|
+
rmSync(d, { recursive: true, force: true });
|
|
595
|
+
d = dirname3(d);
|
|
506
596
|
}
|
|
507
597
|
}
|
|
508
598
|
}
|
|
@@ -510,26 +600,26 @@ function removeInstalled(manifest, { dryRun = false } = {}) {
|
|
|
510
600
|
}
|
|
511
601
|
|
|
512
602
|
// src/manifest.ts
|
|
513
|
-
import { existsSync as
|
|
514
|
-
import { dirname as
|
|
603
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync4, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "node:fs";
|
|
604
|
+
import { dirname as dirname4, join as join6 } from "node:path";
|
|
515
605
|
function manifestPath({ scope, projectDir, home }) {
|
|
516
606
|
return scope === "global" ? join6(home, ".mugiwara", "manifest.json") : join6(projectDir, ".mugiwara", "manifest.json");
|
|
517
607
|
}
|
|
518
608
|
function readManifest(file) {
|
|
519
|
-
return
|
|
609
|
+
return existsSync5(file) ? JSON.parse(readFileSync3(file, "utf8")) : null;
|
|
520
610
|
}
|
|
521
611
|
function writeManifest(file, data) {
|
|
522
|
-
|
|
612
|
+
mkdirSync4(dirname4(file), { recursive: true });
|
|
523
613
|
writeFileSync3(file, JSON.stringify(data, null, 2) + `
|
|
524
614
|
`);
|
|
525
615
|
}
|
|
526
616
|
|
|
527
617
|
// src/mission.ts
|
|
528
|
-
import { existsSync as
|
|
618
|
+
import { existsSync as existsSync6, rmSync as rmSync2, readFileSync as readFileSync4, readdirSync as readdirSync4 } from "node:fs";
|
|
529
619
|
import { join as join7 } from "node:path";
|
|
530
620
|
function activeActor(projectDir) {
|
|
531
621
|
const stateFile = join7(projectDir, ".mugiwara", "state.json");
|
|
532
|
-
if (!
|
|
622
|
+
if (!existsSync6(stateFile))
|
|
533
623
|
return null;
|
|
534
624
|
try {
|
|
535
625
|
const state = JSON.parse(readFileSync4(stateFile, "utf8"));
|
|
@@ -540,7 +630,7 @@ function activeActor(projectDir) {
|
|
|
540
630
|
}
|
|
541
631
|
function resetMission(projectDir, keepLogs, force) {
|
|
542
632
|
const root = join7(projectDir, ".mugiwara");
|
|
543
|
-
if (!
|
|
633
|
+
if (!existsSync6(root))
|
|
544
634
|
return { removed: [], kept: [] };
|
|
545
635
|
if (!force) {
|
|
546
636
|
const actor = activeActor(projectDir);
|
|
@@ -552,29 +642,31 @@ function resetMission(projectDir, keepLogs, force) {
|
|
|
552
642
|
const kept = [];
|
|
553
643
|
for (const dir of ["spec", "plans", "results", "review", "issues", "reports"]) {
|
|
554
644
|
const p = join7(root, dir);
|
|
555
|
-
if (
|
|
645
|
+
if (existsSync6(p)) {
|
|
556
646
|
rmSync2(p, { recursive: true, force: true });
|
|
557
647
|
removed.push(dir);
|
|
558
648
|
}
|
|
559
649
|
}
|
|
560
|
-
for (const f of
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
650
|
+
for (const f of readdirSync4(root)) {
|
|
651
|
+
if (/^state(-.+)?\.json$/.test(f)) {
|
|
652
|
+
const p = join7(root, f);
|
|
653
|
+
if (existsSync6(p)) {
|
|
654
|
+
rmSync2(p);
|
|
655
|
+
removed.push(f);
|
|
656
|
+
}
|
|
565
657
|
}
|
|
566
658
|
}
|
|
567
659
|
if (!keepLogs) {
|
|
568
660
|
const p = join7(root, "logs");
|
|
569
|
-
if (
|
|
661
|
+
if (existsSync6(p)) {
|
|
570
662
|
rmSync2(p, { recursive: true, force: true });
|
|
571
663
|
removed.push("logs");
|
|
572
664
|
}
|
|
573
|
-
} else if (
|
|
665
|
+
} else if (existsSync6(join7(root, "logs"))) {
|
|
574
666
|
kept.push("logs");
|
|
575
667
|
}
|
|
576
668
|
for (const f of ["config", "manifest.json", "backup"]) {
|
|
577
|
-
if (
|
|
669
|
+
if (existsSync6(join7(root, f)))
|
|
578
670
|
kept.push(f);
|
|
579
671
|
}
|
|
580
672
|
return { removed, kept };
|
|
@@ -623,25 +715,31 @@ function resetCmd(flags) {
|
|
|
623
715
|
}
|
|
624
716
|
async function resolveOptions(flags) {
|
|
625
717
|
const interactive = !flag(flags.yes);
|
|
718
|
+
if (interactive && !process.stdin.isTTY) {
|
|
719
|
+
throw new Error("Not a terminal. Run with --yes and --global or --project <dir> --target <ids|all>");
|
|
720
|
+
}
|
|
626
721
|
const rl = interactive ? createRl() : null;
|
|
627
722
|
try {
|
|
628
723
|
let scope = flag(flags.global) ? "global" : str(flags.project) ? "project" : null;
|
|
629
724
|
if (!scope) {
|
|
630
|
-
if (!interactive)
|
|
631
|
-
|
|
632
|
-
|
|
725
|
+
if (!interactive) {
|
|
726
|
+
scope = "project";
|
|
727
|
+
} else
|
|
728
|
+
scope = await choose(rl, "Install scope?", ["global (user-wide)", "project (this repo)"]) === 0 ? "global" : "project";
|
|
633
729
|
}
|
|
634
730
|
const projectDir = resolve(str(flags.project) ?? process.cwd());
|
|
635
|
-
if (scope === "project" && !
|
|
731
|
+
if (scope === "project" && !existsSync7(projectDir))
|
|
636
732
|
throw new Error(`Project dir not found: ${projectDir}`);
|
|
637
733
|
let targetIds = str(flags.target)?.split(",").map((s) => s.trim()) ?? null;
|
|
638
734
|
if (targetIds && targetIds.includes("all"))
|
|
639
735
|
targetIds = [...TARGET_IDS];
|
|
640
736
|
if (!targetIds) {
|
|
641
|
-
if (!interactive)
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
737
|
+
if (!interactive) {
|
|
738
|
+
targetIds = [...TARGET_IDS];
|
|
739
|
+
} else {
|
|
740
|
+
const idx = await multiChoose(rl, "Target AI agents?", ["all targets", ...TARGET_IDS]);
|
|
741
|
+
targetIds = idx.includes(0) ? [...TARGET_IDS] : idx.map((i) => TARGET_IDS[i - 1]);
|
|
742
|
+
}
|
|
645
743
|
}
|
|
646
744
|
for (const id of targetIds) {
|
|
647
745
|
if (!targets[id])
|
|
@@ -701,6 +799,14 @@ async function uninstall(flags) {
|
|
|
701
799
|
const file = manifestPath({ scope, projectDir, home });
|
|
702
800
|
const manifest = readManifest(file);
|
|
703
801
|
if (!manifest) {
|
|
802
|
+
if (scope === "project") {
|
|
803
|
+
const globalFile = manifestPath({ scope: "global", projectDir, home });
|
|
804
|
+
if (existsSync7(globalFile)) {
|
|
805
|
+
console.log(`No project manifest found, but a global install exists. Try:
|
|
806
|
+
mugiwara uninstall --global`);
|
|
807
|
+
return;
|
|
808
|
+
}
|
|
809
|
+
}
|
|
704
810
|
console.log("Nothing installed (no manifest found).");
|
|
705
811
|
return;
|
|
706
812
|
}
|
|
@@ -715,8 +821,20 @@ async function uninstall(flags) {
|
|
|
715
821
|
}
|
|
716
822
|
}
|
|
717
823
|
const removed = removeInstalled(manifest, { dryRun: flag(flags.dryRun) });
|
|
718
|
-
if (!flag(flags.dryRun))
|
|
824
|
+
if (!flag(flags.dryRun)) {
|
|
719
825
|
rmSync3(file);
|
|
826
|
+
const mugiDir = join8(scope === "global" ? home : projectDir, ".mugiwara");
|
|
827
|
+
if (existsSync7(mugiDir) && readdirSync5(mugiDir).length === 0) {
|
|
828
|
+
rmSync3(mugiDir, { recursive: true, force: true });
|
|
829
|
+
}
|
|
830
|
+
if (manifest.targets.includes("opencode")) {
|
|
831
|
+
const opencodeCache = join8(home, ".cache", "opencode", "packages", "@ionivetech");
|
|
832
|
+
if (existsSync7(opencodeCache)) {
|
|
833
|
+
rmSync3(opencodeCache, { recursive: true, force: true });
|
|
834
|
+
console.log(" cleared opencode npm cache (stale plugin versions)");
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
}
|
|
720
838
|
console.log(`OK removed ${removed.length} files`);
|
|
721
839
|
}
|
|
722
840
|
function list(flags) {
|
|
@@ -731,7 +849,12 @@ function list(flags) {
|
|
|
731
849
|
if (!m)
|
|
732
850
|
continue;
|
|
733
851
|
found = true;
|
|
734
|
-
|
|
852
|
+
if (flag(flags.check)) {
|
|
853
|
+
const missing = m.files.filter((f) => !existsSync7(f));
|
|
854
|
+
console.log(`${label}: v${m.version} targets=${m.targets.join(",")} files=${m.files.length} missing=${missing.length} installed=${m.installedAt}`);
|
|
855
|
+
} else {
|
|
856
|
+
console.log(`${label}: v${m.version} targets=${m.targets.join(",")} files=${m.files.length} installed=${m.installedAt}`);
|
|
857
|
+
}
|
|
735
858
|
}
|
|
736
859
|
if (!found)
|
|
737
860
|
console.log("No mugiwara installation found.");
|
|
@@ -740,10 +863,11 @@ function help() {
|
|
|
740
863
|
console.log(`mugiwara ${VERSION} — the Straw Hat crew for AI agents
|
|
741
864
|
|
|
742
865
|
Usage:
|
|
743
|
-
mugiwara [install] install the crew (
|
|
866
|
+
mugiwara [install] install the crew (wizard; with --yes uses project + all)
|
|
744
867
|
mugiwara update replace existing files (backs up differences first)
|
|
745
868
|
mugiwara uninstall remove installed files via manifest
|
|
746
869
|
mugiwara list show installations
|
|
870
|
+
mugiwara list --check health check: show installations + missing files
|
|
747
871
|
mugiwara reset wipe mission state (spec/plans/results/review/issues[/logs])
|
|
748
872
|
mugiwara --help this help
|
|
749
873
|
mugiwara --version print version
|
|
@@ -752,18 +876,13 @@ Flags:
|
|
|
752
876
|
--global user-wide install
|
|
753
877
|
--project <dir> project install (default: cwd)
|
|
754
878
|
--target <ids|all> comma-separated: ${TARGET_IDS.join(", ")}
|
|
755
|
-
--yes, -y non-interactive (
|
|
879
|
+
--yes, -y non-interactive (defaults: project, all targets)
|
|
756
880
|
--force overwrite differing files (with backup)
|
|
757
881
|
--dry-run print actions without writing
|
|
882
|
+
--check with list: report missing files (health check)
|
|
758
883
|
--keep-logs with reset: keep .mugiwara/logs (lessons ledger survives)`);
|
|
759
884
|
}
|
|
760
|
-
var
|
|
761
|
-
if (entry !== undefined) {
|
|
762
|
-
try {
|
|
763
|
-
entry = realpathSync(entry);
|
|
764
|
-
} catch {}
|
|
765
|
-
}
|
|
766
|
-
var isMain = entry !== undefined && import.meta.url === pathToFileURL(entry).href;
|
|
885
|
+
var isMain = process.argv[1] !== undefined && fileURLToPath4(import.meta.url) === resolve(process.argv[1]);
|
|
767
886
|
if (isMain) {
|
|
768
887
|
run(process.argv.slice(2)).catch((err) => {
|
|
769
888
|
console.error(`mugiwara: ${err.message}`);
|
package/gemini-extension.json
CHANGED
package/hooks/session-start.ts
CHANGED
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
console.log(
|
|
4
4
|
JSON.stringify({
|
|
5
5
|
additionalContext:
|
|
6
|
-
"Mugiwara crew
|
|
6
|
+
"Mugiwara crew active by default. Say \\`mugiwara off\\` for a request and the crew stands down (Luffy acknowledges, records it in the decision log). Before ANY task — load \\`mugiwara-orchestration\\` skill as gatekeeper. NEVER execute, answer, or make changes without Wave 0 triage. Classification overhead <15 seconds — cheaper than an incorrect fix. Lane 0 for trivial work (single-file/<20 LOC) skips pipeline; Lane 1+ follows full pipeline. Mode: guided / semi / auto (see .mugiwara/config). Switch with \\`/mugiwara <mode>\\` — applies from the next wave. See skills/mugiwara-workflow."
|
|
7
7
|
})
|
|
8
8
|
);
|
package/package.json
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ionivetech/mugiwara",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
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
|
+
"homepage": "https://github.com/ionivetech/mugiwara#readme",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/ionivetech/mugiwara.git"
|
|
9
|
+
},
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/ionivetech/mugiwara/issues"
|
|
12
|
+
},
|
|
5
13
|
"type": "module",
|
|
6
14
|
"license": "MIT",
|
|
7
15
|
"main": "./.opencode/plugins/mugiwara.mjs",
|
|
@@ -17,9 +25,7 @@
|
|
|
17
25
|
"dist",
|
|
18
26
|
"src",
|
|
19
27
|
"content",
|
|
20
|
-
"docs",
|
|
21
28
|
"references",
|
|
22
|
-
"evals",
|
|
23
29
|
"scripts",
|
|
24
30
|
".opencode",
|
|
25
31
|
".claude-plugin",
|
|
@@ -51,9 +57,10 @@
|
|
|
51
57
|
"validate": "bun scripts/validate-content.ts --check-manifest --check-docs",
|
|
52
58
|
"evals": "bun scripts/run-evals.ts",
|
|
53
59
|
"retrieval-eval": "bun scripts/retrieval-eval.ts",
|
|
60
|
+
"verify-install": "bun scripts/verify-install.ts",
|
|
54
61
|
"sync-version": "bun scripts/sync-version.ts",
|
|
55
|
-
"gate": "bun run typecheck && bun run test && bun run build && bun scripts/validate-content.ts --check-manifest --check-docs && bun run verify-pack && bun scripts/run-evals.ts && bun scripts/retrieval-eval.ts",
|
|
56
|
-
"verify-pack": "npm pack --dry-run 2>&1 |
|
|
62
|
+
"gate": "bun run typecheck && bun run test && bun run build && bun scripts/validate-content.ts --check-manifest --check-docs && bun run verify-pack && bun scripts/run-evals.ts && bun scripts/retrieval-eval.ts && bun scripts/verify-install.ts",
|
|
63
|
+
"verify-pack": "npm pack --dry-run 2>&1 | node -e \"let s='';process.stdin.on('data',d=>s+=d);process.stdin.on('end',()=>{if(!s.includes('ionivetech-mugiwara')){console.error('npm pack failed');process.exit(1)};console.log('npm package clean')})\"",
|
|
57
64
|
"prepack": "bun run build && bun run sync-version"
|
|
58
65
|
},
|
|
59
66
|
"keywords": [
|