@heart-of-gold/toolkit 0.1.35 → 0.1.36
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 +3 -3
- package/README.md +7 -4
- package/package.json +1 -1
- package/plugins/babel-fish/.claude-plugin/plugin.json +1 -1
- package/plugins/babel-fish/skills/visualize/SKILL.md +70 -20
- package/plugins/babel-fish/skills/visualize/scripts/agent-artifact-template.html +169 -0
- package/plugins/babel-fish/skills/visualize/scripts/new-authored-artifact.sh +13 -0
- package/plugins/babel-fish/skills/visualize/scripts/publish-authored-html.sh +93 -0
- package/plugins/deep-thought/.claude-plugin/plugin.json +1 -1
- package/plugins/marvin/.claude-plugin/plugin.json +1 -1
- package/src/commands/install.ts +17 -1
|
@@ -15,19 +15,19 @@
|
|
|
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.2.
|
|
18
|
+
"version": "0.2.6"
|
|
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.3.
|
|
24
|
+
"version": "0.3.6"
|
|
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.2.
|
|
30
|
+
"version": "0.2.4"
|
|
31
31
|
},
|
|
32
32
|
{
|
|
33
33
|
"name": "quellis",
|
package/README.md
CHANGED
|
@@ -26,13 +26,16 @@ bunx @heart-of-gold/toolkit install --to opencode
|
|
|
26
26
|
|
|
27
27
|
### Pi Coding Agent
|
|
28
28
|
```bash
|
|
29
|
-
#
|
|
30
|
-
bunx @heart-of-gold/toolkit install --to pi
|
|
31
|
-
|
|
32
|
-
# Or install the package directly in Pi to get skills + pi-native extensions
|
|
29
|
+
# Option A: install the package directly in Pi to get skills + pi-native extensions
|
|
33
30
|
pi install npm:@heart-of-gold/toolkit
|
|
31
|
+
|
|
32
|
+
# Option B: install shared skills only into Pi's native skill directory
|
|
33
|
+
bunx @heart-of-gold/toolkit install --to pi
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
+
**Important:** choose one Pi install path or the other.
|
|
37
|
+
Do **not** use both the Pi package install and `install --to pi` at the same time, or Pi will report duplicate skill collisions on reload.
|
|
38
|
+
|
|
36
39
|
Pi also discovers skills from the shared `~/.agents/skills/` location, so installs done with the OpenCode target are usable from Pi too.
|
|
37
40
|
|
|
38
41
|
When installed as a Pi package, Heart of Gold exposes Pi-native extension commands for the flagship workflows:
|
package/package.json
CHANGED
|
@@ -21,6 +21,7 @@ Translating structured text into spatial understanding. The job is not to "turn
|
|
|
21
21
|
Create one clear, polished, shareable visual artifact that:
|
|
22
22
|
- matches the user's actual need
|
|
23
23
|
- feels intentionally designed, not markdown restyled in boxes
|
|
24
|
+
- is authored deliberately by the coding agent whenever possible
|
|
24
25
|
- summarizes before detailing
|
|
25
26
|
- uses browser HTML as the primary medium for substantial artifacts
|
|
26
27
|
- falls back to terminal rendering only when that is the better fit
|
|
@@ -34,12 +35,16 @@ Create one clear, polished, shareable visual artifact that:
|
|
|
34
35
|
|
|
35
36
|
Do **not** mirror the source document structure one-to-one unless the user explicitly wants a document view.
|
|
36
37
|
|
|
38
|
+
The coding agent should be the **author** of the visual artifact.
|
|
39
|
+
The renderer is a **finisher/fallback**, not the brain.
|
|
40
|
+
|
|
37
41
|
Instead:
|
|
38
42
|
1. understand the source
|
|
39
43
|
2. decide what the artifact is trying to communicate
|
|
40
44
|
3. choose the visual form that best serves that goal
|
|
41
|
-
4.
|
|
42
|
-
5.
|
|
45
|
+
4. author the HTML artifact directly when practical
|
|
46
|
+
5. use toolkit renderers only as helpers or fallback paths
|
|
47
|
+
6. keep raw/source detail secondary or collapsible when possible
|
|
43
48
|
|
|
44
49
|
HTML should feel like:
|
|
45
50
|
- a dashboard
|
|
@@ -150,8 +155,9 @@ When invoked, behave like a visual editor, not a format converter.
|
|
|
150
155
|
- UI/product visualization
|
|
151
156
|
3. Choose the best artifact family.
|
|
152
157
|
4. If uncertain, ask one concise question.
|
|
153
|
-
5.
|
|
154
|
-
6.
|
|
158
|
+
5. Prefer **agent-authored HTML** when browser rendering will help and the artifact needs real design judgment.
|
|
159
|
+
6. Use toolkit renderers as a fallback when a quick structured artifact is sufficient.
|
|
160
|
+
7. Fall back to terminal rendering when browser/share is unavailable or explicitly not wanted.
|
|
155
161
|
|
|
156
162
|
If the user says "you decide," choose the clearest non-gimmicky artifact, not the fanciest one.
|
|
157
163
|
|
|
@@ -189,12 +195,15 @@ If the user does not care or says "you decide," choose the safest useful mode:
|
|
|
189
195
|
- use `architecture` for clearly system-design-heavy docs
|
|
190
196
|
- use `mindmap` only when the artifact is genuinely concise and branchy
|
|
191
197
|
|
|
192
|
-
## Renderers
|
|
198
|
+
## Authoring & Renderers
|
|
193
199
|
|
|
194
|
-
|
|
195
|
-
-
|
|
200
|
+
Preferred implementation order:
|
|
201
|
+
- **Agent-authored HTML** — primary path for high-quality shareable artifacts
|
|
202
|
+
- `scripts/smart-render.js` — fallback renderer when the agent wants a quick scaffold or safe structured default
|
|
196
203
|
- `scripts/render-mindmap/index.js` — specialized mind-map renderer for branchy content
|
|
197
204
|
|
|
205
|
+
The key rule: if the artifact needs real design judgment, the coding agent should author the HTML directly instead of delegating the whole job to a parser.
|
|
206
|
+
|
|
198
207
|
**Locations:**
|
|
199
208
|
- `scripts/smart-render.js`
|
|
200
209
|
- `scripts/render-mindmap/index.js`
|
|
@@ -220,6 +229,23 @@ fi
|
|
|
220
229
|
|
|
221
230
|
## Usage
|
|
222
231
|
|
|
232
|
+
### Preferred: agent-authored HTML
|
|
233
|
+
|
|
234
|
+
When quality matters more than speed, start from the shared authored-artifact template, write the HTML directly, then publish it.
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
HTML_OUT="$(bash "$(dirname "$SCRIPT")/new-authored-artifact.sh")"
|
|
238
|
+
# edit the generated template at $HTML_OUT
|
|
239
|
+
bash "$(dirname "$SCRIPT")/publish-authored-html.sh" --url-only "$HTML_OUT"
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
Template and helper files:
|
|
243
|
+
- `scripts/agent-artifact-template.html`
|
|
244
|
+
- `scripts/new-authored-artifact.sh`
|
|
245
|
+
- `scripts/publish-authored-html.sh`
|
|
246
|
+
|
|
247
|
+
### Fallback: toolkit renderer
|
|
248
|
+
|
|
223
249
|
```bash
|
|
224
250
|
# Generate a safe default HTML visualization for a markdown file
|
|
225
251
|
node "$SCRIPT" path/to/file.md --out /tmp/view.html
|
|
@@ -236,7 +262,26 @@ node "$(dirname "$SCRIPT")/render-mindmap/index.js" --html /tmp/map.html path/to
|
|
|
236
262
|
|
|
237
263
|
## HTML Share Flow
|
|
238
264
|
|
|
239
|
-
|
|
265
|
+
### Preferred share flow: publish agent-authored HTML
|
|
266
|
+
|
|
267
|
+
Use this when the artifact needs stronger design judgment than the fallback renderer can provide.
|
|
268
|
+
|
|
269
|
+
1. Create the scaffold:
|
|
270
|
+
```bash
|
|
271
|
+
HTML_OUT="$(bash "$(dirname "$SCRIPT")/new-authored-artifact.sh")"
|
|
272
|
+
```
|
|
273
|
+
2. Author the HTML artifact directly into that file.
|
|
274
|
+
3. Publish it:
|
|
275
|
+
```bash
|
|
276
|
+
bash "$(dirname "$SCRIPT")/publish-authored-html.sh" --url-only "$HTML_OUT"
|
|
277
|
+
```
|
|
278
|
+
4. Read the returned URL from stdout.
|
|
279
|
+
5. Return that URL to the user as the primary result.
|
|
280
|
+
6. Briefly explain what was published and why this visual form was chosen.
|
|
281
|
+
|
|
282
|
+
### Fallback share flow: render then publish
|
|
283
|
+
|
|
284
|
+
Use the helper script when the user wants a browser URL and the fallback renderer is sufficient:
|
|
240
285
|
|
|
241
286
|
```bash
|
|
242
287
|
bash scripts/render-and-share.sh path/to/file.md
|
|
@@ -249,18 +294,6 @@ This script:
|
|
|
249
294
|
4. publishes the artifact to the configured local share server
|
|
250
295
|
5. prints the publish result so you can return the URL
|
|
251
296
|
|
|
252
|
-
### Recommended share flow
|
|
253
|
-
|
|
254
|
-
1. Verify or assume the input markdown is ready.
|
|
255
|
-
2. Choose the mode from context.
|
|
256
|
-
3. Run:
|
|
257
|
-
```bash
|
|
258
|
-
bash scripts/render-and-share.sh --mode <chosen-mode> --url-only [file]
|
|
259
|
-
```
|
|
260
|
-
4. Read the returned URL from stdout.
|
|
261
|
-
5. Return that URL to the user as the primary result.
|
|
262
|
-
6. Briefly explain what was published and why this mode was chosen.
|
|
263
|
-
|
|
264
297
|
If publishing fails because the share server is not configured, say so clearly and fall back to terminal rendering unless the user wants to stop and run `share-server-setup` first.
|
|
265
298
|
|
|
266
299
|
## Terminal Rendering
|
|
@@ -289,6 +322,23 @@ Many harness bash panels truncate long output and wrap wide content, breaking al
|
|
|
289
322
|
|
|
290
323
|
The default mode is vertical layout — boxes on main branches, compact leaves, about 40 chars wide.
|
|
291
324
|
|
|
325
|
+
## Agent-Authored HTML Workflow
|
|
326
|
+
|
|
327
|
+
When authoring HTML directly, follow this sequence:
|
|
328
|
+
|
|
329
|
+
1. Read the source and decide the artifact family.
|
|
330
|
+
2. Decide the audience and the first question the page should answer.
|
|
331
|
+
3. Create the scaffold with `new-authored-artifact.sh`.
|
|
332
|
+
4. Replace the template content with a real designed artifact.
|
|
333
|
+
5. Keep source detail secondary.
|
|
334
|
+
6. Publish with `publish-authored-html.sh`.
|
|
335
|
+
|
|
336
|
+
For plans specifically:
|
|
337
|
+
- do not dump the full task prose into the primary lanes
|
|
338
|
+
- summarize workstreams into short cards or task tiles
|
|
339
|
+
- show dependencies, risks, and acceptance separately
|
|
340
|
+
- keep raw markdown only in an appendix or disclosure block
|
|
341
|
+
|
|
292
342
|
## Required Output Structure
|
|
293
343
|
|
|
294
344
|
For substantial HTML artifacts, prefer this structure:
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
|
+
<title>Heart of Gold Visual Artifact</title>
|
|
7
|
+
<style>
|
|
8
|
+
:root {
|
|
9
|
+
--bg: #09111f;
|
|
10
|
+
--bg-2: #0f1a31;
|
|
11
|
+
--panel: rgba(255,255,255,0.06);
|
|
12
|
+
--panel-soft: rgba(255,255,255,0.04);
|
|
13
|
+
--text: #eef2ff;
|
|
14
|
+
--muted: #b8c0d9;
|
|
15
|
+
--muted-2: #91a1c2;
|
|
16
|
+
--border: rgba(255,255,255,0.11);
|
|
17
|
+
--accent: #7c9cff;
|
|
18
|
+
--accent-2: #80e0d0;
|
|
19
|
+
--success: #86efac;
|
|
20
|
+
--warn: #fbbf24;
|
|
21
|
+
--danger: #fca5a5;
|
|
22
|
+
--shadow: 0 24px 80px rgba(0,0,0,0.34);
|
|
23
|
+
--radius-xl: 28px;
|
|
24
|
+
--radius-lg: 20px;
|
|
25
|
+
--radius-md: 16px;
|
|
26
|
+
}
|
|
27
|
+
* { box-sizing: border-box; }
|
|
28
|
+
html, body { margin: 0; padding: 0; }
|
|
29
|
+
html { color-scheme: dark; }
|
|
30
|
+
body {
|
|
31
|
+
font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
|
32
|
+
line-height: 1.55;
|
|
33
|
+
color: var(--text);
|
|
34
|
+
background:
|
|
35
|
+
radial-gradient(circle at top left, rgba(124,156,255,0.18), transparent 32%),
|
|
36
|
+
radial-gradient(circle at top right, rgba(128,224,208,0.12), transparent 24%),
|
|
37
|
+
linear-gradient(180deg, var(--bg-2) 0%, var(--bg) 100%);
|
|
38
|
+
}
|
|
39
|
+
main { max-width: 1480px; margin: 0 auto; padding: 36px 22px 84px; }
|
|
40
|
+
.hero, .section, .rail-card, .card, .stat, .chip, .callout {
|
|
41
|
+
border: 1px solid var(--border);
|
|
42
|
+
box-shadow: var(--shadow);
|
|
43
|
+
backdrop-filter: blur(14px);
|
|
44
|
+
}
|
|
45
|
+
.hero, .section, .rail-card { background: var(--panel); }
|
|
46
|
+
.hero {
|
|
47
|
+
padding: 28px;
|
|
48
|
+
border-radius: 32px;
|
|
49
|
+
margin-bottom: 24px;
|
|
50
|
+
display: grid;
|
|
51
|
+
gap: 16px;
|
|
52
|
+
}
|
|
53
|
+
.eyebrow {
|
|
54
|
+
color: var(--accent-2);
|
|
55
|
+
text-transform: uppercase;
|
|
56
|
+
letter-spacing: 0.16em;
|
|
57
|
+
font-size: 12px;
|
|
58
|
+
font-weight: 700;
|
|
59
|
+
}
|
|
60
|
+
h1 { margin: 0; font-size: clamp(34px, 4vw, 62px); line-height: 1.02; text-wrap: balance; }
|
|
61
|
+
h2 { margin: 0 0 12px; font-size: clamp(22px, 2vw, 32px); text-wrap: balance; }
|
|
62
|
+
h3 { margin: 0 0 10px; font-size: 18px; }
|
|
63
|
+
p { margin: 0; color: var(--muted); }
|
|
64
|
+
.hero p { max-width: 78ch; font-size: 17px; }
|
|
65
|
+
.page { display: grid; grid-template-columns: minmax(0, 1fr) minmax(260px, 320px); gap: 24px; align-items: start; }
|
|
66
|
+
.rail { position: sticky; top: 16px; display: grid; gap: 16px; }
|
|
67
|
+
.rail-card, .section { padding: 22px; border-radius: var(--radius-xl); }
|
|
68
|
+
.section { margin-bottom: 20px; }
|
|
69
|
+
.grid-2, .grid-3, .grid-4, .lane-grid { display: grid; gap: 16px; }
|
|
70
|
+
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
|
71
|
+
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
|
|
72
|
+
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
|
|
73
|
+
.lane-grid { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
|
|
74
|
+
.card, .stat, .lane, .callout {
|
|
75
|
+
padding: 18px;
|
|
76
|
+
border-radius: var(--radius-md);
|
|
77
|
+
background: var(--panel-soft);
|
|
78
|
+
}
|
|
79
|
+
.label {
|
|
80
|
+
color: var(--accent-2);
|
|
81
|
+
text-transform: uppercase;
|
|
82
|
+
letter-spacing: 0.11em;
|
|
83
|
+
font-size: 12px;
|
|
84
|
+
margin-bottom: 8px;
|
|
85
|
+
}
|
|
86
|
+
.stat .value { font-size: 28px; font-weight: 700; color: var(--text); margin-top: 6px; }
|
|
87
|
+
.stat .hint { color: var(--muted-2); font-size: 13px; margin-top: 6px; }
|
|
88
|
+
.chip-row { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
|
|
89
|
+
.chip {
|
|
90
|
+
display: inline-flex; align-items: center; gap: 6px; padding: 8px 10px; border-radius: 999px;
|
|
91
|
+
background: rgba(255,255,255,0.05); color: var(--muted-2); font-size: 12px;
|
|
92
|
+
}
|
|
93
|
+
.chip.good { color: #c7ffd7; }
|
|
94
|
+
.chip.warn { color: #ffd88d; }
|
|
95
|
+
.chip.danger { color: #ffd1d1; }
|
|
96
|
+
details { margin-top: 12px; }
|
|
97
|
+
summary { cursor: pointer; font-weight: 600; }
|
|
98
|
+
.raw {
|
|
99
|
+
margin-top: 12px; padding: 14px; border-radius: 14px; border: 1px solid var(--border);
|
|
100
|
+
background: rgba(0,0,0,0.22); color: #d8e1fb; white-space: pre-wrap;
|
|
101
|
+
font: 13px/1.5 ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
102
|
+
}
|
|
103
|
+
a { color: #dce6ff; }
|
|
104
|
+
ul { margin: 0; padding-left: 18px; color: var(--muted); }
|
|
105
|
+
@media (max-width: 1080px) {
|
|
106
|
+
.page { grid-template-columns: 1fr; }
|
|
107
|
+
.rail { position: static; }
|
|
108
|
+
.grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
|
|
109
|
+
}
|
|
110
|
+
@media (max-width: 720px) {
|
|
111
|
+
main { padding: 20px 14px 60px; }
|
|
112
|
+
.hero, .section, .rail-card { padding: 18px; }
|
|
113
|
+
.grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
|
|
114
|
+
}
|
|
115
|
+
</style>
|
|
116
|
+
</head>
|
|
117
|
+
<body>
|
|
118
|
+
<main>
|
|
119
|
+
<section class="hero">
|
|
120
|
+
<div class="eyebrow">Artifact Family</div>
|
|
121
|
+
<h1>Title</h1>
|
|
122
|
+
<p>One-line framing that explains what this artifact is, why it matters, and how to read it.</p>
|
|
123
|
+
<div class="chip-row">
|
|
124
|
+
<span class="chip">Mode</span>
|
|
125
|
+
<span class="chip">Audience</span>
|
|
126
|
+
<span class="chip">Purpose</span>
|
|
127
|
+
</div>
|
|
128
|
+
</section>
|
|
129
|
+
|
|
130
|
+
<div class="page">
|
|
131
|
+
<section>
|
|
132
|
+
<section class="section">
|
|
133
|
+
<div class="label">Summary</div>
|
|
134
|
+
<h2>Start With the Story</h2>
|
|
135
|
+
<div class="grid-4">
|
|
136
|
+
<div class="stat"><div class="label">Stat</div><div class="value">4</div><div class="hint">What this number means</div></div>
|
|
137
|
+
<div class="stat"><div class="label">Stat</div><div class="value">18</div><div class="hint">What this number means</div></div>
|
|
138
|
+
<div class="stat"><div class="label">Stat</div><div class="value">11</div><div class="hint">What this number means</div></div>
|
|
139
|
+
<div class="stat"><div class="label">Stat</div><div class="value">2</div><div class="hint">What this number means</div></div>
|
|
140
|
+
</div>
|
|
141
|
+
</section>
|
|
142
|
+
|
|
143
|
+
<section class="section">
|
|
144
|
+
<div class="label">Main Body</div>
|
|
145
|
+
<h2>Transform the Source</h2>
|
|
146
|
+
<div class="grid-2">
|
|
147
|
+
<div class="card">
|
|
148
|
+
<div class="label">Use cards</div>
|
|
149
|
+
<p>Summaries, priorities, risks, decisions, and recommendations should be grouped into visual units rather than dumped as prose.</p>
|
|
150
|
+
</div>
|
|
151
|
+
<div class="card">
|
|
152
|
+
<div class="label">Use disclosure</div>
|
|
153
|
+
<p>Keep raw source detail secondary. Put it behind details/summary or a source appendix.</p>
|
|
154
|
+
</div>
|
|
155
|
+
</div>
|
|
156
|
+
</section>
|
|
157
|
+
</section>
|
|
158
|
+
|
|
159
|
+
<aside class="rail">
|
|
160
|
+
<section class="rail-card">
|
|
161
|
+
<div class="label">Rail</div>
|
|
162
|
+
<h3>Keep It Focused</h3>
|
|
163
|
+
<p>Use the right rail for compact metadata, jump links, or decision context — not for a massive table of contents.</p>
|
|
164
|
+
</section>
|
|
165
|
+
</aside>
|
|
166
|
+
</div>
|
|
167
|
+
</main>
|
|
168
|
+
</body>
|
|
169
|
+
</html>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
5
|
+
TEMPLATE="$SCRIPT_DIR/agent-artifact-template.html"
|
|
6
|
+
OUT_PATH="${1:-}"
|
|
7
|
+
|
|
8
|
+
if [[ -z "$OUT_PATH" ]]; then
|
|
9
|
+
OUT_PATH="$(mktemp /tmp/hog-visualize-artifact-XXXXXX.html)"
|
|
10
|
+
fi
|
|
11
|
+
|
|
12
|
+
cp "$TEMPLATE" "$OUT_PATH"
|
|
13
|
+
printf '%s\n' "$OUT_PATH"
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
5
|
+
HTML_PATH=""
|
|
6
|
+
SLUG=""
|
|
7
|
+
TITLE=""
|
|
8
|
+
ALIAS=""
|
|
9
|
+
URL_ONLY=0
|
|
10
|
+
|
|
11
|
+
usage() {
|
|
12
|
+
cat <<'EOF'
|
|
13
|
+
Usage: publish-authored-html.sh <html-file> [--slug STEM] [--title TITLE] [--alias ALIAS] [--url-only]
|
|
14
|
+
|
|
15
|
+
Publish an already-authored HTML artifact via share-html.
|
|
16
|
+
Use this when the coding agent wrote the HTML directly and only needs the share pipeline.
|
|
17
|
+
EOF
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
while [[ $# -gt 0 ]]; do
|
|
21
|
+
case "$1" in
|
|
22
|
+
--slug) SLUG="$2"; shift 2 ;;
|
|
23
|
+
--title) TITLE="$2"; shift 2 ;;
|
|
24
|
+
--alias) ALIAS="$2"; shift 2 ;;
|
|
25
|
+
--url-only) URL_ONLY=1; shift ;;
|
|
26
|
+
--help) usage; exit 0 ;;
|
|
27
|
+
--*) echo "Unknown argument: $1" >&2; exit 1 ;;
|
|
28
|
+
*)
|
|
29
|
+
if [[ -z "$HTML_PATH" ]]; then
|
|
30
|
+
HTML_PATH="$1"
|
|
31
|
+
shift
|
|
32
|
+
else
|
|
33
|
+
echo "Unexpected positional argument: $1" >&2
|
|
34
|
+
exit 1
|
|
35
|
+
fi
|
|
36
|
+
;;
|
|
37
|
+
esac
|
|
38
|
+
done
|
|
39
|
+
|
|
40
|
+
if [[ -z "$HTML_PATH" ]]; then
|
|
41
|
+
usage >&2
|
|
42
|
+
exit 1
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
if [[ ! -f "$HTML_PATH" ]]; then
|
|
46
|
+
echo "HTML file does not exist: $HTML_PATH" >&2
|
|
47
|
+
exit 1
|
|
48
|
+
fi
|
|
49
|
+
|
|
50
|
+
find_share_publish_script() {
|
|
51
|
+
local candidates=(
|
|
52
|
+
"$SCRIPT_DIR/../../share-html/scripts/publish.sh"
|
|
53
|
+
"$SCRIPT_DIR/../../../marvin/skills/share-html/scripts/publish.sh"
|
|
54
|
+
"$SCRIPT_DIR/../../../../marvin/skills/share-html/scripts/publish.sh"
|
|
55
|
+
"$HOME/.agents/skills/share-html/scripts/publish.sh"
|
|
56
|
+
"$HOME/.pi/agent/skills/share-html/scripts/publish.sh"
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
for candidate in "${candidates[@]}"; do
|
|
60
|
+
if [[ -f "$candidate" ]]; then
|
|
61
|
+
printf '%s\n' "$candidate"
|
|
62
|
+
return 0
|
|
63
|
+
fi
|
|
64
|
+
done
|
|
65
|
+
|
|
66
|
+
find "$(cd "$SCRIPT_DIR/../../../../.." && pwd)" -path '*/share-html/scripts/publish.sh' 2>/dev/null | head -1
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
PUBLISH_SCRIPT="$(find_share_publish_script)"
|
|
70
|
+
if [[ -z "$PUBLISH_SCRIPT" || ! -f "$PUBLISH_SCRIPT" ]]; then
|
|
71
|
+
echo '{"ok":false,"error":{"code":"MISSING_SHARE_HTML","message":"Could not find share-html publish.sh. Install the share-html skill first."}}'
|
|
72
|
+
exit 1
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
CMD=(bash "$PUBLISH_SCRIPT" "$HTML_PATH")
|
|
76
|
+
if [[ -n "$SLUG" ]]; then CMD+=(--slug "$SLUG"); fi
|
|
77
|
+
if [[ -n "$TITLE" ]]; then CMD+=(--title "$TITLE"); fi
|
|
78
|
+
if [[ -n "$ALIAS" ]]; then CMD+=(--alias "$ALIAS"); fi
|
|
79
|
+
|
|
80
|
+
PUBLISH_JSON="$(${CMD[@]})"
|
|
81
|
+
|
|
82
|
+
if [[ "$URL_ONLY" -eq 1 ]]; then
|
|
83
|
+
python3 - <<'PY' "$PUBLISH_JSON"
|
|
84
|
+
import json, sys
|
|
85
|
+
payload = json.loads(sys.argv[1])
|
|
86
|
+
if not payload.get("ok", True):
|
|
87
|
+
print(json.dumps(payload))
|
|
88
|
+
raise SystemExit(1)
|
|
89
|
+
print(payload.get("url") or payload.get("viewerUrl") or "")
|
|
90
|
+
PY
|
|
91
|
+
else
|
|
92
|
+
printf '%s\n' "$PUBLISH_JSON"
|
|
93
|
+
fi
|
package/src/commands/install.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { defineCommand } from "citty";
|
|
2
2
|
import { loadAllPlugins, loadPlugin } from "../parsers/claude";
|
|
3
3
|
import { targets } from "../targets/index";
|
|
4
|
-
import { resolve } from "path";
|
|
4
|
+
import { resolve, join } from "path";
|
|
5
|
+
import { existsSync } from "fs";
|
|
6
|
+
import { execSync } from "child_process";
|
|
5
7
|
|
|
6
8
|
export const installCommand = defineCommand({
|
|
7
9
|
meta: {
|
|
@@ -27,6 +29,20 @@ export const installCommand = defineCommand({
|
|
|
27
29
|
},
|
|
28
30
|
async run({ args }) {
|
|
29
31
|
const targetName = args.to;
|
|
32
|
+
|
|
33
|
+
if (targetName === "pi") {
|
|
34
|
+
try {
|
|
35
|
+
const npmRoot = execSync("npm root -g", { encoding: "utf8" }).trim();
|
|
36
|
+
const packagePath = join(npmRoot, "@heart-of-gold", "toolkit", "package.json");
|
|
37
|
+
if (existsSync(packagePath)) {
|
|
38
|
+
console.warn("Warning: @heart-of-gold/toolkit is already installed as a Pi package.");
|
|
39
|
+
console.warn("Using 'install --to pi' as well will create duplicate Pi skill collisions on reload.");
|
|
40
|
+
console.warn("Prefer one Pi install path: either 'pi install npm:@heart-of-gold/toolkit' or 'bunx @heart-of-gold/toolkit install --to pi'.\n");
|
|
41
|
+
}
|
|
42
|
+
} catch {
|
|
43
|
+
// ignore detection failures and proceed normally
|
|
44
|
+
}
|
|
45
|
+
}
|
|
30
46
|
const target = targets[targetName];
|
|
31
47
|
if (!target) {
|
|
32
48
|
const available = Object.keys(targets).join(", ");
|