pi-gsd 1.6.2 → 1.6.3
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.
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* gsd-hooks.ts
|
|
3
|
-
* gsd-extension-version: 1.
|
|
2
|
+
* pi-gsd-hooks.ts — pi-gsd Extension
|
|
3
|
+
* pi-gsd-extension-version: 1.6.2
|
|
4
4
|
*
|
|
5
5
|
* Pi lifecycle extension for the Get Shit Done (GSD) workflow framework.
|
|
6
6
|
* Provides three non-blocking hooks:
|
|
@@ -128,7 +128,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
128
128
|
/\.env/,
|
|
129
129
|
/AGENTS\.md$/,
|
|
130
130
|
/settings\.json$/,
|
|
131
|
-
/gsd-hooks\.ts$/,
|
|
131
|
+
/pi-gsd-hooks\.ts$/,
|
|
132
132
|
];
|
|
133
133
|
if (allowed.some((p) => p.test(filePath))) return undefined;
|
|
134
134
|
|
|
@@ -517,7 +517,6 @@ export default function (pi: ExtensionAPI) {
|
|
|
517
517
|
},
|
|
518
518
|
});
|
|
519
519
|
|
|
520
|
-
|
|
521
520
|
// ── tool_result: context usage monitor ───────────────────────────────────
|
|
522
521
|
const WARNING_THRESHOLD = 35; // warn when remaining % ≤ 35
|
|
523
522
|
const CRITICAL_THRESHOLD = 25; // critical when remaining % ≤ 25
|
package/package.json
CHANGED
package/scripts/postinstall.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* Runs automatically after `npm install pi-gsd`.
|
|
6
6
|
* Copies the pi harness from this package's
|
|
7
7
|
* \`.gsd/harnesses/pi/\` into the consumer project's \`.pi/gsd/\`
|
|
8
|
-
* and installs the \`gsd-hooks.ts\` extension into \`.pi/extensions/\`.
|
|
8
|
+
* and installs the \`pi-gsd-hooks.ts\` extension into \`.pi/extensions/\`.
|
|
9
9
|
*
|
|
10
10
|
* Safe to re-run — files are skipped if already present (unless GSD_FORCE=1).
|
|
11
11
|
*/
|
|
@@ -219,7 +219,7 @@ function main() {
|
|
|
219
219
|
installed++;
|
|
220
220
|
}
|
|
221
221
|
|
|
222
|
-
// ── Pi extension (.pi/extensions/gsd-hooks.ts) ─────────────────────────────
|
|
222
|
+
// ── Pi extension (.pi/extensions/pi-gsd-hooks.ts) ─────────────────────────────
|
|
223
223
|
// Install the GSD pi lifecycle extension (session_start, tool_call, tool_result hooks).
|
|
224
224
|
// The extension is auto-discovered by pi from .pi/extensions/ - no manual wiring needed.
|
|
225
225
|
installPiExtension(PROJECT_ROOT, PKG_DIR, FORCE, (copied) => {
|
|
@@ -231,6 +231,7 @@ function main() {
|
|
|
231
231
|
// Prompts are served directly from the npm package (user scope).
|
|
232
232
|
// Local copies in .pi/prompts/ cause collision warnings on every pi update.
|
|
233
233
|
// Remove any gsd-*.md files previously installed there.
|
|
234
|
+
// Also remove the old gsd-hooks.ts if present (renamed to pi-gsd-hooks.ts).
|
|
234
235
|
const promptsDest = path.join(PROJECT_ROOT, ".pi", "prompts");
|
|
235
236
|
if (fs.existsSync(promptsDest)) {
|
|
236
237
|
const stale = fs
|
|
@@ -244,6 +245,14 @@ function main() {
|
|
|
244
245
|
);
|
|
245
246
|
}
|
|
246
247
|
}
|
|
248
|
+
const oldExt = path.join(PROJECT_ROOT, ".pi", "extensions", "gsd-hooks.ts");
|
|
249
|
+
if (fs.existsSync(oldExt)) {
|
|
250
|
+
fs.rmSync(oldExt);
|
|
251
|
+
log(
|
|
252
|
+
"ok",
|
|
253
|
+
".pi/extensions/gsd-hooks.ts (removed — renamed to pi-gsd-hooks.ts)",
|
|
254
|
+
);
|
|
255
|
+
}
|
|
247
256
|
|
|
248
257
|
console.log("");
|
|
249
258
|
|
|
@@ -303,17 +312,33 @@ function getPackageVersion() {
|
|
|
303
312
|
function installPiExtension(projectRoot, pkgDir, force, callback) {
|
|
304
313
|
const piDir = path.join(projectRoot, ".pi");
|
|
305
314
|
const extDir = path.join(piDir, "extensions");
|
|
306
|
-
const extDest = path.join(extDir, "gsd-hooks.ts");
|
|
307
|
-
const extSrc = path.join(pkgDir, ".gsd", "extensions", "gsd-hooks.ts");
|
|
315
|
+
const extDest = path.join(extDir, "pi-gsd-hooks.ts");
|
|
316
|
+
const extSrc = path.join(pkgDir, ".gsd", "extensions", "pi-gsd-hooks.ts");
|
|
308
317
|
|
|
309
318
|
if (!fs.existsSync(extSrc)) {
|
|
310
|
-
log("warn", ".pi/extensions/gsd-hooks.ts (source absent - skipped)");
|
|
319
|
+
log("warn", ".pi/extensions/pi-gsd-hooks.ts (source absent - skipped)");
|
|
311
320
|
callback(false);
|
|
312
321
|
return;
|
|
313
322
|
}
|
|
314
323
|
|
|
315
|
-
|
|
316
|
-
|
|
324
|
+
// Always update the extension — it is owned by pi-gsd, not the user.
|
|
325
|
+
// Compare pi-gsd-extension-version comments to detect staleness.
|
|
326
|
+
const extractVersion = (file) => {
|
|
327
|
+
try {
|
|
328
|
+
const match = fs
|
|
329
|
+
.readFileSync(file, "utf8")
|
|
330
|
+
.match(/pi-gsd-extension-version:\s*([\d.]+)/);
|
|
331
|
+
return match ? match[1] : null;
|
|
332
|
+
} catch {
|
|
333
|
+
return null;
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
const srcVersion = extractVersion(extSrc);
|
|
337
|
+
const destVersion = fs.existsSync(extDest) ? extractVersion(extDest) : null;
|
|
338
|
+
const needsUpdate = force || !destVersion || destVersion !== srcVersion;
|
|
339
|
+
|
|
340
|
+
if (!needsUpdate) {
|
|
341
|
+
log("skip", `.pi/extensions/pi-gsd-hooks.ts (up-to-date v${destVersion})`);
|
|
317
342
|
callback(false);
|
|
318
343
|
} else {
|
|
319
344
|
try {
|
|
@@ -321,13 +346,13 @@ function installPiExtension(projectRoot, pkgDir, force, callback) {
|
|
|
321
346
|
fs.copyFileSync(extSrc, extDest);
|
|
322
347
|
log(
|
|
323
348
|
"ok",
|
|
324
|
-
".pi/extensions/gsd-hooks.ts (GSD lifecycle extension installed)",
|
|
349
|
+
".pi/extensions/pi-gsd-hooks.ts (GSD lifecycle extension installed)",
|
|
325
350
|
);
|
|
326
351
|
callback(true);
|
|
327
352
|
} catch (e) {
|
|
328
353
|
log(
|
|
329
354
|
"warn",
|
|
330
|
-
".pi/extensions/gsd-hooks.ts (install failed: " + e.message + ")",
|
|
355
|
+
".pi/extensions/pi-gsd-hooks.ts (install failed: " + e.message + ")",
|
|
331
356
|
);
|
|
332
357
|
callback(false);
|
|
333
358
|
return;
|
|
@@ -352,9 +377,13 @@ function installPiExtension(projectRoot, pkgDir, force, callback) {
|
|
|
352
377
|
? settings.extensions
|
|
353
378
|
: [];
|
|
354
379
|
|
|
380
|
+
// Remove stale gsd-hooks.ts entry if present (renamed to pi-gsd-hooks.ts)
|
|
381
|
+
const oldExtPath = path.join(extDir, "gsd-hooks.ts");
|
|
382
|
+
const cleaned = extensions.filter((e) => e !== oldExtPath);
|
|
383
|
+
|
|
355
384
|
// Avoid duplicate entries
|
|
356
|
-
if (!
|
|
357
|
-
settings.extensions = [...
|
|
385
|
+
if (!cleaned.includes(extDest)) {
|
|
386
|
+
settings.extensions = [...cleaned, extDest];
|
|
358
387
|
fs.mkdirSync(piDir, { recursive: true });
|
|
359
388
|
fs.writeFileSync(
|
|
360
389
|
settingsFile,
|
|
@@ -362,6 +391,11 @@ function installPiExtension(projectRoot, pkgDir, force, callback) {
|
|
|
362
391
|
"utf8",
|
|
363
392
|
);
|
|
364
393
|
log("ok", ".pi/settings.json (extensions array updated)");
|
|
394
|
+
} else if (cleaned.length !== extensions.length) {
|
|
395
|
+
// Removed stale entry but extDest already present
|
|
396
|
+
settings.extensions = cleaned;
|
|
397
|
+
fs.writeFileSync(settingsFile, JSON.stringify(settings, null, "\t"), "utf8");
|
|
398
|
+
log("ok", ".pi/settings.json (removed stale gsd-hooks.ts entry)");
|
|
365
399
|
}
|
|
366
400
|
} catch (e) {
|
|
367
401
|
log("warn", ".pi/settings.json (could not update: " + e.message + ")");
|
|
@@ -4,7 +4,7 @@ description: Check and repair GSD hook wiring for pi. Use when postinstall was s
|
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
<objective>
|
|
7
|
-
Verify that the GSD pi extension (`gsd-hooks.ts`) is correctly installed in the current project.
|
|
7
|
+
Verify that the GSD pi extension (`pi-gsd-hooks.ts`) is correctly installed in the current project.
|
|
8
8
|
If the extension is missing, install it and update `.pi/settings.json`.
|
|
9
9
|
If already present, confirm hook wiring and report status.
|
|
10
10
|
Always route first-time users to `/gsd-new-project` at the end.
|
|
@@ -12,7 +12,7 @@ Always route first-time users to `/gsd-new-project` at the end.
|
|
|
12
12
|
|
|
13
13
|
<context>
|
|
14
14
|
**Why this skill exists:**
|
|
15
|
-
`bun install` does not run npm `postinstall` scripts, so `gsd-hooks.ts` may not be
|
|
15
|
+
`bun install` does not run npm `postinstall` scripts, so `pi-gsd-hooks.ts` may not be
|
|
16
16
|
automatically copied into the consumer project's `.pi/extensions/` directory.
|
|
17
17
|
This skill provides a manual fallback that performs the same wiring as `postinstall.js`.
|
|
18
18
|
|
|
@@ -23,34 +23,34 @@ This skill provides a manual fallback that performs the same wiring as `postinst
|
|
|
23
23
|
- `tool_result` → context-usage monitor with debounced warnings
|
|
24
24
|
|
|
25
25
|
**Extension source inside the pi-gsd package:**
|
|
26
|
-
`.gsd/extensions/gsd-hooks.ts`
|
|
26
|
+
`.gsd/extensions/pi-gsd-hooks.ts`
|
|
27
27
|
|
|
28
28
|
**Target location in the consumer project:**
|
|
29
|
-
`.pi/extensions/gsd-hooks.ts`
|
|
29
|
+
`.pi/extensions/pi-gsd-hooks.ts`
|
|
30
30
|
|
|
31
31
|
**settings.json entry (belt-and-suspenders - pi also auto-discovers from `.pi/extensions/`):**
|
|
32
|
-
`{ "extensions": ["<absolute-path-to-.pi/extensions/gsd-hooks.ts>"] }`
|
|
32
|
+
`{ "extensions": ["<absolute-path-to-.pi/extensions/pi-gsd-hooks.ts>"] }`
|
|
33
33
|
</context>
|
|
34
34
|
|
|
35
35
|
<process>
|
|
36
36
|
|
|
37
37
|
## Step 1 - Locate the pi-gsd package
|
|
38
38
|
|
|
39
|
-
Resolve the pi-gsd package root (where `gsd-hooks.ts` lives):
|
|
39
|
+
Resolve the pi-gsd package root (where `pi-gsd-hooks.ts` lives):
|
|
40
40
|
|
|
41
41
|
1. Try `node -e "console.log(require.resolve('pi-gsd/package.json'))"` - strip `/package.json` suffix to get PKG_DIR.
|
|
42
42
|
2. If that fails, try common global paths:
|
|
43
43
|
- `~/.bun/install/global/node_modules/pi-gsd`
|
|
44
44
|
- `/home/linuxbrew/.linuxbrew/lib/node_modules/pi-gsd`
|
|
45
45
|
- Output of `npm root -g` + `/pi-gsd`
|
|
46
|
-
3. Confirm the extension source exists at `<PKG_DIR>/.gsd/extensions/gsd-hooks.ts`.
|
|
46
|
+
3. Confirm the extension source exists at `<PKG_DIR>/.gsd/extensions/pi-gsd-hooks.ts`.
|
|
47
47
|
If the source cannot be found, report the error clearly and stop - do not proceed to Step 2.
|
|
48
48
|
|
|
49
49
|
## Step 2 - Check current project extension status
|
|
50
50
|
|
|
51
51
|
In the current working directory (the consumer project):
|
|
52
52
|
|
|
53
|
-
- **Check A:** Does `.pi/extensions/gsd-hooks.ts` exist?
|
|
53
|
+
- **Check A:** Does `.pi/extensions/pi-gsd-hooks.ts` exist?
|
|
54
54
|
- **Check B:** Does `.pi/settings.json` exist? If yes, does `extensions` array include an absolute path to the extension file?
|
|
55
55
|
- **Check C:** Does `.pi/extensions/` directory exist?
|
|
56
56
|
|
|
@@ -59,21 +59,21 @@ In the current working directory (the consumer project):
|
|
|
59
59
|
### If extension is MISSING (Check A failed):
|
|
60
60
|
|
|
61
61
|
1. Create `.pi/extensions/` directory if it does not exist.
|
|
62
|
-
2. Copy `<PKG_DIR>/.gsd/extensions/gsd-hooks.ts` → `.pi/extensions/gsd-hooks.ts`.
|
|
62
|
+
2. Copy `<PKG_DIR>/.gsd/extensions/pi-gsd-hooks.ts` → `.pi/extensions/pi-gsd-hooks.ts`.
|
|
63
63
|
3. Update `.pi/settings.json`:
|
|
64
|
-
- If the file does not exist, create it as `{ "extensions": ["<absolute-path>/.pi/extensions/gsd-hooks.ts"] }`.
|
|
64
|
+
- If the file does not exist, create it as `{ "extensions": ["<absolute-path>/.pi/extensions/pi-gsd-hooks.ts"] }`.
|
|
65
65
|
- If the file exists but `extensions` array is missing or does not include the path, add the absolute path.
|
|
66
66
|
- Preserve all other existing settings - merge, do not overwrite.
|
|
67
|
-
4. Report: `✓ GSD extension installed at .pi/extensions/gsd-hooks.ts`
|
|
67
|
+
4. Report: `✓ GSD extension installed at .pi/extensions/pi-gsd-hooks.ts`
|
|
68
68
|
5. Report: `✓ .pi/settings.json updated`
|
|
69
69
|
|
|
70
70
|
### If extension is PRESENT (Check A passed):
|
|
71
71
|
|
|
72
72
|
1. Confirm the file is non-empty (not a zero-byte stub).
|
|
73
|
-
2. Confirm it contains the marker comment `gsd-extension-version:` - indicating it is the genuine GSD extension, not a stale copy from another tool.
|
|
73
|
+
2. Confirm it contains the marker comment `pi-gsd-extension-version:` - indicating it is the genuine GSD extension, not a stale copy from another tool.
|
|
74
74
|
3. Check Check B - if `settings.json` is missing or the extension path is absent, add it now (same logic as missing case, step 3).
|
|
75
75
|
4. Report:
|
|
76
|
-
- `✓ GSD extension present at .pi/extensions/gsd-hooks.ts`
|
|
76
|
+
- `✓ GSD extension present at .pi/extensions/pi-gsd-hooks.ts`
|
|
77
77
|
- `✓ hooks: session_start (update-check), tool_call (workflow-guard), tool_result (context-monitor)`
|
|
78
78
|
- `✓ .pi/settings.json` - either "already registered" or "path added"
|
|
79
79
|
|
|
@@ -84,9 +84,9 @@ Print a concise status table:
|
|
|
84
84
|
```
|
|
85
85
|
GSD pi hook wiring status
|
|
86
86
|
──────────────────────────────────────────────────────────
|
|
87
|
-
Extension file .pi/extensions/gsd-hooks.ts ✓ / ✗
|
|
87
|
+
Extension file .pi/extensions/pi-gsd-hooks.ts ✓ / ✗
|
|
88
88
|
Settings entry .pi/settings.json extensions ✓ / ✗
|
|
89
|
-
Extension version gsd-extension-version: X.Y.Z (value)
|
|
89
|
+
Extension version pi-gsd-extension-version: X.Y.Z (value)
|
|
90
90
|
──────────────────────────────────────────────────────────
|
|
91
91
|
```
|
|
92
92
|
|