pi-crew 0.9.47 → 0.9.48

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/CHANGELOG.md CHANGED
@@ -3,6 +3,29 @@
3
3
  > **Note:** `atomic-write-v2.ts` / `AtomicWriter` mentioned in historical entries below was consolidated into `atomic-write.ts` as of v0.9.42. This changelog is preserved as historical record — the migration was completed (the v2 class was never adopted; v1 won on simplicity + symlink-safety + link+unlink atomicity). See `docs/migration/atomic-write-v2-migration.md` for the decision rationale.
4
4
 
5
5
 
6
+ ## [0.9.48] — Fix postinstall skill-collision regression (2026-07-24)
7
+
8
+ Removes the `copySkills()` postinstall step introduced in v0.9.47. That step
9
+ redundantly copied every `skills/<name>/` to `~/.pi/agent/skills/`, but **Pi
10
+ already discovers skills natively from the npm package dir**
11
+ (`~/.pi/agent/npm/node_modules/pi-crew/skills/`). The duplication caused 31
12
+ "skill collision" warnings on every Pi startup (user-level copy shadowing the
13
+ package version).
14
+
15
+ - **`scripts/postinstall.mjs`**: `copySkills()` **removed**. Replaced with
16
+ `cleanupStaleSkillCopies()`, a one-time migration that removes the stale
17
+ copies created by v0.9.47's `copySkills()` — but **only byte-identical**
18
+ copies (a skill the user has customized is preserved). On upgrade, this
19
+ silently removes the 31 stale copies and clears the collisions. Verified:
20
+ 31 identical→remove, `pi-fork-sync` (user-only) untouched.
21
+
22
+ ### Verification
23
+
24
+ - `npm run test:critical` → 97/97 pass.
25
+ - Cleanup dry-run: 31/31 stale copies identified as byte-identical → safe removal.
26
+ - User-only skill (`pi-fork-sync`) correctly preserved.
27
+
28
+
6
29
  ## [0.9.47] — Broker Phase 4 gated ON (default-on flip) (2026-07-22)
7
30
 
8
31
  Flips `broker.enabled` from `false` to `true` as the new default on Linux
@@ -41,10 +64,10 @@ native Windows). Three independent kill switches remain available:
41
64
  sync → live TUI probing via tmux/pty → smoke team run). 659 lines, 26
42
65
  sections, 15 triggers. Bundled `scripts/pty_probe.py` (174-line hardened
43
66
  TUI probe with zombie reaping).
44
- - **`scripts/postinstall.mjs`**: new `copySkills()` step mirrors every
45
- `skills/<name>/` dir to `~/.pi/agent/skills/` on install, so pi-crew's
46
- skills are available globally (not just inside the pi-crew project).
47
- Best-effort, never fails the install.
67
+ - **`scripts/postinstall.mjs`**: ~~new `copySkills()` step mirrors every
68
+ `skills/<name>/` dir to `~/.pi/agent/skills/`~~ **(reverted in v0.9.48 —
69
+ Pi discovers skills natively from the npm package; copying only created
70
+ collision warnings).** See v0.9.48 below.
48
71
 
49
72
  ### Verification
50
73
 
package/README.md CHANGED
@@ -291,7 +291,7 @@ The advisory is **informational only** — there is no `force:true` flag needed
291
291
  - **Broker default-on**: `broker.enabled` flipped `false` → `true` on Linux + macOS. The inter-pi broker lets concurrent Pi sessions exchange messages, steering notes, and task-status events over a Unix-domain socket. Three kill switches remain: config `broker.enabled: false`, env `PI_CREW_BROKER=0` (always wins), Windows auto-disable.
292
292
  - **Verifier-hang fix**: `npm run test:critical` — a curated 14-file / 97-test subset (~20s) replaces full `npm test` (>4 min) in verifier prompts. The full suite was exceeding the 300s `RESPONSE_TIMEOUT_MS`, killing workers with exit 143. Both plan-templates and all 4 workflow verifier prompts now specify the fast command.
