@heart-of-gold/toolkit 0.1.8 → 0.1.10
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/README.md +9 -7
- package/extensions/pi/brainstorm.ts +9 -53
- package/extensions/pi/plan.ts +5 -76
- package/extensions/pi/work.ts +25 -66
- package/package.json +2 -1
- package/plugins/guide/README.md +6 -0
- package/plugins/guide/skills/claude-code/SKILL.md +118 -0
- package/plugins/guide/skills/claude-code/scripts/run-claude-code.sh +140 -0
- package/src/index.ts +1 -1
- package/src/utils/transform.ts +2 -0
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> **Don't Panic.**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
29 skills for AI coding agents. Five plugins. Works with **Claude Code, Codex, OpenCode, Pi**, and any tool supporting the [agentskills.io](https://agentskills.io) standard. Named after *The Hitchhiker's Guide to the Galaxy* because the universe is absurd and your tools should at least have personality.
|
|
6
6
|
|
|
7
7
|
## Installation
|
|
8
8
|
|
|
@@ -36,12 +36,13 @@ pi install npm:@heart-of-gold/toolkit
|
|
|
36
36
|
Pi also discovers skills from the shared `~/.agents/skills/` location, so installs done with the OpenCode target are usable from Pi too.
|
|
37
37
|
|
|
38
38
|
When installed as a Pi package, Heart of Gold exposes Pi-native extension commands for the flagship workflows:
|
|
39
|
-
- `/deep-thought-brainstorm` —
|
|
40
|
-
- `/deep-thought-plan` — planning
|
|
41
|
-
- `/marvin-work` —
|
|
42
|
-
- `/marvin-execute` — leave planning mode and begin execution
|
|
39
|
+
- `/deep-thought-brainstorm` — start a brainstorm (collaborative discovery)
|
|
40
|
+
- `/deep-thought-plan` — start planning (research and produce a plan document)
|
|
41
|
+
- `/marvin-work` — start executing a plan (with always-on safety guardrails)
|
|
43
42
|
|
|
44
|
-
|
|
43
|
+
The skills themselves enforce their own boundaries (read-only for brainstorm/plan, safe commands for work) via `allowed-tools` and prompt constraints — no manual mode switching needed.
|
|
44
|
+
|
|
45
|
+
The work extension also provides always-on guardrails that protect `.env`, `.git/`, and `node_modules/` from edits, block `git add .` and destructive `rm`, and require confirmation for `git push` / `npm publish`.
|
|
45
46
|
|
|
46
47
|
### List available skills
|
|
47
48
|
```bash
|
|
@@ -106,13 +107,14 @@ Your personal content engine.
|
|
|
106
107
|
|
|
107
108
|
Configurable sources (RSS, Gmail, HN, web search), narrative briefs, LinkedIn drafts, blog outlines, voice fidelity checking, iMessage delivery, and two-way captures.
|
|
108
109
|
|
|
109
|
-
|
|
110
|
+
7 skills · 2 agents · 5 scripts
|
|
110
111
|
|
|
111
112
|
```
|
|
112
113
|
/guide:setup # configure your sources, themes, and voice
|
|
113
114
|
/guide:pipeline # run the full content engine
|
|
114
115
|
/guide:capture # morning/evening thought capture
|
|
115
116
|
/guide:write-post # guided blog writing (7 phases)
|
|
117
|
+
/guide:claude-code # Claude Code CLI guidance
|
|
116
118
|
/guide:codex # Codex CLI guidance
|
|
117
119
|
/guide:gemini # Gemini CLI guidance
|
|
118
120
|
```
|
|
@@ -1,67 +1,23 @@
|
|
|
1
1
|
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
2
2
|
|
|
3
|
-
function sendPrompt(pi: ExtensionAPI, prompt: string, ctx: Parameters<NonNullable<Parameters<ExtensionAPI["registerCommand"]>[1]["handler"]>>[1]) {
|
|
4
|
-
if (ctx.isIdle()) {
|
|
5
|
-
pi.sendUserMessage(prompt);
|
|
6
|
-
} else {
|
|
7
|
-
pi.sendUserMessage(prompt, { deliverAs: "followUp" });
|
|
8
|
-
ctx.ui.notify("Brainstorm prompt queued as follow-up", "info");
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
|
|
12
3
|
export default function brainstormExtension(pi: ExtensionAPI) {
|
|
13
4
|
pi.registerCommand("deep-thought-brainstorm", {
|
|
14
|
-
description: "
|
|
5
|
+
description: "Start a brainstorm — collaborative discovery before planning",
|
|
15
6
|
handler: async (args, ctx) => {
|
|
16
|
-
|
|
17
|
-
ctx.ui.notify("/deep-thought-brainstorm requires interactive mode", "warning");
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const topic = args.trim() || (await ctx.ui.editor("Brainstorm topic", ""))?.trim();
|
|
7
|
+
const topic = args.trim() || (ctx.hasUI ? (await ctx.ui.editor("Brainstorm topic", ""))?.trim() : undefined);
|
|
22
8
|
if (!topic) {
|
|
23
|
-
ctx.ui.notify("
|
|
9
|
+
ctx.ui.notify("Usage: /deep-thought-brainstorm <topic>", "info");
|
|
24
10
|
return;
|
|
25
11
|
}
|
|
26
12
|
|
|
27
|
-
const
|
|
28
|
-
"Unclear — need discovery",
|
|
29
|
-
"Partly clear — explore tradeoffs",
|
|
30
|
-
"Quite clear — validate before planning",
|
|
31
|
-
]);
|
|
32
|
-
if (!clarity) {
|
|
33
|
-
ctx.ui.notify("Cancelled", "info");
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
13
|
+
const prompt = `/skill:brainstorm ${topic}`;
|
|
36
14
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
if (!goal) {
|
|
43
|
-
ctx.ui.notify("Cancelled", "info");
|
|
44
|
-
return;
|
|
15
|
+
if (ctx.isIdle()) {
|
|
16
|
+
pi.sendUserMessage(prompt);
|
|
17
|
+
} else {
|
|
18
|
+
pi.sendUserMessage(prompt, { deliverAs: "followUp" });
|
|
19
|
+
ctx.ui.notify("Brainstorm queued as follow-up", "info");
|
|
45
20
|
}
|
|
46
|
-
|
|
47
|
-
const prompt = [
|
|
48
|
-
`/skill:brainstorm ${topic}`,
|
|
49
|
-
"",
|
|
50
|
-
"Use a pi-friendly interactive flow:",
|
|
51
|
-
"- Ask one question at a time.",
|
|
52
|
-
"- Use explicit option lists whenever there are natural choices.",
|
|
53
|
-
"- Keep momentum high and avoid dumping questionnaires.",
|
|
54
|
-
"",
|
|
55
|
-
`Current clarity: ${clarity}`,
|
|
56
|
-
`Primary goal: ${goal}`,
|
|
57
|
-
].join("\n");
|
|
58
|
-
|
|
59
|
-
const theme = ctx.ui.theme;
|
|
60
|
-
ctx.ui.setStatus(
|
|
61
|
-
"deep-thought-brainstorm",
|
|
62
|
-
theme.fg("accent", "◉") + theme.fg("dim", " Brainstorm flow active"),
|
|
63
|
-
);
|
|
64
|
-
sendPrompt(pi, prompt, ctx);
|
|
65
21
|
},
|
|
66
22
|
});
|
|
67
23
|
}
|
package/extensions/pi/plan.ts
CHANGED
|
@@ -1,93 +1,22 @@
|
|
|
1
1
|
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
2
2
|
|
|
3
|
-
const PLAN_SAFE_TOOLS = ["read", "bash", "grep", "find", "ls"];
|
|
4
|
-
|
|
5
3
|
export default function planExtension(pi: ExtensionAPI) {
|
|
6
|
-
let previousTools: string[] | null = null;
|
|
7
|
-
|
|
8
|
-
const applyPlanTools = () => {
|
|
9
|
-
const available = new Set(pi.getAllTools().map((tool) => tool.name));
|
|
10
|
-
const nextTools = PLAN_SAFE_TOOLS.filter((tool) => available.has(tool));
|
|
11
|
-
if (nextTools.length > 0) {
|
|
12
|
-
pi.setActiveTools(nextTools);
|
|
13
|
-
}
|
|
14
|
-
};
|
|
15
|
-
|
|
16
4
|
pi.registerCommand("deep-thought-plan", {
|
|
17
|
-
description: "
|
|
5
|
+
description: "Start planning — research and produce a plan document",
|
|
18
6
|
handler: async (args, ctx) => {
|
|
19
|
-
|
|
20
|
-
ctx.ui.notify("/deep-thought-plan requires interactive mode", "warning");
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const source = args.trim() || (await ctx.ui.editor("Plan topic or brainstorm path", ""))?.trim();
|
|
7
|
+
const source = args.trim() || (ctx.hasUI ? (await ctx.ui.editor("Plan topic or brainstorm path", ""))?.trim() : undefined);
|
|
25
8
|
if (!source) {
|
|
26
|
-
ctx.ui.notify("
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const mode = await ctx.ui.select("How should planning mode behave?", [
|
|
31
|
-
"Read-only planning (recommended)",
|
|
32
|
-
"Allow normal tools, but stay in planning mode",
|
|
33
|
-
]);
|
|
34
|
-
if (!mode) {
|
|
35
|
-
ctx.ui.notify("Cancelled", "info");
|
|
9
|
+
ctx.ui.notify("Usage: /deep-thought-plan <topic or brainstorm path>", "info");
|
|
36
10
|
return;
|
|
37
11
|
}
|
|
38
12
|
|
|
39
|
-
|
|
40
|
-
previousTools = pi.getActiveTools();
|
|
41
|
-
}
|
|
42
|
-
if (mode.startsWith("Read-only")) {
|
|
43
|
-
applyPlanTools();
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const prompt = [
|
|
47
|
-
`/skill:plan ${source}`,
|
|
48
|
-
"",
|
|
49
|
-
"Use a pi-friendly planning flow:",
|
|
50
|
-
"- Keep planning read-only unless the user explicitly exits planning mode.",
|
|
51
|
-
"- Ask one question at a time when clarification is needed.",
|
|
52
|
-
"- Use concise option lists when choosing between paths or handoffs.",
|
|
53
|
-
].join("\n");
|
|
54
|
-
|
|
55
|
-
const theme = ctx.ui.theme;
|
|
56
|
-
ctx.ui.setStatus(
|
|
57
|
-
"deep-thought-plan",
|
|
58
|
-
theme.fg("accent", "◉") + theme.fg("dim", " Plan mode active"),
|
|
59
|
-
);
|
|
60
|
-
|
|
61
|
-
if (ctx.isIdle()) {
|
|
62
|
-
pi.sendUserMessage(prompt);
|
|
63
|
-
} else {
|
|
64
|
-
pi.sendUserMessage(prompt, { deliverAs: "followUp" });
|
|
65
|
-
ctx.ui.notify("Plan prompt queued as follow-up", "info");
|
|
66
|
-
}
|
|
67
|
-
},
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
pi.registerCommand("marvin-execute", {
|
|
71
|
-
description: "Exit planning mode, restore tools, and optionally start work",
|
|
72
|
-
handler: async (args, ctx) => {
|
|
73
|
-
if (previousTools) {
|
|
74
|
-
pi.setActiveTools(previousTools);
|
|
75
|
-
previousTools = null;
|
|
76
|
-
}
|
|
77
|
-
ctx.ui.setStatus("deep-thought-plan", "");
|
|
78
|
-
|
|
79
|
-
const target = args.trim();
|
|
80
|
-
if (!target) {
|
|
81
|
-
ctx.ui.notify("Planning mode cleared. Run /marvin-work <plan-path> when ready.", "info");
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
13
|
+
const prompt = `/skill:plan ${source}`;
|
|
84
14
|
|
|
85
|
-
const prompt = `/skill:work ${target}`;
|
|
86
15
|
if (ctx.isIdle()) {
|
|
87
16
|
pi.sendUserMessage(prompt);
|
|
88
17
|
} else {
|
|
89
18
|
pi.sendUserMessage(prompt, { deliverAs: "followUp" });
|
|
90
|
-
ctx.ui.notify("
|
|
19
|
+
ctx.ui.notify("Plan queued as follow-up", "info");
|
|
91
20
|
}
|
|
92
21
|
},
|
|
93
22
|
});
|
package/extensions/pi/work.ts
CHANGED
|
@@ -5,76 +5,15 @@ const CONFIRM_COMMANDS = [/\bgit\s+push\b/i, /\bnpm\s+publish\b/i, /\bbun\s+publ
|
|
|
5
5
|
const BLOCKED_COMMANDS = [/\bgit\s+add\s+\.\b/i, /\brm\s+(-rf?|--recursive)/i];
|
|
6
6
|
|
|
7
7
|
export default function workExtension(pi: ExtensionAPI) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
pi.registerCommand("marvin-work", {
|
|
11
|
-
description: "Interactive pi-first entrypoint for the shared work skill",
|
|
12
|
-
handler: async (args, ctx) => {
|
|
13
|
-
if (!ctx.hasUI) {
|
|
14
|
-
ctx.ui.notify("/marvin-work requires interactive mode", "warning");
|
|
15
|
-
return;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const planPath = args.trim() || (await ctx.ui.editor("Plan path", ""))?.trim();
|
|
19
|
-
if (!planPath) {
|
|
20
|
-
ctx.ui.notify("Cancelled", "info");
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const runMode = await ctx.ui.select("How strict should work mode be?", [
|
|
25
|
-
"Normal guardrails (recommended)",
|
|
26
|
-
"Strict guardrails for shipping work",
|
|
27
|
-
]);
|
|
28
|
-
if (!runMode) {
|
|
29
|
-
ctx.ui.notify("Cancelled", "info");
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
workMode = true;
|
|
34
|
-
const theme = ctx.ui.theme;
|
|
35
|
-
ctx.ui.setStatus(
|
|
36
|
-
"marvin-work",
|
|
37
|
-
theme.fg("accent", "◉") + theme.fg("dim", ` Work mode active — ${runMode}`),
|
|
38
|
-
);
|
|
39
|
-
|
|
40
|
-
const prompt = [
|
|
41
|
-
`/skill:work ${planPath}`,
|
|
42
|
-
"",
|
|
43
|
-
"Use pi guardrails while executing:",
|
|
44
|
-
"- keep progress visible as tasks move from in-progress to complete",
|
|
45
|
-
"- do not use `git add .`",
|
|
46
|
-
"- confirm push/publish actions deliberately",
|
|
47
|
-
"- protect .env, .git/, and node_modules/ from accidental edits",
|
|
48
|
-
].join("\n");
|
|
49
|
-
|
|
50
|
-
if (ctx.isIdle()) {
|
|
51
|
-
pi.sendUserMessage(prompt);
|
|
52
|
-
} else {
|
|
53
|
-
pi.sendUserMessage(prompt, { deliverAs: "followUp" });
|
|
54
|
-
ctx.ui.notify("Work prompt queued as follow-up", "info");
|
|
55
|
-
}
|
|
56
|
-
},
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
pi.registerCommand("marvin-work-off", {
|
|
60
|
-
description: "Disable Heart of Gold work-mode guardrails",
|
|
61
|
-
handler: async (_args, ctx) => {
|
|
62
|
-
workMode = false;
|
|
63
|
-
ctx.ui.setStatus("marvin-work", "");
|
|
64
|
-
ctx.ui.notify("Work mode disabled", "info");
|
|
65
|
-
},
|
|
66
|
-
});
|
|
67
|
-
|
|
8
|
+
// Always-on guardrails — no mode toggle needed
|
|
68
9
|
pi.on("tool_call", async (event, ctx) => {
|
|
69
|
-
if (!workMode) return undefined;
|
|
70
|
-
|
|
71
10
|
if (event.toolName === "write" || event.toolName === "edit") {
|
|
72
11
|
const path = String(event.input.path ?? "");
|
|
73
12
|
if (PROTECTED_PATHS.some((segment) => path.includes(segment))) {
|
|
74
13
|
if (ctx.hasUI) {
|
|
75
|
-
ctx.ui.notify(
|
|
14
|
+
ctx.ui.notify(`⛔ Protected path: ${path}`, "warning");
|
|
76
15
|
}
|
|
77
|
-
return { block: true, reason: `Protected path
|
|
16
|
+
return { block: true, reason: `Protected path: ${path}` };
|
|
78
17
|
}
|
|
79
18
|
}
|
|
80
19
|
|
|
@@ -82,7 +21,7 @@ export default function workExtension(pi: ExtensionAPI) {
|
|
|
82
21
|
const command = String(event.input.command ?? "");
|
|
83
22
|
|
|
84
23
|
if (BLOCKED_COMMANDS.some((pattern) => pattern.test(command))) {
|
|
85
|
-
return { block: true, reason: `Blocked unsafe command
|
|
24
|
+
return { block: true, reason: `Blocked unsafe command: ${command}` };
|
|
86
25
|
}
|
|
87
26
|
|
|
88
27
|
if (!CONFIRM_COMMANDS.some((pattern) => pattern.test(command))) {
|
|
@@ -93,11 +32,31 @@ export default function workExtension(pi: ExtensionAPI) {
|
|
|
93
32
|
return { block: true, reason: `Interactive confirmation required for: ${command}` };
|
|
94
33
|
}
|
|
95
34
|
|
|
96
|
-
const choice = await ctx.ui.select(`Confirm
|
|
35
|
+
const choice = await ctx.ui.select(`Confirm: ${command}`, ["Allow", "Block"]);
|
|
97
36
|
if (choice !== "Allow") {
|
|
98
37
|
return { block: true, reason: `Blocked by user: ${command}` };
|
|
99
38
|
}
|
|
100
39
|
|
|
101
40
|
return undefined;
|
|
102
41
|
});
|
|
42
|
+
|
|
43
|
+
pi.registerCommand("marvin-work", {
|
|
44
|
+
description: "Start executing a plan — implement with guardrails",
|
|
45
|
+
handler: async (args, ctx) => {
|
|
46
|
+
const planPath = args.trim() || (ctx.hasUI ? (await ctx.ui.editor("Plan path", ""))?.trim() : undefined);
|
|
47
|
+
if (!planPath) {
|
|
48
|
+
ctx.ui.notify("Usage: /marvin-work <plan path>", "info");
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const prompt = `/skill:work ${planPath}`;
|
|
53
|
+
|
|
54
|
+
if (ctx.isIdle()) {
|
|
55
|
+
pi.sendUserMessage(prompt);
|
|
56
|
+
} else {
|
|
57
|
+
pi.sendUserMessage(prompt, { deliverAs: "followUp" });
|
|
58
|
+
ctx.ui.notify("Work queued as follow-up", "info");
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
});
|
|
103
62
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@heart-of-gold/toolkit",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Cross-platform installer for Heart of Gold skills — works with Codex, OpenCode, Pi, Claude Code, and more",
|
|
6
6
|
"bin": {
|
|
@@ -59,6 +59,7 @@
|
|
|
59
59
|
"./plugins/deep-thought/skills/review",
|
|
60
60
|
"./plugins/deep-thought/skills/think",
|
|
61
61
|
"./plugins/guide/skills/capture",
|
|
62
|
+
"./plugins/guide/skills/claude-code",
|
|
62
63
|
"./plugins/guide/skills/codex",
|
|
63
64
|
"./plugins/guide/skills/gemini",
|
|
64
65
|
"./plugins/guide/skills/pipeline",
|
package/plugins/guide/README.md
CHANGED
|
@@ -73,6 +73,12 @@ Guided blog writing in seven phases:
|
|
|
73
73
|
|
|
74
74
|
Can pick up blog outlines generated by the pipeline (`needs_write_post: true` in frontmatter).
|
|
75
75
|
|
|
76
|
+
### /guide:claude-code
|
|
77
|
+
|
|
78
|
+
Headless Claude Code handoff for second opinions, code review, targeted analysis, or follow-up on a bounded task.
|
|
79
|
+
|
|
80
|
+
Use it when you want another agent harness to invoke Claude Code non-interactively, capture the result, and summarize it back. The skill ships with a small wrapper script that standardizes `claude -p` / resume usage across installs.
|
|
81
|
+
|
|
76
82
|
## How the Pipeline Works
|
|
77
83
|
|
|
78
84
|
```
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: claude-code
|
|
3
|
+
description: Use when the user asks to run Claude Code CLI (`claude`, `claude resume`) or asks for a second opinion, review, analysis, refactor, or follow-up specifically from Claude Code.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Claude Code CLI Skill Guide
|
|
7
|
+
|
|
8
|
+
Use this skill to hand a bounded task to Claude Code from the current harness, capture the output, and summarize it back to the user.
|
|
9
|
+
|
|
10
|
+
## Defaults
|
|
11
|
+
|
|
12
|
+
- Default model: `sonnet`
|
|
13
|
+
- Default permission mode for review or analysis: `plan`
|
|
14
|
+
- Default permission mode for requested edits: `acceptEdits`
|
|
15
|
+
- Default effort: `medium`
|
|
16
|
+
|
|
17
|
+
Prefer the harness's structured question UI when available; otherwise ask plainly in text and wait for the answer before continuing.
|
|
18
|
+
|
|
19
|
+
## Running a Task
|
|
20
|
+
|
|
21
|
+
1. Ask the user which model to use if they care. Default to `sonnet`.
|
|
22
|
+
2. Ask for permission mode only when it materially affects safety:
|
|
23
|
+
- `plan` for review, analysis, and read-only second opinions
|
|
24
|
+
- `acceptEdits` when the user explicitly wants Claude Code to make local changes
|
|
25
|
+
- `bypassPermissions` only with explicit user approval
|
|
26
|
+
3. Resolve the bundled runner relative to this skill:
|
|
27
|
+
- `scripts/run-claude-code.sh`
|
|
28
|
+
4. Build a concrete prompt for Claude Code. For review requests, include scope and output shape:
|
|
29
|
+
- Ask for findings ordered by severity
|
|
30
|
+
- Ask for file paths in each finding
|
|
31
|
+
- Ask for a short final verdict
|
|
32
|
+
5. Run the bundled script:
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
bash <skill-dir>/scripts/run-claude-code.sh \
|
|
36
|
+
--prompt "<PROMPT>" \
|
|
37
|
+
--model <MODEL> \
|
|
38
|
+
--permission-mode <MODE> \
|
|
39
|
+
--effort <EFFORT>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
6. Capture stdout and summarize the result for the user.
|
|
43
|
+
7. If the user wants a follow-up, resume the latest Claude Code session instead of starting from scratch:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
bash <skill-dir>/scripts/run-claude-code.sh \
|
|
47
|
+
--resume latest \
|
|
48
|
+
--prompt "<FOLLOW_UP_PROMPT>" \
|
|
49
|
+
--model <MODEL> \
|
|
50
|
+
--permission-mode <MODE> \
|
|
51
|
+
--effort <EFFORT>
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Quick Reference
|
|
55
|
+
|
|
56
|
+
| Use case | Permission mode | Suggested prompt shape |
|
|
57
|
+
| --- | --- | --- |
|
|
58
|
+
| Read-only code review | `plan` | "Review the current diff and return findings ordered by severity with file paths." |
|
|
59
|
+
| Architecture second opinion | `plan` | "Assess this design and name the top risks, tradeoffs, and missing tests." |
|
|
60
|
+
| Targeted implementation | `acceptEdits` | "Implement X, keep changes minimal, and explain what changed." |
|
|
61
|
+
| Continue prior thread | prior mode | Resume with a narrow follow-up prompt instead of restating everything |
|
|
62
|
+
|
|
63
|
+
## Prompting Guidance
|
|
64
|
+
|
|
65
|
+
- Keep prompts bounded. Claude Code performs better when the scope is explicit.
|
|
66
|
+
- Name the artifact under review: current diff, specific files, or a directory.
|
|
67
|
+
- For reviews, ask for bugs, regressions, missing tests, and risky assumptions first.
|
|
68
|
+
- For implementation requests, specify what must not change.
|
|
69
|
+
- If you disagree with the result, treat Claude Code as a colleague and challenge it with evidence.
|
|
70
|
+
|
|
71
|
+
## Examples
|
|
72
|
+
|
|
73
|
+
### Review the current diff
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
bash <skill-dir>/scripts/run-claude-code.sh \
|
|
77
|
+
--prompt "Review the current git diff. Return only findings, ordered by severity, with file paths and concise explanations." \
|
|
78
|
+
--model sonnet \
|
|
79
|
+
--permission-mode plan \
|
|
80
|
+
--effort medium
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Ask Claude Code to inspect a single file
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
bash <skill-dir>/scripts/run-claude-code.sh \
|
|
87
|
+
--prompt "Review src/server.ts for correctness, edge cases, and missing tests. Keep the response concise." \
|
|
88
|
+
--model sonnet \
|
|
89
|
+
--permission-mode plan \
|
|
90
|
+
--effort high
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Continue the latest Claude Code session
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
bash <skill-dir>/scripts/run-claude-code.sh \
|
|
97
|
+
--resume latest \
|
|
98
|
+
--prompt "Focus only on the migration risk you mentioned. What is the safest rollout plan?" \
|
|
99
|
+
--model sonnet \
|
|
100
|
+
--permission-mode plan \
|
|
101
|
+
--effort medium
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Script
|
|
105
|
+
|
|
106
|
+
Use the bundled runner instead of assembling `claude` commands ad hoc:
|
|
107
|
+
|
|
108
|
+
- `scripts/run-claude-code.sh --check` verifies that Claude Code is installed
|
|
109
|
+
- `scripts/run-claude-code.sh --help` prints usage
|
|
110
|
+
|
|
111
|
+
The wrapper keeps flag handling deterministic and portable when this skill is installed into Codex, Pi, or other agent harnesses.
|
|
112
|
+
|
|
113
|
+
## Error Handling
|
|
114
|
+
|
|
115
|
+
- Stop and report failures when `claude --version` or the runner exits non-zero.
|
|
116
|
+
- If Claude Code is missing, tell the user to install or authenticate Claude Code before retrying.
|
|
117
|
+
- If output is partial or Claude reports permission issues, summarize that clearly and ask whether to retry with a different permission mode.
|
|
118
|
+
- Do not use `bypassPermissions` unless the user explicitly approves it.
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
usage() {
|
|
5
|
+
cat <<'EOF'
|
|
6
|
+
Usage:
|
|
7
|
+
run-claude-code.sh --check
|
|
8
|
+
run-claude-code.sh --prompt "..." [options]
|
|
9
|
+
|
|
10
|
+
Options:
|
|
11
|
+
--check Verify that Claude Code is installed
|
|
12
|
+
--prompt TEXT Prompt to send to Claude Code
|
|
13
|
+
--model MODEL Claude model or alias (default: sonnet)
|
|
14
|
+
--permission-mode MODE plan, acceptEdits, default, auto, dontAsk, bypassPermissions
|
|
15
|
+
--effort LEVEL low, medium, high, max
|
|
16
|
+
--output-format FORMAT text, json, stream-json (default: text)
|
|
17
|
+
--resume VALUE Resume a session, for example: latest
|
|
18
|
+
--continue Continue the most recent session in the current directory
|
|
19
|
+
--add-dir PATH Additional directory to allow tool access to; repeatable
|
|
20
|
+
--cwd PATH Working directory to run Claude Code from
|
|
21
|
+
--help Show this help text
|
|
22
|
+
EOF
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
check_only=0
|
|
26
|
+
prompt=""
|
|
27
|
+
model="sonnet"
|
|
28
|
+
permission_mode=""
|
|
29
|
+
effort=""
|
|
30
|
+
output_format="text"
|
|
31
|
+
resume_value=""
|
|
32
|
+
continue_mode=0
|
|
33
|
+
cwd=""
|
|
34
|
+
add_dirs=()
|
|
35
|
+
|
|
36
|
+
while [[ $# -gt 0 ]]; do
|
|
37
|
+
case "$1" in
|
|
38
|
+
--check)
|
|
39
|
+
check_only=1
|
|
40
|
+
shift
|
|
41
|
+
;;
|
|
42
|
+
--prompt)
|
|
43
|
+
[[ $# -ge 2 ]] || { echo "Missing value for --prompt" >&2; exit 2; }
|
|
44
|
+
prompt="$2"
|
|
45
|
+
shift 2
|
|
46
|
+
;;
|
|
47
|
+
--model)
|
|
48
|
+
[[ $# -ge 2 ]] || { echo "Missing value for --model" >&2; exit 2; }
|
|
49
|
+
model="$2"
|
|
50
|
+
shift 2
|
|
51
|
+
;;
|
|
52
|
+
--permission-mode)
|
|
53
|
+
[[ $# -ge 2 ]] || { echo "Missing value for --permission-mode" >&2; exit 2; }
|
|
54
|
+
permission_mode="$2"
|
|
55
|
+
shift 2
|
|
56
|
+
;;
|
|
57
|
+
--effort)
|
|
58
|
+
[[ $# -ge 2 ]] || { echo "Missing value for --effort" >&2; exit 2; }
|
|
59
|
+
effort="$2"
|
|
60
|
+
shift 2
|
|
61
|
+
;;
|
|
62
|
+
--output-format)
|
|
63
|
+
[[ $# -ge 2 ]] || { echo "Missing value for --output-format" >&2; exit 2; }
|
|
64
|
+
output_format="$2"
|
|
65
|
+
shift 2
|
|
66
|
+
;;
|
|
67
|
+
--resume)
|
|
68
|
+
[[ $# -ge 2 ]] || { echo "Missing value for --resume" >&2; exit 2; }
|
|
69
|
+
resume_value="$2"
|
|
70
|
+
shift 2
|
|
71
|
+
;;
|
|
72
|
+
--continue)
|
|
73
|
+
continue_mode=1
|
|
74
|
+
shift
|
|
75
|
+
;;
|
|
76
|
+
--add-dir)
|
|
77
|
+
[[ $# -ge 2 ]] || { echo "Missing value for --add-dir" >&2; exit 2; }
|
|
78
|
+
add_dirs+=("$2")
|
|
79
|
+
shift 2
|
|
80
|
+
;;
|
|
81
|
+
--cwd)
|
|
82
|
+
[[ $# -ge 2 ]] || { echo "Missing value for --cwd" >&2; exit 2; }
|
|
83
|
+
cwd="$2"
|
|
84
|
+
shift 2
|
|
85
|
+
;;
|
|
86
|
+
--help|-h)
|
|
87
|
+
usage
|
|
88
|
+
exit 0
|
|
89
|
+
;;
|
|
90
|
+
*)
|
|
91
|
+
echo "Unknown argument: $1" >&2
|
|
92
|
+
usage >&2
|
|
93
|
+
exit 2
|
|
94
|
+
;;
|
|
95
|
+
esac
|
|
96
|
+
done
|
|
97
|
+
|
|
98
|
+
if [[ "$check_only" -eq 1 ]]; then
|
|
99
|
+
exec claude --version
|
|
100
|
+
fi
|
|
101
|
+
|
|
102
|
+
if [[ -z "$prompt" ]]; then
|
|
103
|
+
echo "--prompt is required unless --check is used" >&2
|
|
104
|
+
exit 2
|
|
105
|
+
fi
|
|
106
|
+
|
|
107
|
+
if [[ -n "$resume_value" && "$continue_mode" -eq 1 ]]; then
|
|
108
|
+
echo "--resume and --continue cannot be used together" >&2
|
|
109
|
+
exit 2
|
|
110
|
+
fi
|
|
111
|
+
|
|
112
|
+
cmd=(claude)
|
|
113
|
+
|
|
114
|
+
if [[ -n "$resume_value" ]]; then
|
|
115
|
+
cmd+=(-r "$resume_value")
|
|
116
|
+
elif [[ "$continue_mode" -eq 1 ]]; then
|
|
117
|
+
cmd+=(-c)
|
|
118
|
+
fi
|
|
119
|
+
|
|
120
|
+
cmd+=(--print --output-format "$output_format" --model "$model")
|
|
121
|
+
|
|
122
|
+
if [[ -n "$permission_mode" ]]; then
|
|
123
|
+
cmd+=(--permission-mode "$permission_mode")
|
|
124
|
+
fi
|
|
125
|
+
|
|
126
|
+
if [[ -n "$effort" ]]; then
|
|
127
|
+
cmd+=(--effort "$effort")
|
|
128
|
+
fi
|
|
129
|
+
|
|
130
|
+
for dir in "${add_dirs[@]}"; do
|
|
131
|
+
cmd+=(--add-dir "$dir")
|
|
132
|
+
done
|
|
133
|
+
|
|
134
|
+
cmd+=("$prompt")
|
|
135
|
+
|
|
136
|
+
if [[ -n "$cwd" ]]; then
|
|
137
|
+
cd "$cwd"
|
|
138
|
+
fi
|
|
139
|
+
|
|
140
|
+
exec "${cmd[@]}"
|
package/src/index.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { targetsCommand } from "./commands/targets";
|
|
|
7
7
|
const main = defineCommand({
|
|
8
8
|
meta: {
|
|
9
9
|
name: "heart-of-gold",
|
|
10
|
-
version: "0.1.
|
|
10
|
+
version: "0.1.10",
|
|
11
11
|
description:
|
|
12
12
|
"Cross-platform installer for Heart of Gold skills — Codex, OpenCode, Pi, Claude Code, and more",
|
|
13
13
|
},
|
package/src/utils/transform.ts
CHANGED
|
@@ -9,6 +9,7 @@ const CODEX_COMMAND_ALIASES: Record<string, string> = {
|
|
|
9
9
|
"/brainstorm": "$brainstorm",
|
|
10
10
|
"/capture": "$capture",
|
|
11
11
|
"/coach": "$coach",
|
|
12
|
+
"/claude-code": "$claude-code",
|
|
12
13
|
"/codex": "$codex",
|
|
13
14
|
"/compound": "$compound",
|
|
14
15
|
"/craft-skill": "$craft-skill",
|
|
@@ -26,6 +27,7 @@ const CODEX_COMMAND_ALIASES: Record<string, string> = {
|
|
|
26
27
|
"/goal-checkin": "$goal-checkin",
|
|
27
28
|
"/goal-setting": "$goal-setting",
|
|
28
29
|
"/guide:capture": "$capture",
|
|
30
|
+
"/guide:claude-code": "$claude-code",
|
|
29
31
|
"/guide:codex": "$codex",
|
|
30
32
|
"/guide:gemini": "$gemini",
|
|
31
33
|
"/guide:pipeline": "$pipeline",
|