pi-crew 0.9.52 → 0.9.54
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 +39 -0
- package/index.ts +39 -10
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,45 @@
|
|
|
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.54] — HOTFIX (real root cause): esbuild runtime dep mis-declared as devDependency (2026-07-29)
|
|
7
|
+
|
|
8
|
+
**Fixes the TRUE root cause** of the extension-load regression that affected 0.9.52 AND 0.9.53. Both are deprecated; `latest` now points here.
|
|
9
|
+
|
|
10
|
+
### Root cause (the real one — 0.9.53 diagnosed the symptom, not the cause)
|
|
11
|
+
`esbuild` is imported at **runtime** by the shipped bundle `dist/index.mjs` — via `src/runtime/dynamic-workflow-runner.ts` (`import { transformSync } from "esbuild"`, used to compile `.dwf.ts` dynamic-workflow files). But it was declared as a **`devDependency`**, not a `dependency`. `devDependencies` are NOT installed by `npm install pi-crew` (production), so the bundle failed to load with `Cannot find package 'esbuild'`, and `index.ts` then fell back to the `src/` strip-types path — which also fails when `src/` isn't shipped (PKG-2) → `Cannot find module './src/extension/register.ts'`.
|
|
12
|
+
|
|
13
|
+
This was **latent** since esbuild was first used at runtime: pre-0.9.52 it was masked because `src/` WAS shipped, so the strip-types fallback loaded `register.ts` without eagerly pulling in the dynamic-workflow runner's esbuild import. PKG-2 (0.9.52) removed `src/`, surfacing the latent bundle-load failure.
|
|
14
|
+
|
|
15
|
+
0.9.53's dynamic-import change to `index.ts` was necessary (correct) but NOT sufficient — it only changed how `index.ts` *reaches* `src/`; it did not fix the bundle failing to load in the first place.
|
|
16
|
+
|
|
17
|
+
### Fix
|
|
18
|
+
- **Move `esbuild` from `devDependencies` to `dependencies`.** The bundle now loads in production. Verified via a faithful simulation of Pi's loader (jiti with Pi's peerDep alias map) on a production install (`npm install --omit=dev`, no `src/`).
|
|
19
|
+
|
|
20
|
+
### Regression guards (run in CI's Test step on all platforms)
|
|
21
|
+
- `test/unit/bundle-deps-consistency.test.ts` — **new**. Parses `dist/index.mjs`'s external imports and asserts each is declared in `dependencies` or `peerDependencies` (not `devDependencies`-only). Would have caught both 0.9.52 and 0.9.53. (Regex allows `{}` in named imports so it doesn't miss `import { transformSync } from "esbuild"`.)
|
|
22
|
+
- `test/unit/extension-entry-load.test.ts` (from 0.9.53) — asserts `index.ts` has no static top-level `./src/` imports.
|
|
23
|
+
|
|
24
|
+
### Note on 0.9.52 / 0.9.53
|
|
25
|
+
Both **deprecated** on npm. `latest` → 0.9.54. Upgrade: `npm install pi-crew@latest`.
|
|
26
|
+
|
|
27
|
+
## [0.9.53] — HOTFIX: extension-load regression in published npm installs (2026-07-29)
|
|
28
|
+
|
|
29
|
+
**Fixes the v0.9.52 regression** where every fresh `npm install pi-crew` failed at extension load with `Cannot find module './src/extension/register.ts'`. Affected all platforms.
|
|
30
|
+
|
|
31
|
+
### Root cause
|
|
32
|
+
v0.9.52's PKG-2 (Sprint 6) excluded `src/` from the npm tarball to slim it (16→4.8MB), but `index.ts` — the extension entry Pi loads via strip-types — still had **top-level static imports** from `./src/extension/register.ts` and `./src/runtime/run-tracker.ts`. The module loader resolves static imports BEFORE any code in the file runs, so the load failed before the shipped, self-contained `dist/index.mjs` bundle was ever tried. Pre-0.9.52 this was masked because `src/` was shipped alongside.
|
|
33
|
+
|
|
34
|
+
CI missed it because the `test:bundle` step loads `dist/index.mjs` directly (with repo peerDeps), and the CI-5 smoke test used `node --check` (syntax only — does not resolve imports).
|
|
35
|
+
|
|
36
|
+
### Fix (`index.ts`)
|
|
37
|
+
The src/ imports are now **dynamic `import()`** inside the fallback path only. The self-contained `dist/index.mjs` bundle (always shipped in the tarball) is the default and loads without `src/`. The src/ fallback is reached only when the bundle is absent — i.e. dev clones without a built `dist/`. Published installs never touch `src/`. No behavior change for bundle users; the fallback semantics (`PI_CREW_USE_BUNDLE=0` opt-out) are preserved.
|
|
38
|
+
|
|
39
|
+
### Regression guard
|
|
40
|
+
New `test/unit/extension-entry-load.test.ts` asserts `index.ts` has no static top-level `./src/` value imports (and that the dynamic src/ fallback imports still exist). Would have caught v0.9.52. Runs in CI's Test step on all platforms.
|
|
41
|
+
|
|
42
|
+
### Note on v0.9.52
|
|
43
|
+
v0.9.52 is **deprecated** on npm — upgrade to 0.9.53. If you installed 0.9.52, run `npm install pi-crew@latest` (or `npx pi install npm:pi-crew`).
|
|
44
|
+
|
|
6
45
|
## [0.9.52] — Sprint 1-6: security hardening, durability, god-module refactor, tarball slim (2026-07-28)
|
|
7
46
|
|
|
8
47
|
A full audit-driven upgrade pass — 6 sprints, ~60 findings from `REVIEW-UPGRADE-2026-07-27.md`, independently verified in `VERIFY-2026-07-27.md` (~22% of the original report's claims corrected: 4 false positives, count inflations, stale line refs). Test suite 6446 unit + 191 integration, 0 fail. CI green on ubuntu/macos/windows.
|
package/index.ts
CHANGED
|
@@ -47,18 +47,29 @@
|
|
|
47
47
|
* avoid recursion), the bundle flip risk is acceptable.
|
|
48
48
|
*/
|
|
49
49
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
50
|
-
import { registerPiTeams as registerPiTeamsFromSrc } from "./src/extension/register.ts";
|
|
51
|
-
import { waitForRun as waitForRunFromSrc } from "./src/runtime/run-tracker.ts";
|
|
52
50
|
import { accessSync } from "node:fs";
|
|
53
51
|
import { fileURLToPath } from "node:url";
|
|
54
52
|
import { dirname, resolve } from "node:path";
|
|
55
53
|
|
|
56
|
-
//
|
|
57
|
-
//
|
|
54
|
+
// IMPORTANT: src/ imports here MUST be dynamic (lazy `import()`), never
|
|
55
|
+
// top-level static imports. Published npm packages ship only dist/index.mjs
|
|
56
|
+
// in the tarball (src/ is excluded by the package.json "files" field — keeps
|
|
57
|
+
// the package ~5MB instead of ~16MB). A top-level static
|
|
58
|
+
// `import { x } from "./src/..."` is resolved by the module loader BEFORE
|
|
59
|
+
// this file's code runs, so it would break every fresh `npm install`
|
|
60
|
+
// (Cannot find module './src/...'). Dynamic import() defers src/ resolution
|
|
61
|
+
// to the fallback path below, which only executes when the bundle is
|
|
62
|
+
// unavailable — i.e. dev clones that still have src/. Published installs
|
|
63
|
+
// always ship + load the bundle, so src/ is never touched there.
|
|
64
|
+
|
|
65
|
+
// Minimal bundle shape — loose types because dist/index.mjs has no .d.ts
|
|
66
|
+
// (it's a build artifact, not source). The src fallback types use
|
|
67
|
+
// `typeof import(...)` type queries, which are type-only constructs erased
|
|
68
|
+
// at runtime (no module load) — they stay in sync with the real modules.
|
|
58
69
|
type BundleModule = {
|
|
59
70
|
default?: (pi: ExtensionAPI) => void;
|
|
60
|
-
waitForRun?: typeof
|
|
61
|
-
registerPiTeams?: (
|
|
71
|
+
waitForRun?: typeof import("./src/runtime/run-tracker.ts").waitForRun;
|
|
72
|
+
registerPiTeams?: typeof import("./src/extension/register.ts").registerPiTeams;
|
|
62
73
|
};
|
|
63
74
|
|
|
64
75
|
const OPT_OUT = new Set(["0", "false", "no", "off"]);
|
|
@@ -91,8 +102,26 @@ if (!envForceOff) {
|
|
|
91
102
|
}
|
|
92
103
|
}
|
|
93
104
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
105
|
+
// Lazy src/ fallback — only resolved when the bundle is unavailable
|
|
106
|
+
// (dev clones without a built dist/). NEVER imported in published
|
|
107
|
+
// installs, where the bundle always ships + loads above. This dynamic
|
|
108
|
+
// import() is what lets us exclude src/ from the npm tarball.
|
|
109
|
+
let srcRegister:
|
|
110
|
+
| typeof import("./src/extension/register.ts").registerPiTeams
|
|
111
|
+
| undefined;
|
|
112
|
+
let srcWaitForRun:
|
|
113
|
+
| typeof import("./src/runtime/run-tracker.ts").waitForRun
|
|
114
|
+
| undefined;
|
|
115
|
+
if (!bundleModule) {
|
|
116
|
+
({ registerPiTeams: srcRegister } = await import(
|
|
117
|
+
"./src/extension/register.ts",
|
|
118
|
+
));
|
|
119
|
+
({ waitForRun: srcWaitForRun } = await import(
|
|
120
|
+
"./src/runtime/run-tracker.ts",
|
|
121
|
+
));
|
|
122
|
+
}
|
|
97
123
|
|
|
98
|
-
export
|
|
124
|
+
export const waitForRun = bundleModule?.waitForRun ?? srcWaitForRun!;
|
|
125
|
+
export const registerPiTeams: (pi: ExtensionAPI) => void =
|
|
126
|
+
bundleModule?.registerPiTeams ?? srcRegister!;
|
|
127
|
+
export default bundleModule?.default ?? ((pi: ExtensionAPI) => srcRegister!(pi));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-crew",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.54",
|
|
4
4
|
"description": "Pi extension for coordinated AI teams, workflows, worktrees, and async task orchestration",
|
|
5
5
|
"author": "baphuongna",
|
|
6
6
|
"license": "MIT",
|
|
@@ -121,6 +121,7 @@
|
|
|
121
121
|
"ajv": "^8.20.0",
|
|
122
122
|
"cli-highlight": "^2.1.11",
|
|
123
123
|
"diff": "^5.2.0",
|
|
124
|
+
"esbuild": "^0.28.1",
|
|
124
125
|
"jiti": "^2.7.0",
|
|
125
126
|
"yaml": "^2.9.0"
|
|
126
127
|
},
|
|
@@ -131,7 +132,6 @@
|
|
|
131
132
|
"@earendil-works/pi-coding-agent": "^0.82.0",
|
|
132
133
|
"@earendil-works/pi-tui": "^0.82.0",
|
|
133
134
|
"@types/node": "^25.9.5",
|
|
134
|
-
"esbuild": "^0.28.1",
|
|
135
135
|
"tsx": "^4.23.0",
|
|
136
136
|
"typescript": "^7.0.2"
|
|
137
137
|
},
|