293
293
  - **`real-test-pi-crew` skill** (659 lines): distills the 8-tier verification discipline used to ship this release (critical tests → 3-path kill-switch proof → typecheck/bundle → bundle md5 sync → live TUI probing via tmux/pty → smoke team run). Bundled `scripts/pty_probe.py`.
294
- - **Postinstall `copySkills()`**: `npx pi install .` now mirrors every `skills/<name>/` to `~/.pi/agent/skills/` for global availability.
294
+ - **Postinstall skill-collision fix**: v0.9.47's `copySkills()` (which mirrored skills to `~/.pi/agent/skills/`) caused 31 "collision" warnings — Pi already discovers skills natively from the npm package. v0.9.48 removes `copySkills()` and adds a safe byte-identical cleanup (`cleanupStaleSkillCopies()`) that clears the stale copies on upgrade. User-customized skills are preserved.
295
295
  - See [CHANGELOG.md](CHANGELOG.md) §0.9.47 and [docs/decisions/2026-07-22-broker-phase4-gated-on.md](docs/decisions/2026-07-22-broker-phase4-gated-on.md).
296
296
 
297
297
  ### v0.9.45 – v0.9.46 (2026-07-20): security + perf remediation, UI stability
@@ -71,8 +71,11 @@ pi install npm:pi-crew
71
71
  1. Builds the ESM bundle (`scripts/build-bundle.mjs`) — best-effort, falls
72
72
  back to strip-types loading if esbuild is missing.
73
73
  2. Installs the bundled `crew-vibes.ttf` font into the user fonts directory.
74
- 3. Copies every `skills/<name>/` dir to `~/.pi/agent/skills/` so pi-crew's
75
- skills are available globally (not just inside the pi-crew project).
74
+ 3. Runs `cleanupStaleSkillCopies()` — a one-time migration that removes
75
+ stale skill copies from `~/.pi/agent/skills/` left by v0.9.47's (now-removed)
76
+ `copySkills()` step. Only removes **byte-identical** copies; user-customized
77
+ skills are preserved. Pi discovers skills natively from the npm package's
78
+ own `skills/` dir, so copies are never needed.
76
79
 
77
80
  All three steps are best-effort and never fail the install.
78
81
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-crew",
3
- "version": "0.9.47",
3
+ "version": "0.9.48",
4
4
  "description": "Pi extension for coordinated AI teams, workflows, worktrees, and async task orchestration",
5
5
  "author": "baphuongna",
6
6
  "license": "MIT",
@@ -6,13 +6,17 @@
6
6
  * let Pi fall back to strip-types loading).
7
7
  * 2. Install the bundled crew-vibes.ttf into the user fonts directory so
8
8
  * the crew-vibes speed/capacity PUA glyphs render.
9
- * 3. Copy bundled skills to ~/.pi/agent/skills/ so they are available
10
- * globally (not just inside the pi-crew project).
9
+ * 3. Remove stale skill copies from ~/.pi/agent/skills/ (migration from
10
+ * the v0.9.47 copySkills() bug — see cleanupStaleSkillCopies()).
11
11
  *
12
12
  * Replaces the old `postinstall` shell chain so the font install runs on
13
13
  * every platform without relying on shell-specific chaining (`;`/`&&`).
14
+ *
15
+ * NOTE: skills are NOT copied here. Pi discovers skills natively from the
16
+ * npm package dir (`~/.pi/agent/npm/node_modules/pi-crew/skills/`); copying
17
+ * them to ~/.pi/agent/skills/ only creates duplicate "collision" warnings.
14
18
  */
15
- import { cpSync, existsSync, mkdirSync, readdirSync } from "node:fs";
19
+ import { existsSync, readFileSync, readdirSync, rmSync } from "node:fs";
16
20
  import { spawnSync } from "node:child_process";
17
21
  import { dirname, join } from "node:path";
