@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.
@@ -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.5"
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.5"
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.3"
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
- # Install shared skills into Pi's native skill directory
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heart-of-gold/toolkit",
3
- "version": "0.1.35",
3
+ "version": "0.1.36",
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": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "babel-fish",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "description": "Universal Translator — media generation tools for audio, image, video, and visualization",
5
5
  "author": {
6
6
  "name": "ondrej-svec",
@@ -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. compress and reshape the content into a stronger visual story
42
- 5. keep raw/source detail secondary or collapsible when possible
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. Generate one HTML artifact first when browser rendering will help.
154
- 6. Fall back to terminal rendering when browser/share is unavailable or explicitly not wanted.
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
- Visualization has two implementation layers:
195
- - `scripts/smart-render.js` — renders one HTML artifact using the mode the coding agent chose, with a safe fallback
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
- Use the helper script when the user wants a browser URL and the share server is already configured:
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deep-thought",
3
- "version": "0.2.5",
3
+ "version": "0.2.6",
4
4
  "description": "The Answer Computer — reasoning tools for brainstorming, planning, architecture design, and deep thinking",
5
5
  "author": {
6
6
  "name": "ondrej-svec",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "marvin",
3
- "version": "0.3.5",
3
+ "version": "0.3.6",
4
4
  "description": "The Paranoid Android — quality tools for code review, knowledge compounding, and work execution",
5
5
  "author": {
6
6
  "name": "ondrej-svec",
@@ -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(", ");