@heart-of-gold/toolkit 0.1.24 → 0.1.30
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 -9
- 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 +17 -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/README.md +11 -2
- package/plugins/guide/scripts/fetch-gmail.sh +88 -21
- package/plugins/marvin/.claude-plugin/plugin.json +1 -1
- package/plugins/marvin/README.md +23 -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/marvin/skills/share-html/SKILL.md +55 -0
- package/plugins/marvin/skills/share-html/scripts/healthcheck.sh +5 -0
- package/plugins/marvin/skills/share-html/scripts/publish.sh +101 -0
- package/plugins/marvin/skills/share-server-setup/SKILL.md +108 -0
- package/plugins/marvin/skills/share-server-setup/scripts/configure-existing-server.sh +38 -0
- package/plugins/marvin/skills/share-server-setup/scripts/configure-tailscale-viewer.sh +65 -0
- package/plugins/marvin/skills/share-server-setup/scripts/healthcheck.sh +44 -0
- package/plugins/marvin/skills/share-server-setup/scripts/install-launch-agent.sh +23 -0
- package/plugins/marvin/skills/share-server-setup/scripts/install-reference-server.sh +28 -0
- 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,15 @@ 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
|
|
42
|
+
- `/share` — publish an HTML file or static site directory through the portable `share-html` skill
|
|
43
|
+
- `/share-server-setup` — set up or adopt the local share server through the portable `share-server-setup` skill
|
|
41
44
|
- `/marvin-work` — start executing a plan (with always-on safety guardrails)
|
|
42
45
|
|
|
46
|
+
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.
|
|
47
|
+
|
|
48
|
+
For extension debugging, Pi also exposes `/deep-thought-guided-debug` to toggle notices explaining when a guided prompt was extracted, skipped, dismissed, or answered.
|
|
49
|
+
|
|
43
50
|
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
51
|
|
|
45
52
|
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,15 +97,18 @@ The unglamorous work that compounds.
|
|
|
90
97
|
|
|
91
98
|
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
99
|
|
|
93
|
-
|
|
100
|
+
9 skills · 2 agents · 3 knowledge files
|
|
94
101
|
|
|
95
102
|
```
|
|
96
|
-
/marvin:work
|
|
97
|
-
/marvin:quick-review
|
|
98
|
-
/marvin:compound
|
|
99
|
-
/marvin:redteam
|
|
100
|
-
/marvin:scaffold
|
|
101
|
-
/marvin:test-writer
|
|
103
|
+
/marvin:work # execute plans — implement, test, commit, ship
|
|
104
|
+
/marvin:quick-review # fast opinionated quality pass (simplicity, tests, correctness)
|
|
105
|
+
/marvin:compound # document solved problems for future reference
|
|
106
|
+
/marvin:redteam # adversarial review — find weaknesses, expose with failing tests
|
|
107
|
+
/marvin:scaffold # prepare project structure, configs, dependencies
|
|
108
|
+
/marvin:test-writer # write failing tests from user stories
|
|
109
|
+
/marvin:copy-editor # two-layer copy editor (typography audit + LLM judgment)
|
|
110
|
+
/marvin:share-server-setup # set up local artifact sharing infrastructure
|
|
111
|
+
/marvin:share-html # publish HTML/static output to a browser URL
|
|
102
112
|
```
|
|
103
113
|
|
|
104
114
|
### [Guide](plugins/guide/) — The Hitchhiker's Guide
|
|
@@ -172,6 +182,10 @@ bunx @heart-of-gold/toolkit list deep-thought
|
|
|
172
182
|
|
|
173
183
|
# Show supported targets
|
|
174
184
|
bunx @heart-of-gold/toolkit targets
|
|
185
|
+
|
|
186
|
+
# Manage the local share server reference implementation
|
|
187
|
+
bunx @heart-of-gold/toolkit share-server health
|
|
188
|
+
bunx @heart-of-gold/toolkit share-server install
|
|
175
189
|
```
|
|
176
190
|
|
|
177
191
|
## Release Safety
|
|
@@ -192,10 +206,11 @@ npm run check:compat
|
|
|
192
206
|
|
|
193
207
|
- **Codex/OpenCode/Pi**: Bun runtime (for `bunx`)
|
|
194
208
|
- **Claude Code**: No additional requirements
|
|
195
|
-
- **Guide plugin**: Python 3.10+, `feedparser`, `pyyaml`, `jq`, `curl`
|
|
209
|
+
- **Guide plugin**: Python 3.10+, `feedparser`, `pyyaml`, `jq`, `curl`, `zip`
|
|
196
210
|
- **Babel Fish audio**: ElevenLabs API key
|
|
197
211
|
- **Babel Fish image**: OpenRouter API key
|
|
198
212
|
- **iMessage delivery**: macOS (optional)
|
|
213
|
+
- **Private tailnet viewer exposure**: Tailscale CLI (optional)
|
|
199
214
|
|
|
200
215
|
## Acknowledgments
|
|
201
216
|
|
|
@@ -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
|
+
}
|