18
22
  import { fileURLToPath } from "node:url";
@@ -29,32 +33,53 @@ function run(scriptRel) {
29
33
  }
30
34
 
31
35
  /**
32
- * Copy each skill directory from pi-crew/skills/ to ~/.pi/agent/skills/.
33
- * Best-effort: must never fail the install.
36
+ * Remove stale skill copies from ~/.pi/agent/skills/ that are byte-identical
37
+ * to the bundled skills/ — left over from the v0.9.47 copySkills() postinstall
38
+ * (which redundantly copied all skills, causing "collision" warnings).
39
+ *
40
+ * Pi discovers skills natively from the npm package dir, so these copies only
41
+ * create noise AND can shadow newer package versions on upgrade.
42
+ *
43
+ * SAFE: only removes EXACT (byte-identical) copies. A skill the user has
44
+ * customized (differs from the package) is preserved. Best-effort, never
45
+ * fails the install.
34
46
  */
35
- function copySkills() {
47
+ function cleanupStaleSkillCopies() {
36
48
  const srcSkillsDir = join(root, "skills");
37
49
  if (!existsSync(srcSkillsDir)) return;
38
50
 
39
51
  const destSkillsDir = join(homedir(), ".pi", "agent", "skills");
40
- try {
41
- mkdirSync(destSkillsDir, { recursive: true });
42
- } catch {
43
- return; // can't create dest — skip silently
44
- }
52
+ if (!existsSync(destSkillsDir)) return;
45
53
 
54
+ let removed = 0;
55
+ let kept = 0;
46
56
  for (const entry of readdirSync(srcSkillsDir, { withFileTypes: true })) {
47
57
  if (!entry.isDirectory()) continue;
48
- const skillMd = join(srcSkillsDir, entry.name, "SKILL.md");
49
- if (!existsSync(skillMd)) continue;
58
+ const srcSkillMd = join(srcSkillsDir, entry.name, "SKILL.md");
59
+ if (!existsSync(srcSkillMd)) continue;
60
+ const destSkillDir = join(destSkillsDir, entry.name);
61
+ const destSkillMd = join(destSkillDir, "SKILL.md");
62
+ if (!existsSync(destSkillMd)) continue;
50
63
  try {
51
- cpSync(join(srcSkillsDir, entry.name), join(destSkillsDir, entry.name), {
52
- recursive: true,
53
- });
64
+ const srcContent = readFileSync(srcSkillMd, "utf8");
65
+ const destContent = readFileSync(destSkillMd, "utf8");
66
+ if (srcContent === destContent) {
67
+ rmSync(destSkillDir, { recursive: true, force: true });
68
+ removed++;
69
+ } else {
70
+ // User customized this skill — preserve it.
71
+ kept++;
72
+ }
54
73
  } catch {
55
74
  // best-effort: skip this skill on error
56
75
  }
57
76
  }
77
+ if (removed > 0) {
78
+ const note = kept > 0 ? ` (${kept} customized copy(ies) preserved)` : "";
79
+ console.warn(
80
+ `[pi-crew] postinstall: removed ${removed} stale skill cop${removed === 1 ? "y" : "ies"} from ~/.pi/agent/skills/${note}.`,
81
+ );
82
+ }
58
83
  }
59
84
 
60
85
  function main() {
@@ -74,8 +99,8 @@ function main() {
74
99
  }
75
100
  // Font install is best-effort and must never fail the install.
76
101
  run("scripts/install-crew-vibes-font.mjs");
77
- // Copy bundled skills to ~/.pi/agent/skills/ for global availability.
78
- copySkills();
102
+ // Migration cleanup: remove stale skill copies from v0.9.47's copySkills().
103
+ cleanupStaleSkillCopies();
79
104
  } catch (err) {
80
105
  // Postinstall must NEVER fail the install (SEC-M2).
81
106
  console.warn("[pi-crew] postinstall: best-effort step failed:", err instanceof Error ? err.message : err);