@ionivetech/mugiwara 0.1.2 → 0.2.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/.opencode/plugins/mugiwara.mjs +102 -0
- package/README.md +209 -230
- package/content/agents/brook-healing.md +8 -2
- package/content/agents/chopper-checkpoint.md +9 -4
- package/content/agents/eval-runner.md +5 -1
- package/content/agents/franky-gates.md +9 -4
- package/content/agents/jinbe-security.md +5 -1
- package/content/agents/luffy-orchestrator.md +14 -8
- package/content/agents/memory-keeper.md +4 -0
- package/content/agents/nami-planner.md +12 -5
- package/content/agents/resume-coordinator.md +5 -1
- package/content/agents/robin-reviewer.md +5 -1
- package/content/agents/sanji-quality.md +7 -3
- package/content/agents/skeptic-verifier.md +5 -1
- package/content/agents/using-mugiwara.md +11 -7
- package/content/agents/usopp-brainstorm.md +9 -3
- package/content/agents/zoro-execution.md +16 -11
- package/content/skills/mugiwara-backend/SKILL.md +12 -0
- package/content/skills/mugiwara-brainstorm/SKILL.md +28 -1
- package/content/skills/mugiwara-checkpoint/SKILL.md +8 -6
- package/content/skills/mugiwara-deprecation/SKILL.md +77 -0
- package/content/skills/mugiwara-dynamic-workflow/SKILL.md +3 -3
- package/content/skills/mugiwara-execution/SKILL.md +32 -15
- package/content/skills/mugiwara-gates/SKILL.md +4 -0
- package/content/skills/mugiwara-git/SKILL.md +10 -0
- package/content/skills/mugiwara-healing/SKILL.md +9 -3
- package/content/skills/mugiwara-mode/SKILL.md +63 -0
- package/content/skills/mugiwara-orchestration/SKILL.md +26 -8
- package/content/skills/mugiwara-planning/SKILL.md +50 -25
- package/content/skills/mugiwara-pr/SKILL.md +51 -0
- package/content/skills/mugiwara-quality/SKILL.md +19 -2
- package/content/skills/mugiwara-resume/SKILL.md +6 -4
- package/content/skills/mugiwara-testcases/SKILL.md +52 -0
- package/content/skills/mugiwara-workflow/SKILL.md +36 -13
- package/dist/mugiwara.js +9 -20
- package/docs/adoption-guide.md +72 -0
- package/docs/agent-anatomy.md +72 -0
- package/docs/agents.md +51 -0
- package/docs/claude-setup.md +38 -0
- package/docs/codex-setup.md +24 -0
- package/docs/comparison.md +63 -0
- package/docs/copilot-setup.md +27 -0
- package/docs/cursor-setup.md +23 -0
- package/docs/developer-onboarding.md +85 -0
- package/docs/execution-model.md +59 -0
- package/docs/gemini-setup.md +24 -0
- package/docs/getting-started.md +84 -0
- package/docs/git-strategy.md +62 -0
- package/docs/index.md +45 -0
- package/docs/modes.md +64 -0
- package/docs/opencode-setup.md +47 -0
- package/docs/rule-based-setup.md +31 -0
- package/docs/skill-anatomy.md +73 -0
- package/docs/skills.md +61 -0
- package/docs/windsurf-setup.md +16 -0
- package/docs/workflow.md +80 -0
- package/package.json +21 -3
- package/src/args.ts +1 -1
- package/src/cli.ts +5 -15
- package/src/installer.ts +4 -6
- package/src/manifest.ts +0 -1
package/docs/skills.md
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# The Techniques — 25 Skills
|
|
2
|
+
|
|
3
|
+
Each skill is a portable markdown playbook — the "how to" the crew follows when
|
|
4
|
+
it embodies a role. Skills are the actual content; agents are the personas.
|
|
5
|
+
|
|
6
|
+
## Core pipeline
|
|
7
|
+
|
|
8
|
+
| Skill | Enforces |
|
|
9
|
+
|-------|----------|
|
|
10
|
+
| `mugiwara-workflow` | The harness entry point: inline execution model, gateway triage, wave pipeline, workspace layout, blocker protocol, cleanup |
|
|
11
|
+
| `mugiwara-orchestration` | Luffy's captain behavior: 5-way classifier, check-ins, work splitting, decision log, closure |
|
|
12
|
+
| `mugiwara-brainstorm` | Usopp's critical sparring: interrogate, research facts, cut over-engineering, recommend |
|
|
13
|
+
| `mugiwara-planning` | Interview-first, full-context scan, wave plans with parallel/sequential markers + anti-patterns |
|
|
14
|
+
| `mugiwara-execution` | Todo list, sequential tasks inline + parallel worker batches, 6-field delegation for parallel work, one commit per logical task |
|
|
15
|
+
| `mugiwara-checkpoint` | Verify-everything audit — deduped and scoped to the wave's diff; failure rows to the blocker ledger |
|
|
16
|
+
| `mugiwara-quality` | Discover the project's real tooling; formatter, linter, unit tests under the consent matrix |
|
|
17
|
+
| `mugiwara-gates` | Coverage ≥90% new / ≥80% modified, build validation, Definition of Done |
|
|
18
|
+
| `mugiwara-review` | Doubt-driven review: breaking-change analysis, five-axis, severity-tagged findings |
|
|
19
|
+
| `mugiwara-security` | OWASP-driven security review, untrusted-data doctrine, severity by exploitability × impact |
|
|
20
|
+
| `mugiwara-healing` | Reads the ledger, Stop-the-Line + Prove-It root-cause fixes, rollback prep |
|
|
21
|
+
|
|
22
|
+
## Mission control
|
|
23
|
+
|
|
24
|
+
| Skill | Enforces |
|
|
25
|
+
|-------|----------|
|
|
26
|
+
| `mugiwara-mode` | Runtime levels guided / semi / auto, consent invariants, gated auto-GO, push + ready-PR terminal |
|
|
27
|
+
| `mugiwara-git` | Atomic commits, save-points, multi-commit splitting, bisect/blame debugging |
|
|
28
|
+
| `mugiwara-testcases` | User-test intake (ATDD): immutable-gold rule, declarative-AC routing, consent, failure adjudication |
|
|
29
|
+
| `mugiwara-pr` | CI/CD loop terminal: one verdict file + push via plain git; stop-at-PR invariant |
|
|
30
|
+
| `mugiwara-ship` | GO/NO-GO ship gate: pre-launch checklist, feature flags, rollback plan |
|
|
31
|
+
| `mugiwara-deprecation` | Sunset & migration discipline: keep-or-retire gate, cutover playbooks, safe schema changes |
|
|
32
|
+
| `mugiwara-resume` | Session resume: rebuild state from `.mugiwara/` after compaction/loss; never restart |
|
|
33
|
+
| `mugiwara-lessons` | Cross-mission memory: actionable lessons ledger, read at triage, written at closure |
|
|
34
|
+
| `mugiwara-observability` | Trace the crew: structured logs, OTel-compatible spans, session correlation |
|
|
35
|
+
|
|
36
|
+
## Domain & advanced
|
|
37
|
+
|
|
38
|
+
| Skill | Enforces |
|
|
39
|
+
|-------|----------|
|
|
40
|
+
| `mugiwara-frontend` | Anti-slop frontend: audit-first redesigns, design-system extraction, slop list |
|
|
41
|
+
| `mugiwara-backend` | Backend/server code: repo standards first, API design, data integrity, error handling, security |
|
|
42
|
+
| `mugiwara-agent-security` | Secure the agent layer: prompt injection, memory poisoning, excessive agency, secrets, sandboxing |
|
|
43
|
+
| `mugiwara-dynamic-workflow` | Runtime workflow patterns: fan-out-and-synthesize, tournament, loop-until-done, classify-and-act |
|
|
44
|
+
| `mugiwara-eval` | Test the harness itself: task suites, judge-agent rubric comparison, pass/fail per case |
|
|
45
|
+
|
|
46
|
+
## Anatomy of a skill
|
|
47
|
+
|
|
48
|
+
Every skill is a single `SKILL.md` with frontmatter + a playbook body:
|
|
49
|
+
|
|
50
|
+
```markdown
|
|
51
|
+
---
|
|
52
|
+
name: mugiwara-checkpoint
|
|
53
|
+
description: Use after an execution wave to audit results against the plan. ...
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
# Checkpoint (Chopper)
|
|
57
|
+
|
|
58
|
+
<playbook: protocol, rules, red flags, iron law>
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
See [skill-anatomy.md](skill-anatomy.md) for the details.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Windsurf Setup
|
|
2
|
+
|
|
3
|
+
## Install
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npx @ionivetech/mugiwara@latest --project ./my-app --target windsurf --yes
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## What you get
|
|
10
|
+
|
|
11
|
+
- 25 skills as rules files in `.devin/rules`.
|
|
12
|
+
|
|
13
|
+
## Notes
|
|
14
|
+
|
|
15
|
+
Windsurf is a **project-only** target. Skills-only — the crew pipeline runs
|
|
16
|
+
through the rule files.
|
package/docs/workflow.md
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# The Wave Pipeline
|
|
2
|
+
|
|
3
|
+
A mission runs as ten waves (plus one optional adversarial pass). Each wave is
|
|
4
|
+
owned by one crew member and runs **inline** in the main conversation.
|
|
5
|
+
|
|
6
|
+
| Wave | Owner | Skill | Output |
|
|
7
|
+
|------|-------|-------|--------|
|
|
8
|
+
| 0 Triage | Luffy | `mugiwara-orchestration` | 5-way route decision + reason |
|
|
9
|
+
| 1 Brainstorm | Usopp | `mugiwara-brainstorm` | refined direction, options, recommendation |
|
|
10
|
+
| 2 Planning | Nami | `mugiwara-planning` | plan doc: waves, tasks, acceptance criteria |
|
|
11
|
+
| 3 Execution | Zoro | `mugiwara-execution` | implemented tasks with evidence |
|
|
12
|
+
| 4 Checkpoint | Chopper | `mugiwara-checkpoint` | audit report + failure ledger |
|
|
13
|
+
| 4.5 Adversarial | Skeptic | `mugiwara-dynamic-workflow` | findings report (optional) |
|
|
14
|
+
| 5 Quality | Sanji | `mugiwara-quality` | formatter/linter/test results |
|
|
15
|
+
| 6 Gates | Franky | `mugiwara-gates` | coverage + build verdict |
|
|
16
|
+
| 7 Review | Robin ∥ Jinbe | `mugiwara-review` + `mugiwara-security` | severity-tagged findings |
|
|
17
|
+
| 8 Healing | Brook | `mugiwara-healing` | fixes; loops back to Wave 4, max 3 cycles |
|
|
18
|
+
| 9 Closure | Luffy | `mugiwara-orchestration` | closure report + push + PR verdict handed to you |
|
|
19
|
+
|
|
20
|
+
## Wave 0 — Triage
|
|
21
|
+
|
|
22
|
+
Every mission starts at the Luffy gateway, which classifies the request 5 ways:
|
|
23
|
+
|
|
24
|
+
| Class | Signal | Route |
|
|
25
|
+
|-------|--------|-------|
|
|
26
|
+
| Trivial | one obvious small change, no ambiguity | Wave 2 directly |
|
|
27
|
+
| Explicit | clear requirements, written spec exists | Wave 2 directly |
|
|
28
|
+
| Exploratory | needs direction, options, research | Wave 1 first |
|
|
29
|
+
| Open-ended | broad goal, undefined scope | Wave 1 first |
|
|
30
|
+
| Ambiguous | requirements, APIs, scope unclear | Wave 1 first |
|
|
31
|
+
|
|
32
|
+
The decision + reason is logged in `.mugiwara/logs/`. Risk (money/security/
|
|
33
|
+
data/public API) always triggers the full pipeline.
|
|
34
|
+
|
|
35
|
+
## Wave 4 — Checkpoint (Chopper)
|
|
36
|
+
|
|
37
|
+
The verify-everything gate. After execution, Chopper re-runs every acceptance
|
|
38
|
+
criterion — but efficiently:
|
|
39
|
+
|
|
40
|
+
- **Deduped**: each unique check command runs once per wave, scoped to the
|
|
41
|
+
files this wave changed. No running `npm test` once per task.
|
|
42
|
+
- **Scoped by diff**: `git diff --name-only <wave-base>..HEAD` decides what
|
|
43
|
+
actually needs re-verification.
|
|
44
|
+
- **Commit hygiene**: one `git log --stat` pass, not per-commit.
|
|
45
|
+
- Failures land in the blocker ledger `.mugiwara/issues/` with honest
|
|
46
|
+
code-vs-env classification.
|
|
47
|
+
|
|
48
|
+
## Wave 7 — Review
|
|
49
|
+
|
|
50
|
+
Robin (doubt-driven review) and Jinbe (security) run in parallel. Robin maps
|
|
51
|
+
breaking changes to callers before reading the diff; Jinbe runs STRIDE + OWASP.
|
|
52
|
+
Findings are severity-tagged with path:line.
|
|
53
|
+
|
|
54
|
+
## Wave 8 — Healing
|
|
55
|
+
|
|
56
|
+
Brook reads the blocker ledger and fixes root causes, proving each fix by
|
|
57
|
+
re-running the failed check. The loop returns to Wave 4 — max 3 cycles, then
|
|
58
|
+
escalation to you.
|
|
59
|
+
|
|
60
|
+
## Wave 9 — Closure
|
|
61
|
+
|
|
62
|
+
Luffy runs the ship gate, writes the closure report, deletes superseded
|
|
63
|
+
intermediate files, then the terminal step in every mode: **save-point commit →
|
|
64
|
+
push the mission branch → write the PR verdict file → hand branch + verdict to
|
|
65
|
+
you**, who opens the PR. The crew never creates a PR, merges, or deploys.
|
|
66
|
+
|
|
67
|
+
## The two rules that hold it together
|
|
68
|
+
|
|
69
|
+
1. **Evidence over claims.** No wave passes on assertion — the owning agent
|
|
70
|
+
runs the checks and shows output. "Subagents lie. No evidence = not
|
|
71
|
+
complete."
|
|
72
|
+
2. **The plan is the source of truth.** From Wave 2 on, the plan doc in
|
|
73
|
+
`.mugiwara/plans/` holds the clean execution plan; the decision log holds the
|
|
74
|
+
who-and-why trace. No wave is skipped without the reason recorded.
|
|
75
|
+
|
|
76
|
+
## Blocker protocol
|
|
77
|
+
|
|
78
|
+
Any agent that hits a blocker appends a row
|
|
79
|
+
(`wave | task | symptom | attempted | help-needed`) to the ledger and escalates.
|
|
80
|
+
Never a silent workaround. Brook heals what the ledger lists.
|
package/package.json
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ionivetech/mugiwara",
|
|
3
|
-
"version": "0.
|
|
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, Windsurf, Cline, Kilo, Antigravity.",
|
|
3
|
+
"version": "0.2.0",
|
|
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",
|
|
7
|
+
"main": "./.opencode/plugins/mugiwara.mjs",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./.opencode/plugins/mugiwara.mjs",
|
|
10
|
+
"./plugin": "./.opencode/plugins/mugiwara.mjs",
|
|
11
|
+
"./package.json": "./package.json"
|
|
12
|
+
},
|
|
7
13
|
"bin": {
|
|
8
14
|
"mugiwara": "dist/mugiwara.js"
|
|
9
15
|
},
|
|
@@ -11,11 +17,18 @@
|
|
|
11
17
|
"dist",
|
|
12
18
|
"src",
|
|
13
19
|
"content",
|
|
20
|
+
"docs",
|
|
21
|
+
".opencode",
|
|
14
22
|
"scripts/install.sh",
|
|
15
23
|
"scripts/install.ps1",
|
|
16
24
|
"README.md",
|
|
17
25
|
"LICENSE"
|
|
18
26
|
],
|
|
27
|
+
"pi": {
|
|
28
|
+
"skills": [
|
|
29
|
+
"./content/skills"
|
|
30
|
+
]
|
|
31
|
+
},
|
|
19
32
|
"engines": {
|
|
20
33
|
"node": ">=20.11"
|
|
21
34
|
},
|
|
@@ -26,7 +39,8 @@
|
|
|
26
39
|
"build": "bun build src/cli.ts --outfile dist/mugiwara.js --target node --format esm",
|
|
27
40
|
"validate": "bun scripts/validate-content.ts",
|
|
28
41
|
"evals": "bun scripts/run-evals.ts",
|
|
29
|
-
"
|
|
42
|
+
"sync-version": "bun scripts/sync-version.ts",
|
|
43
|
+
"prepack": "bun run build && bun run sync-version"
|
|
30
44
|
},
|
|
31
45
|
"keywords": [
|
|
32
46
|
"ai",
|
|
@@ -34,9 +48,13 @@
|
|
|
34
48
|
"skills",
|
|
35
49
|
"claude-code",
|
|
36
50
|
"opencode",
|
|
51
|
+
"opencode-plugin",
|
|
37
52
|
"copilot",
|
|
38
53
|
"gemini",
|
|
39
54
|
"codex",
|
|
55
|
+
"cursor",
|
|
56
|
+
"kimi",
|
|
57
|
+
"pi",
|
|
40
58
|
"windsurf",
|
|
41
59
|
"cline",
|
|
42
60
|
"multi-agent",
|
package/src/args.ts
CHANGED
|
@@ -6,7 +6,7 @@ export type Args = {
|
|
|
6
6
|
flags: Record<string, FlagValue>;
|
|
7
7
|
};
|
|
8
8
|
|
|
9
|
-
const VALUE_FLAGS: Record<string, string> = { '--project': 'project', '--target': 'target'
|
|
9
|
+
const VALUE_FLAGS: Record<string, string> = { '--project': 'project', '--target': 'target' };
|
|
10
10
|
const BOOL_FLAGS: Record<string, string> = {
|
|
11
11
|
'--global': 'global', '--yes': 'yes', '-y': 'yes', '--force': 'force',
|
|
12
12
|
'--dry-run': 'dryRun', '--help': 'help', '-h': 'help', '--version': 'version', '-v': 'version',
|
package/src/cli.ts
CHANGED
|
@@ -11,8 +11,6 @@ import { installTo, removeInstalled, VERSION, CONTENT_DIR } from './installer.ts
|
|
|
11
11
|
import { manifestPath, readManifest, writeManifest, type Scope } from './manifest.ts';
|
|
12
12
|
import { parseFrontmatter } from './frontmatter.ts';
|
|
13
13
|
|
|
14
|
-
const TYPES = ['frontend', 'backend', 'fullstack', 'general'];
|
|
15
|
-
|
|
16
14
|
const str = (v: FlagValue): string | undefined => (typeof v === 'string' ? v : undefined);
|
|
17
15
|
const flag = (v: FlagValue): boolean => v === true;
|
|
18
16
|
|
|
@@ -30,7 +28,7 @@ export async function run(argv: string[]): Promise<void> {
|
|
|
30
28
|
}
|
|
31
29
|
}
|
|
32
30
|
|
|
33
|
-
async function resolveOptions(flags: Args['flags']): Promise<{ scope: Scope; projectDir: string; targetIds: string[]
|
|
31
|
+
async function resolveOptions(flags: Args['flags']): Promise<{ scope: Scope; projectDir: string; targetIds: string[] }> {
|
|
34
32
|
const interactive = !flag(flags.yes);
|
|
35
33
|
const rl = interactive ? createRl() : null;
|
|
36
34
|
try {
|
|
@@ -53,20 +51,14 @@ async function resolveOptions(flags: Args['flags']): Promise<{ scope: Scope; pro
|
|
|
53
51
|
if (!targets[id]) throw new Error(`Unknown target: ${id} (valid: ${TARGET_IDS.join(', ')}, all)`);
|
|
54
52
|
}
|
|
55
53
|
|
|
56
|
-
|
|
57
|
-
if (!type) {
|
|
58
|
-
if (!interactive) throw new Error('Specify --type with --yes');
|
|
59
|
-
type = TYPES[await choose(rl!, 'Project type?', TYPES)];
|
|
60
|
-
}
|
|
61
|
-
if (!TYPES.includes(type)) throw new Error(`Unknown type: ${type} (valid: ${TYPES.join(', ')})`);
|
|
62
|
-
return { scope, projectDir, targetIds, type };
|
|
54
|
+
return { scope, projectDir, targetIds };
|
|
63
55
|
} finally {
|
|
64
56
|
if (rl) rl.close();
|
|
65
57
|
}
|
|
66
58
|
}
|
|
67
59
|
|
|
68
60
|
async function install(flags: Args['flags']): Promise<void> {
|
|
69
|
-
const { scope, projectDir, targetIds
|
|
61
|
+
const { scope, projectDir, targetIds } = await resolveOptions(flags);
|
|
70
62
|
const home = homedir();
|
|
71
63
|
const allFiles: string[] = [];
|
|
72
64
|
const allNotes: string[] = [];
|
|
@@ -79,7 +71,7 @@ async function install(flags: Args['flags']): Promise<void> {
|
|
|
79
71
|
}
|
|
80
72
|
installed.push(id);
|
|
81
73
|
console.log(`\n-> ${t.label} (${scope})`);
|
|
82
|
-
const r = installTo(t, { scope, projectDir,
|
|
74
|
+
const r = installTo(t, { scope, projectDir, home, dryRun: flag(flags.dryRun), force: flag(flags.force) });
|
|
83
75
|
console.log(` written ${r.written.length}, skipped ${r.skipped.length}, backed up ${r.backedUp.length}`);
|
|
84
76
|
for (const n of r.notes) console.log(` note: ${n}`);
|
|
85
77
|
allFiles.push(...r.written);
|
|
@@ -91,7 +83,6 @@ async function install(flags: Args['flags']): Promise<void> {
|
|
|
91
83
|
writeManifest(file, {
|
|
92
84
|
version: VERSION,
|
|
93
85
|
scope,
|
|
94
|
-
type,
|
|
95
86
|
installedAt: new Date().toISOString(),
|
|
96
87
|
targets: [...new Set([...(prev?.targets ?? []), ...installed])],
|
|
97
88
|
files: [...new Set([...(prev?.files ?? []), ...allFiles])],
|
|
@@ -164,8 +155,7 @@ Flags:
|
|
|
164
155
|
--global user-wide install
|
|
165
156
|
--project <dir> project install (default: cwd)
|
|
166
157
|
--target <ids|all> comma-separated: ${TARGET_IDS.join(', ')}
|
|
167
|
-
--
|
|
168
|
-
--yes, -y non-interactive (needs --global/--project, --target, --type)
|
|
158
|
+
--yes, -y non-interactive (needs --global/--project, --target)
|
|
169
159
|
--force overwrite differing files (with backup)
|
|
170
160
|
--dry-run print actions without writing`);
|
|
171
161
|
}
|
package/src/installer.ts
CHANGED
|
@@ -10,7 +10,6 @@ export type ContentItem = { name: string; data: FrontmatterData; body: string };
|
|
|
10
10
|
export type InstallOptions = {
|
|
11
11
|
scope: Scope;
|
|
12
12
|
projectDir: string;
|
|
13
|
-
type: string;
|
|
14
13
|
dryRun?: boolean;
|
|
15
14
|
force?: boolean;
|
|
16
15
|
home?: string;
|
|
@@ -39,10 +38,9 @@ export const CONTENT_DIR = join(import.meta.dirname, '..', 'content');
|
|
|
39
38
|
const pkg = JSON.parse(readFileSync(join(import.meta.dirname, '..', 'package.json'), 'utf8')) as { version: string };
|
|
40
39
|
export const VERSION = pkg.version;
|
|
41
40
|
|
|
42
|
-
export function collectContent(
|
|
41
|
+
export function collectContent(): { skills: ContentItem[]; agents: ContentItem[] } {
|
|
43
42
|
const skillNames = readdirSync(join(CONTENT_DIR, 'skills'), { withFileTypes: true })
|
|
44
|
-
.filter(e => e.isDirectory()).map(e => e.name)
|
|
45
|
-
.filter(name => includeFrontend || name !== 'mugiwara-frontend');
|
|
43
|
+
.filter(e => e.isDirectory()).map(e => e.name);
|
|
46
44
|
const skills = skillNames.map(name => {
|
|
47
45
|
const { data, body } = parseFrontmatter(readFileSync(join(CONTENT_DIR, 'skills', name, 'SKILL.md'), 'utf8'));
|
|
48
46
|
return { name, data, body };
|
|
@@ -57,9 +55,9 @@ export function collectContent({ includeFrontend }: { includeFrontend: boolean }
|
|
|
57
55
|
}
|
|
58
56
|
|
|
59
57
|
export function installTo(target: Target, opts: InstallOptions): InstallResult {
|
|
60
|
-
const { scope, projectDir,
|
|
58
|
+
const { scope, projectDir, dryRun = false, force = false } = opts;
|
|
61
59
|
const home = opts.home ?? homedir();
|
|
62
|
-
const { skills, agents } = collectContent(
|
|
60
|
+
const { skills, agents } = collectContent();
|
|
63
61
|
const dirs = target.paths({ scope, projectDir, home });
|
|
64
62
|
const backupRoot = join(scope === 'global' ? home : projectDir, '.mugiwara');
|
|
65
63
|
const result: InstallResult = { written: [], skipped: [], backedUp: [], notes: [] };
|