@heart-of-gold/toolkit 0.1.23 → 0.1.29
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 +5 -5
- package/README.md +24 -11
- package/extensions/pi/architect.ts +23 -0
- package/extensions/pi/guided-workflows-core.js +147 -0
- package/extensions/pi/guided-workflows.ts +420 -0
- package/extensions/pi/index.ts +15 -0
- package/extensions/pi/share.ts +42 -0
- package/package.json +4 -1
- package/plugins/babel-fish/README.md +4 -1
- package/plugins/deep-thought/.claude-plugin/plugin.json +1 -1
- package/plugins/deep-thought/README.md +4 -1
- package/plugins/deep-thought/skills/expert-panel/SKILL.md +517 -0
- package/plugins/guide/.claude-plugin/plugin.json +1 -1
- package/plugins/guide/README.md +31 -2
- package/plugins/guide/skills/claude-code/SKILL.md +10 -10
- package/plugins/guide/skills/share-html/SKILL.md +55 -0
- package/plugins/guide/skills/share-html/scripts/healthcheck.sh +5 -0
- package/plugins/guide/skills/share-html/scripts/publish.sh +101 -0
- package/plugins/guide/skills/share-server-setup/SKILL.md +108 -0
- package/plugins/guide/skills/share-server-setup/scripts/configure-existing-server.sh +38 -0
- package/plugins/guide/skills/share-server-setup/scripts/configure-tailscale-viewer.sh +65 -0
- package/plugins/guide/skills/share-server-setup/scripts/healthcheck.sh +44 -0
- package/plugins/guide/skills/share-server-setup/scripts/install-launch-agent.sh +23 -0
- package/plugins/guide/skills/share-server-setup/scripts/install-reference-server.sh +28 -0
- package/plugins/marvin/.claude-plugin/plugin.json +1 -1
- package/plugins/marvin/README.md +17 -5
- package/plugins/marvin/skills/copy-editor/SKILL.md +300 -0
- package/plugins/marvin/skills/copy-editor/knowledge/ROLE.md +186 -0
- package/plugins/marvin/skills/copy-editor/knowledge/config-schema.md +166 -0
- package/plugins/marvin/skills/copy-editor/knowledge/language-profiles.md +138 -0
- package/plugins/marvin/skills/copy-editor/knowledge/lockfile-schema.md +259 -0
- package/plugins/marvin/skills/copy-editor/knowledge/output-contract.md +191 -0
- package/plugins/marvin/skills/copy-editor/knowledge/segmentation-prompt-v1.md +398 -0
- package/plugins/marvin/skills/copy-editor/knowledge/segmentation-prompt-v2.md +340 -0
- package/plugins/marvin/skills/copy-editor/knowledge/segmentation.md +165 -0
- package/plugins/marvin/skills/copy-editor/rules/czech.ts +482 -0
- package/plugins/marvin/skills/copy-editor/rules/english.ts +64 -0
- package/plugins/marvin/skills/copy-editor/rules/index.ts +29 -0
- package/plugins/marvin/skills/copy-editor/rules/types.ts +130 -0
- package/plugins/marvin/skills/copy-editor/scripts/copy-audit.ts +1527 -0
- package/plugins/marvin/skills/copy-editor/scripts/finding-filter.ts +51 -0
- package/plugins/marvin/skills/copy-editor/scripts/lockfile.ts +363 -0
- package/plugins/marvin/skills/copy-editor/scripts/self-test.ts +778 -0
- package/plugins/marvin/skills/redteam/SKILL.md +0 -22
- package/plugins/quellis/README.md +11 -2
- package/plugins/quellis/knowledge/coaching-frameworks.md +157 -14
- package/plugins/quellis/plugin.json +2 -1
- package/plugins/quellis/skills/coach/SKILL.md +269 -29
- package/plugins/quellis/skills/goal-checkin/SKILL.md +41 -11
- package/plugins/quellis/skills/goal-setting/SKILL.md +74 -30
- package/plugins/quellis/skills/reflect/SKILL.md +92 -20
- package/share-server/README.md +138 -0
- package/share-server/package.json +7 -0
- package/share-server/src/config.ts +65 -0
- package/share-server/src/index.ts +276 -0
- package/share-server/src/publish.ts +131 -0
- package/share-server/src/storage.ts +98 -0
- package/share-server/src/types.ts +39 -0
- package/share-server/src/viewer.ts +56 -0
- package/src/commands/share-server.ts +105 -0
- package/src/index.ts +3 -1
|
@@ -9,31 +9,31 @@
|
|
|
9
9
|
"name": "guide",
|
|
10
10
|
"source": "./plugins/guide",
|
|
11
11
|
"description": "The Hitchhiker's Guide — content creation suite with automated pipeline, daily briefs, and blog writing",
|
|
12
|
-
"version": "0.
|
|
12
|
+
"version": "0.3.0"
|
|
13
13
|
},
|
|
14
14
|
{
|
|
15
15
|
"name": "deep-thought",
|
|
16
16
|
"source": "./plugins/deep-thought",
|
|
17
17
|
"description": "The Answer Computer — reasoning tools for brainstorming, planning, and deep thinking",
|
|
18
|
-
"version": "0.
|
|
18
|
+
"version": "0.2.2"
|
|
19
19
|
},
|
|
20
20
|
{
|
|
21
21
|
"name": "marvin",
|
|
22
22
|
"source": "./plugins/marvin",
|
|
23
23
|
"description": "The Paranoid Android — quality tools for code review, knowledge compounding, and work execution",
|
|
24
|
-
"version": "0.
|
|
24
|
+
"version": "0.3.0"
|
|
25
25
|
},
|
|
26
26
|
{
|
|
27
27
|
"name": "babel-fish",
|
|
28
28
|
"source": "./plugins/babel-fish",
|
|
29
29
|
"description": "Universal Translator — media generation tools for audio, image, and video content",
|
|
30
|
-
"version": "0.
|
|
30
|
+
"version": "0.2.0"
|
|
31
31
|
},
|
|
32
32
|
{
|
|
33
33
|
"name": "quellis",
|
|
34
34
|
"source": "./plugins/quellis",
|
|
35
35
|
"description": "AI Coaching Companion — ICF methodology, powerful questions, goal-setting, and reflection",
|
|
36
|
-
"version": "0.
|
|
36
|
+
"version": "0.3.0"
|
|
37
37
|
}
|
|
38
38
|
]
|
|
39
39
|
}
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> **Don't Panic.**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
30 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
|
|
|
@@ -38,8 +38,13 @@ Pi also discovers skills from the shared `~/.agents/skills/` location, so instal
|
|
|
38
38
|
When installed as a Pi package, Heart of Gold exposes Pi-native extension commands for the flagship workflows:
|
|
39
39
|
- `/deep-thought-brainstorm` — start a brainstorm (collaborative discovery)
|
|
40
40
|
- `/deep-thought-plan` — start planning (research and produce a plan document)
|
|
41
|
+
- `/deep-thought-architect` — turn brainstorm decisions into stories and architecture docs
|
|
41
42
|
- `/marvin-work` — start executing a plan (with always-on safety guardrails)
|
|
42
43
|
|
|
44
|
+
Pi package installs also include a Pi-only guided workflow enhancer for supported Heart of Gold skills. For `brainstorm`, `plan`, and `architect`, when the assistant asks a high-confidence structured question, Pi can upgrade it into a custom interactive TUI and feed the answer back into the same workflow. Shared skills remain plain-text portable in every other harness.
|
|
45
|
+
|
|
46
|
+
For extension debugging, Pi also exposes `/deep-thought-guided-debug` to toggle notices explaining when a guided prompt was extracted, skipped, dismissed, or answered.
|
|
47
|
+
|
|
43
48
|
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
49
|
|
|
45
50
|
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`.
|
|
@@ -90,7 +95,7 @@ The unglamorous work that compounds.
|
|
|
90
95
|
|
|
91
96
|
Execute plans task by task with tests after every change. Quick-review code with an emphasis on simplicity — catch YAGNI violations, premature abstractions, and code that solves problems that don't exist yet. Document solutions so the next person doesn't waste time re-discovering what you already figured out.
|
|
92
97
|
|
|
93
|
-
|
|
98
|
+
7 skills · 2 agents · 3 knowledge files
|
|
94
99
|
|
|
95
100
|
```
|
|
96
101
|
/marvin:work # execute plans — implement, test, commit, ship
|
|
@@ -99,6 +104,7 @@ Execute plans task by task with tests after every change. Quick-review code with
|
|
|
99
104
|
/marvin:redteam # adversarial review — find weaknesses, expose with failing tests
|
|
100
105
|
/marvin:scaffold # prepare project structure, configs, dependencies
|
|
101
106
|
/marvin:test-writer # write failing tests from user stories
|
|
107
|
+
/marvin:copy-editor # two-layer copy editor (typography audit + LLM judgment)
|
|
102
108
|
```
|
|
103
109
|
|
|
104
110
|
### [Guide](plugins/guide/) — The Hitchhiker's Guide
|
|
@@ -107,16 +113,18 @@ Your personal content engine.
|
|
|
107
113
|
|
|
108
114
|
Configurable sources (RSS, Gmail, HN, web search), narrative briefs, LinkedIn drafts, blog outlines, voice fidelity checking, iMessage delivery, and two-way captures.
|
|
109
115
|
|
|
110
|
-
|
|
116
|
+
9 skills · 2 agents · 5 scripts
|
|
111
117
|
|
|
112
118
|
```
|
|
113
|
-
/guide:setup
|
|
114
|
-
/guide:pipeline
|
|
115
|
-
/guide:capture
|
|
116
|
-
/guide:write-post
|
|
117
|
-
/guide:
|
|
118
|
-
/guide:
|
|
119
|
-
/guide:
|
|
119
|
+
/guide:setup # configure your sources, themes, and voice
|
|
120
|
+
/guide:pipeline # run the full content engine
|
|
121
|
+
/guide:capture # morning/evening thought capture
|
|
122
|
+
/guide:write-post # guided blog writing (7 phases)
|
|
123
|
+
/guide:share-server-setup # set up local artifact sharing infrastructure
|
|
124
|
+
/guide:share-html # publish HTML/static output to a browser URL
|
|
125
|
+
/guide:claude-code # Claude Code CLI guidance
|
|
126
|
+
/guide:codex # Codex CLI guidance
|
|
127
|
+
/guide:gemini # Gemini CLI guidance
|
|
120
128
|
```
|
|
121
129
|
|
|
122
130
|
### [Babel Fish](plugins/babel-fish/) — Universal Translator
|
|
@@ -172,6 +180,10 @@ bunx @heart-of-gold/toolkit list deep-thought
|
|
|
172
180
|
|
|
173
181
|
# Show supported targets
|
|
174
182
|
bunx @heart-of-gold/toolkit targets
|
|
183
|
+
|
|
184
|
+
# Manage the local share server reference implementation
|
|
185
|
+
bunx @heart-of-gold/toolkit share-server health
|
|
186
|
+
bunx @heart-of-gold/toolkit share-server install
|
|
175
187
|
```
|
|
176
188
|
|
|
177
189
|
## Release Safety
|
|
@@ -192,10 +204,11 @@ npm run check:compat
|
|
|
192
204
|
|
|
193
205
|
- **Codex/OpenCode/Pi**: Bun runtime (for `bunx`)
|
|
194
206
|
- **Claude Code**: No additional requirements
|
|
195
|
-
- **Guide plugin**: Python 3.10+, `feedparser`, `pyyaml`, `jq`, `curl`
|
|
207
|
+
- **Guide plugin**: Python 3.10+, `feedparser`, `pyyaml`, `jq`, `curl`, `zip`
|
|
196
208
|
- **Babel Fish audio**: ElevenLabs API key
|
|
197
209
|
- **Babel Fish image**: OpenRouter API key
|
|
198
210
|
- **iMessage delivery**: macOS (optional)
|
|
211
|
+
- **Private tailnet viewer exposure**: Tailscale CLI (optional)
|
|
199
212
|
|
|
200
213
|
## Acknowledgments
|
|
201
214
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
2
|
+
|
|
3
|
+
export default function architectExtension(pi: ExtensionAPI) {
|
|
4
|
+
pi.registerCommand("deep-thought-architect", {
|
|
5
|
+
description: "Start architect — turn brainstorm decisions into stories and architecture docs",
|
|
6
|
+
handler: async (args, ctx) => {
|
|
7
|
+
const source =
|
|
8
|
+
args.trim() || (ctx.hasUI ? (await ctx.ui.editor("Architect input (feature or brainstorm path)", ""))?.trim() : undefined);
|
|
9
|
+
if (!source) {
|
|
10
|
+
ctx.ui.notify("Usage: /deep-thought-architect <feature or brainstorm path>", "info");
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const prompt = `/skill:architect ${source}`;
|
|
15
|
+
if (ctx.isIdle()) {
|
|
16
|
+
pi.sendUserMessage(prompt);
|
|
17
|
+
} else {
|
|
18
|
+
pi.sendUserMessage(prompt, { deliverAs: "followUp" });
|
|
19
|
+
ctx.ui.notify("Architect queued as follow-up", "info");
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
export const WORKFLOW_PATTERNS = [
|
|
2
|
+
{ workflow: "brainstorm", pattern: /^\/(?:skill:brainstorm|brainstorm|deep-thought:brainstorm|deep-thought-brainstorm)\b/i },
|
|
3
|
+
{ workflow: "plan", pattern: /^\/(?:skill:plan|plan|deep-thought:plan|deep-thought-plan)\b/i },
|
|
4
|
+
{ workflow: "architect", pattern: /^\/(?:skill:architect|architect|deep-thought:architect|deep-thought-architect)\b/i },
|
|
5
|
+
];
|
|
6
|
+
|
|
7
|
+
export const RESET_COMMAND_PATTERN =
|
|
8
|
+
/^\/(?!(?:skill:brainstorm|brainstorm|deep-thought:brainstorm|deep-thought-brainstorm|skill:plan|plan|deep-thought:plan|deep-thought-plan|skill:architect|architect|deep-thought:architect|deep-thought-architect)\b)\S+/i;
|
|
9
|
+
|
|
10
|
+
export function normalizeInline(text) {
|
|
11
|
+
return String(text)
|
|
12
|
+
.replace(/\*\*(.*?)\*\*/g, "$1")
|
|
13
|
+
.replace(/__(.*?)__/g, "$1")
|
|
14
|
+
.replace(/`([^`]+)`/g, "$1")
|
|
15
|
+
.replace(/\s+/g, " ")
|
|
16
|
+
.trim();
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function detectWorkflow(text) {
|
|
20
|
+
const trimmed = String(text).trim();
|
|
21
|
+
for (const { workflow, pattern } of WORKFLOW_PATTERNS) {
|
|
22
|
+
if (pattern.test(trimmed)) return workflow;
|
|
23
|
+
}
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function parseExtractionEnvelope(text) {
|
|
28
|
+
try {
|
|
29
|
+
let json = String(text).trim();
|
|
30
|
+
const codeBlock = json.match(/```(?:json)?\s*([\s\S]*?)```/i);
|
|
31
|
+
if (codeBlock) json = codeBlock[1].trim();
|
|
32
|
+
const parsed = JSON.parse(json);
|
|
33
|
+
if (!parsed || typeof parsed !== "object" || typeof parsed.kind !== "string") return null;
|
|
34
|
+
if (parsed.kind === "none") return parsed;
|
|
35
|
+
if (parsed.kind !== "single_choice" && parsed.kind !== "text") return null;
|
|
36
|
+
if (typeof parsed.question !== "string" || parsed.question.trim() === "") return null;
|
|
37
|
+
if (parsed.kind === "single_choice") {
|
|
38
|
+
if (!Array.isArray(parsed.options) || parsed.options.length < 2 || parsed.options.length > 5) return null;
|
|
39
|
+
}
|
|
40
|
+
return parsed;
|
|
41
|
+
} catch {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function splitQuestionAndContext(lines, optionStartIndex) {
|
|
47
|
+
const prior = lines.slice(0, optionStartIndex).map((line) => normalizeInline(line)).filter(Boolean);
|
|
48
|
+
if (prior.length === 0) return { question: "Choose an option" };
|
|
49
|
+
|
|
50
|
+
let question = prior[prior.length - 1];
|
|
51
|
+
let contextLines = prior.slice(0, -1);
|
|
52
|
+
|
|
53
|
+
for (let i = prior.length - 1; i >= 0; i--) {
|
|
54
|
+
const line = prior[i];
|
|
55
|
+
if (line.endsWith("?") || line.endsWith(":")) {
|
|
56
|
+
question = line.replace(/:$/, "");
|
|
57
|
+
contextLines = prior.slice(Math.max(0, i - 2), i);
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return { question, context: contextLines.join(" ").trim() || undefined };
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function heuristicExtractOptions(text) {
|
|
66
|
+
const lines = String(text).split(/\r?\n/);
|
|
67
|
+
const options = [];
|
|
68
|
+
let optionStartIndex = -1;
|
|
69
|
+
|
|
70
|
+
for (let i = 0; i < lines.length; i++) {
|
|
71
|
+
const line = lines[i].trim();
|
|
72
|
+
const match = line.match(/^(\d+\.|[-*])\s+(.*)$/);
|
|
73
|
+
if (!match) {
|
|
74
|
+
if (options.length > 0) break;
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
if (optionStartIndex === -1) optionStartIndex = i;
|
|
78
|
+
const body = normalizeInline(match[2]);
|
|
79
|
+
const parts = body.split(/\s+[—-]\s+/);
|
|
80
|
+
const label = parts[0]?.trim();
|
|
81
|
+
const description = parts.slice(1).join(" — ").trim() || undefined;
|
|
82
|
+
if (!label) break;
|
|
83
|
+
options.push({ label, description });
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (optionStartIndex === -1 || options.length < 2 || options.length > 5) return null;
|
|
87
|
+
const { question, context } = splitQuestionAndContext(lines, optionStartIndex);
|
|
88
|
+
return { kind: "single_choice", question, context, options, confidence: "medium" };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function heuristicExtractText(text) {
|
|
92
|
+
const lines = String(text)
|
|
93
|
+
.split(/\r?\n/)
|
|
94
|
+
.map((line) => normalizeInline(line))
|
|
95
|
+
.filter(Boolean);
|
|
96
|
+
|
|
97
|
+
for (let i = lines.length - 1; i >= 0; i--) {
|
|
98
|
+
const line = lines[i];
|
|
99
|
+
if (!line.endsWith("?")) continue;
|
|
100
|
+
if (/^(if|when|otherwise|for example)\b/i.test(line)) continue;
|
|
101
|
+
return {
|
|
102
|
+
kind: "text",
|
|
103
|
+
question: line,
|
|
104
|
+
context: lines.slice(Math.max(0, i - 2), i).join(" ").trim() || undefined,
|
|
105
|
+
confidence: "low",
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export function heuristicExtractPrompt(text) {
|
|
113
|
+
return heuristicExtractOptions(text) ?? heuristicExtractText(text) ?? { kind: "none", reason: "no clear prompt", confidence: "low" };
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function coerceExtractedPrompt(workflow, extracted) {
|
|
117
|
+
if (!extracted || extracted.kind === "none") return null;
|
|
118
|
+
if (extracted.confidence === "low") return null;
|
|
119
|
+
|
|
120
|
+
if (extracted.kind === "single_choice") {
|
|
121
|
+
const options = (extracted.options ?? [])
|
|
122
|
+
.filter((option) => option && typeof option.label === "string" && option.label.trim() !== "")
|
|
123
|
+
.map((option) => ({
|
|
124
|
+
label: normalizeInline(option.label),
|
|
125
|
+
description: option.description ? normalizeInline(option.description) : undefined,
|
|
126
|
+
}));
|
|
127
|
+
if (options.length < 2 || options.length > 5) return null;
|
|
128
|
+
return {
|
|
129
|
+
kind: "single_choice",
|
|
130
|
+
workflow,
|
|
131
|
+
question: normalizeInline(extracted.question),
|
|
132
|
+
context: extracted.context ? normalizeInline(extracted.context) : undefined,
|
|
133
|
+
options,
|
|
134
|
+
answerInstruction: extracted.answerInstruction ? normalizeInline(extracted.answerInstruction) : undefined,
|
|
135
|
+
confidence: extracted.confidence,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
kind: "text",
|
|
141
|
+
workflow,
|
|
142
|
+
question: normalizeInline(extracted.question),
|
|
143
|
+
context: extracted.context ? normalizeInline(extracted.context) : undefined,
|
|
144
|
+
answerInstruction: extracted.answerInstruction ? normalizeInline(extracted.answerInstruction) : undefined,
|
|
145
|
+
confidence: extracted.confidence,
|
|
146
|
+
};
|
|
147
|
+
}
|