@ionivetech/mugiwara 0.6.1 → 0.6.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.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/.codex-plugin/plugin.json +1 -1
- package/.cursor-plugin/plugin.json +1 -1
- package/.kimi-plugin/plugin.json +1 -1
- package/.opencode/commands/mugiwara-onboard.md +15 -0
- package/.opencode/plugins/mugiwara.mjs +6 -5
- package/README.md +15 -13
- package/content/agents/luffy-orchestrator.md +14 -4
- package/content/agents/onboarding-guide.md +24 -45
- package/content/agents/zoro-execution.md +4 -0
- package/content/skills/mugiwara-backend/SKILL.md +1 -1
- package/content/skills/mugiwara-checkpoint/SKILL.md +1 -1
- package/content/skills/mugiwara-claim-audit/SKILL.md +1 -1
- package/content/skills/mugiwara-execution/SKILL.md +20 -20
- package/content/skills/mugiwara-execution/references/dispatch.md +4 -3
- package/content/skills/mugiwara-frontend/SKILL.md +1 -1
- package/content/skills/mugiwara-healing/SKILL.md +1 -1
- package/content/skills/mugiwara-orchestration/SKILL.md +28 -31
- package/content/skills/mugiwara-orchestration/references/check-ins.md +34 -0
- package/content/skills/mugiwara-orchestration/references/closure.md +1 -1
- package/content/skills/mugiwara-pr/SKILL.md +11 -8
- package/content/skills/mugiwara-ship/SKILL.md +1 -1
- package/content/skills/mugiwara-sunset/SKILL.md +1 -1
- package/content/skills/mugiwara-workflow/SKILL.md +3 -1
- package/content/skills/mugiwara-workflow/references/workspace-layout.md +7 -6
- package/content/skills/using-mugiwara/SKILL.md +4 -0
- package/dist/mugiwara.js +5 -12
- package/gemini-extension.json +1 -1
- package/package.json +1 -1
- package/plugin.json +1 -1
- package/scripts/onboard.ts +3 -29
- package/scripts/release-notes.ts +152 -75
- package/scripts/savepoint.sh +10 -2
- package/src/mission.ts +3 -6
- package/src/targets/claude.ts +5 -3
- package/src/targets/opencode.ts +12 -8
package/scripts/savepoint.sh
CHANGED
|
@@ -7,6 +7,14 @@ die() { echo "savepoint: $*" >&2; exit 1; }
|
|
|
7
7
|
|
|
8
8
|
MUGIWARA_DIR="${MUGIWARA_DIR:-.mugiwara}"
|
|
9
9
|
|
|
10
|
+
# --- git identity for actor attribution ---
|
|
11
|
+
# Resolve once from repo git config; used when no actor is passed explicitly.
|
|
12
|
+
# GIT_AUTHOR_NAME is an env var usually unset — falling through to $USER
|
|
13
|
+
# attributes the savepoint to the OS user instead of the git identity.
|
|
14
|
+
GIT_NAME="$(git config user.name 2>/dev/null || true)"
|
|
15
|
+
GIT_EMAIL="$(git config user.email 2>/dev/null || true)"
|
|
16
|
+
if [ -n "$GIT_NAME" ] && [ -n "$GIT_EMAIL" ]; then GIT_ID="$GIT_NAME <$GIT_EMAIL>"; else GIT_ID="$GIT_NAME"; fi
|
|
17
|
+
|
|
10
18
|
# --- parse mission args ---
|
|
11
19
|
# --branch flag must parse FIRST — it shifts positionals
|
|
12
20
|
BRANCH_MODE=0
|
|
@@ -14,13 +22,13 @@ if [ "${1:-}" = "--branch" ]; then
|
|
|
14
22
|
BRANCH_MODE=1
|
|
15
23
|
shift
|
|
16
24
|
MISSION="${1:-${STATE_MISSION:-}}"
|
|
17
|
-
ACTOR="${2:-${STATE_ACTOR:-${GIT_AUTHOR_NAME:-${USER:-}}}}"
|
|
25
|
+
ACTOR="${2:-${STATE_ACTOR:-${GIT_AUTHOR_NAME:-${GIT_ID:-${USER:-}}}}}"
|
|
18
26
|
BRANCH="${3:-$(git branch --show-current 2>/dev/null || echo 'unknown')}"
|
|
19
27
|
WAVE="${4:-${STATE_WAVE:-1}}"
|
|
20
28
|
MODE="${5:-${STATE_MODE:-guided}}"
|
|
21
29
|
else
|
|
22
30
|
MISSION="${1:-${STATE_MISSION:-}}"
|
|
23
|
-
ACTOR="${2:-${STATE_ACTOR:-${GIT_AUTHOR_NAME:-${USER:-}}}}"
|
|
31
|
+
ACTOR="${2:-${STATE_ACTOR:-${GIT_AUTHOR_NAME:-${GIT_ID:-${USER:-}}}}}"
|
|
24
32
|
BRANCH="${3:-$(git branch --show-current 2>/dev/null || echo 'unknown')}"
|
|
25
33
|
WAVE="${4:-${STATE_WAVE:-1}}"
|
|
26
34
|
MODE="${5:-${STATE_MODE:-guided}}"
|
package/src/mission.ts
CHANGED
|
@@ -80,15 +80,12 @@ export function archiveMission(projectDir: string, mission: string, opts: { dryR
|
|
|
80
80
|
if (f) report = join('reports', f);
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
-
//
|
|
84
|
-
//
|
|
83
|
+
// step results 01..05 + todos.md are evidence — kept; archive removes
|
|
84
|
+
// only spec/review/issues/logs/continue.md
|
|
85
85
|
const resultsDir = join(root, 'results', mission);
|
|
86
86
|
if (existsSync(resultsDir)) {
|
|
87
87
|
for (const f of readdirSync(resultsDir)) {
|
|
88
|
-
|
|
89
|
-
const p = join(resultsDir, f);
|
|
90
|
-
if (!dryRun) rmSync(p, { recursive: true, force: true });
|
|
91
|
-
removed.push(join('results', mission, f));
|
|
88
|
+
kept.push(join('results', mission, f));
|
|
92
89
|
}
|
|
93
90
|
}
|
|
94
91
|
|
package/src/targets/claude.ts
CHANGED
|
@@ -10,8 +10,10 @@ const HOOKS_SRC = join(here, '..', '..', 'hooks');
|
|
|
10
10
|
const COMMANDS_SRC = join(here, '..', '..', '.claude', 'commands');
|
|
11
11
|
|
|
12
12
|
// Claude Code has no path-scoped permission. write-scope maps to a partial
|
|
13
|
-
// `tools:` list
|
|
14
|
-
//
|
|
13
|
+
// `tools:` list — applied to internal subagent-only agents only: artifacts
|
|
14
|
+
// agents lose Edit (cannot modify existing source) but keep Write (must create
|
|
15
|
+
// .mugiwara/**). User-facing crew run inline in the main thread and keep the
|
|
16
|
+
// default toolset (incl. Edit); discipline is enforced by rules, not tools.
|
|
15
17
|
function toolsFromScope(scope?: string): string | undefined {
|
|
16
18
|
if (scope === 'artifacts') return 'Read, Grep, Glob, Write, Bash, WebFetch, WebSearch';
|
|
17
19
|
return undefined;
|
|
@@ -35,7 +37,7 @@ export const target: Target = {
|
|
|
35
37
|
transformAgent(data: FrontmatterData, body: string) {
|
|
36
38
|
const fm: FrontmatterData = { name: data.name, description: data.description };
|
|
37
39
|
if (data.tools) fm.tools = data.tools;
|
|
38
|
-
else {
|
|
40
|
+
else if (data['internal-agent'] === 'true') {
|
|
39
41
|
const generated = toolsFromScope(data['write-scope']);
|
|
40
42
|
if (generated) fm.tools = generated;
|
|
41
43
|
}
|
package/src/targets/opencode.ts
CHANGED
|
@@ -32,23 +32,27 @@ const CREW: Record<string, CrewConfig> = {
|
|
|
32
32
|
'memory-keeper': { color: '#d946ef', temperature: 0.2, steps: 8 },
|
|
33
33
|
};
|
|
34
34
|
|
|
35
|
-
// write-scope is the single source of truth (content/agents/*.md frontmatter)
|
|
36
|
-
//
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
//
|
|
35
|
+
// write-scope is the single source of truth (content/agents/*.md frontmatter),
|
|
36
|
+
// but it is a RULE for user-facing crew agents: they run inline in the main
|
|
37
|
+
// thread, so a runtime permission bound to the active-agent identity would
|
|
38
|
+
// force tab-switching per wave and break auto mode + resume. Runtime
|
|
39
|
+
// enforcement stays for internal subagent-only agents (internal: true) — the
|
|
40
|
+
// path boundary IS expressible in opencode: permission.edit accepts
|
|
41
|
+
// glob/pattern -> action, last match wins. Artifacts internal agents get
|
|
42
|
+
// deny-all-edit except .mugiwara/**; source internal agents get full edit
|
|
43
|
+
// allow. Derived at install time from the frontmatter field.
|
|
40
44
|
function permissionFromScope(scope: string | undefined): Record<string, string | Record<string, string>> | undefined {
|
|
41
45
|
if (scope === 'source') return { edit: 'allow' };
|
|
42
46
|
if (scope === 'artifacts') return { edit: { '*': 'deny', '.mugiwara/**': 'allow' } };
|
|
43
47
|
return undefined;
|
|
44
48
|
}
|
|
45
49
|
|
|
46
|
-
function agentFrontmatter(name: string, description: string, writeScope?: string) {
|
|
50
|
+
function agentFrontmatter(name: string, description: string, internal: boolean, writeScope?: string) {
|
|
47
51
|
const crew = CREW[name];
|
|
48
52
|
const lines = [`description: ${description}`, `mode: all`];
|
|
49
53
|
if (crew) {
|
|
50
54
|
lines.push(`color: '${crew.color}'`, `temperature: ${crew.temperature}`, `steps: ${crew.steps}`);
|
|
51
|
-
const perm = permissionFromScope(writeScope);
|
|
55
|
+
const perm = internal ? permissionFromScope(writeScope) : undefined;
|
|
52
56
|
if (perm) {
|
|
53
57
|
lines.push('permission:');
|
|
54
58
|
for (const [k, v] of Object.entries(perm)) {
|
|
@@ -81,7 +85,7 @@ export const target: Target = {
|
|
|
81
85
|
},
|
|
82
86
|
transformAgent(data: FrontmatterData, body: string) {
|
|
83
87
|
const desc = data['internal-agent'] === 'true' ? `[INTERNAL] ${data.description}` : data.description;
|
|
84
|
-
const fm = agentFrontmatter(data.name, desc, data['write-scope']);
|
|
88
|
+
const fm = agentFrontmatter(data.name, desc, data['internal-agent'] === 'true', data['write-scope']);
|
|
85
89
|
return { relPath: `${data.name}.md`, text: `---\n${fm}\n---\n${body}` };
|
|
86
90
|
},
|
|
87
91
|
refsDir({ scope, projectDir, home }, skillName: string) {
|