pi-crew 0.11.7 → 0.11.8
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/.githooks/pre-commit +22 -0
- package/.githooks/pre-push +56 -0
- package/CHANGELOG.md +121 -1
- package/dist/index.mjs +528 -510
- package/docs/publishing.md +29 -0
- package/index.ts +3 -3
- package/package.json +8 -5
- package/scripts/install-hooks.mjs +32 -0
- package/skills/real-test-pi-crew/SKILL.md +31 -18
- package/src/config/config-validation.ts +8 -1
- package/src/config/env-vars.ts +16 -1
- package/src/config/types.ts +28 -4
- package/src/extension/registration/foreground-run-controller.ts +19 -10
- package/src/extension/registration/lifecycle-handlers.ts +6 -491
- package/src/extension/registration/lifecycle.ts +7 -90
- package/src/extension/registration/render-loop.ts +502 -0
- package/src/extension/team-tool/doctor.ts +6 -0
- package/src/runtime/child-pi/child-pi-spawn.ts +7 -0
- package/src/runtime/child-pi/child-pi.ts +37 -2
- package/src/runtime/child-pi/pi-version.ts +187 -0
- package/src/runtime/classifier/classifier-service.ts +298 -0
- package/src/runtime/dispatch-batch.ts +4 -0
- package/src/runtime/live-session/live-session-runtime.ts +31 -0
- package/src/runtime/model/pi-args.ts +62 -3
- package/src/runtime/process/zombie-scanner.ts +168 -7
- package/src/runtime/rpc/README.md +64 -25
- package/src/runtime/rpc/rpc-worker.ts +146 -26
- package/src/runtime/run-worker.ts +89 -15
- package/src/runtime/scheduling/run-coalesced-task-group.ts +3 -0
- package/src/runtime/skill-instructions.ts +66 -1
- package/src/runtime/surface/resolve-surface.ts +34 -19
- package/src/runtime/task-runner/child-executor.ts +132 -0
- package/src/runtime/task-runner/pre-execution.ts +8 -0
- package/src/runtime/task-runner.ts +6 -0
- package/src/schema/config-schema.ts +20 -8
- package/src/schema/team-tool-schema.ts +4 -2
- package/src/state/contracts.ts +5 -0
- package/src/ui/format-helpers.ts +11 -0
- package/src/ui/overlays/mailbox-compose-overlay.ts +15 -1
- package/src/ui/rail.ts +14 -1
- package/src/ui/settings-overlay.ts +11 -2
- package/src/ui/widget/task-list.ts +10 -3
- package/src/ui/widget/widget-renderer.ts +53 -4
- package/src/utils/relative-time.ts +11 -3
- package/src/utils/visual.ts +32 -2
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# pi-crew pre-commit hook — block lockfile-drift commits locally.
|
|
3
|
+
#
|
|
4
|
+
# Catches the "bump a devDependency in package.json but forget `npm install`"
|
|
5
|
+
# class of CI failure BEFORE it is pushed. Runs the fast (<50ms, no install)
|
|
6
|
+
# check-lockfile-sync.mjs gate only when package.json or package-lock.json is
|
|
7
|
+
# staged, so it adds zero overhead to unrelated commits.
|
|
8
|
+
#
|
|
9
|
+
# Activate once per clone: git config core.hooksPath .githooks
|
|
10
|
+
# Bypass for a WIP commit: git commit --no-verify (CI will still catch it)
|
|
11
|
+
|
|
12
|
+
set -euo pipefail
|
|
13
|
+
|
|
14
|
+
# Only run when the manifests are staged (cheap path for unrelated commits).
|
|
15
|
+
if git diff --cached --name-only -- package.json package-lock.json | grep -q .; then
|
|
16
|
+
echo "[pre-commit] checking package.json ↔ package-lock.json sync…"
|
|
17
|
+
if ! node scripts/check-lockfile-sync.mjs; then
|
|
18
|
+
echo "[pre-commit] ✋ commit blocked: package-lock.json is out of sync."
|
|
19
|
+
echo "[pre-commit] Fix: run 'npm install' and 'git add package-lock.json', or use --no-verify to bypass (CI still gates)."
|
|
20
|
+
exit 1
|
|
21
|
+
fi
|
|
22
|
+
fi
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# pi-crew pre-push hook — broaden the local release gate (D3).
|
|
3
|
+
#
|
|
4
|
+
# The 2026-10 CI-red recurrence: pushes to origin/main ran only
|
|
5
|
+
# test:critical (~120 tests) locally, while CI runs the FULL unit suite —
|
|
6
|
+
# three waves in a row shipped red. This hook closes that gap BEFORE the
|
|
7
|
+
# push leaves the machine.
|
|
8
|
+
#
|
|
9
|
+
# Scope:
|
|
10
|
+
# push to refs/heads/main → check:conflict-markers + typecheck, then the
|
|
11
|
+
# FULL unit suite (npm run test:unit — the same
|
|
12
|
+
# gate CI runs); any failure blocks the push
|
|
13
|
+
# any other ref → fast gates only (check:conflict-markers +
|
|
14
|
+
# typecheck)
|
|
15
|
+
#
|
|
16
|
+
# Activated by `npm install` (prepare → scripts/install-hooks.mjs sets
|
|
17
|
+
# git config core.hooksPath .githooks) or manually:
|
|
18
|
+
# git config core.hooksPath .githooks
|
|
19
|
+
# Emergency bypass: git push --no-verify (CI still gates main).
|
|
20
|
+
|
|
21
|
+
set -euo pipefail
|
|
22
|
+
|
|
23
|
+
cd "$(git rev-parse --show-toplevel)"
|
|
24
|
+
|
|
25
|
+
pushes_main=0
|
|
26
|
+
while read -r local_ref local_sha remote_ref remote_sha; do
|
|
27
|
+
if [ "$remote_ref" = "refs/heads/main" ]; then
|
|
28
|
+
pushes_main=1
|
|
29
|
+
fi
|
|
30
|
+
done
|
|
31
|
+
|
|
32
|
+
if ! npm run check:conflict-markers; then
|
|
33
|
+
echo "[pre-push] ✋ push blocked: conflict markers present."
|
|
34
|
+
echo "[pre-push] Fix: resolve the markers, or bypass with 'git push --no-verify' (CI still gates)."
|
|
35
|
+
exit 1
|
|
36
|
+
fi
|
|
37
|
+
if ! npm run typecheck; then
|
|
38
|
+
echo "[pre-push] ✋ push blocked: typecheck failed."
|
|
39
|
+
echo "[pre-push] Fix the errors above, or bypass with 'git push --no-verify' (CI still gates)."
|
|
40
|
+
exit 1
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
if [ "$pushes_main" = "1" ]; then
|
|
44
|
+
echo "[pre-push] push to main: running the FULL unit suite (test:unit)…"
|
|
45
|
+
# Capture the full log so a flake's failing test is identifiable even when
|
|
46
|
+
# the push output is truncated by tooling (lesson 2026-10-07: three hook
|
|
47
|
+
# blocks lost their failure detail to a trailing `| tail`).
|
|
48
|
+
UNIT_LOG="${TMPDIR:-/tmp}/pi-crew-prepush-unit.log"
|
|
49
|
+
if ! npm run test:unit 2>&1 | tee "$UNIT_LOG"; then
|
|
50
|
+
echo "[pre-push] ✋ push blocked: test:unit failed (full log: $UNIT_LOG)."
|
|
51
|
+
echo "[pre-push] Fix the failures above, or bypass with 'git push --no-verify' (CI still gates)."
|
|
52
|
+
exit 1
|
|
53
|
+
fi
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
echo "[pre-push] gates green."
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,126 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.11.8] — Pi 1.0.4 adoption + RPC/surface hardening + battery-proven stability (2026-10-07)
|
|
4
|
+
|
|
5
|
+
### Added — deep-learn polish batch (docs/reviews/pi-1.0.0-deep-learn-r3-2026-10-03.md R3 matrix)
|
|
6
|
+
|
|
7
|
+
- **RPC worker transport wired (P2-3 integration)** — after a live-fire probe against a real
|
|
8
|
+
`pi --mode rpc` (24 ui-requests drained by the drain policy; dialog auto-answered `cancel`
|
|
9
|
+
with no deadlock; steer honored at 53 ms RTT), the `runtime.workerTransport: "rpc"` path now
|
|
10
|
+
dispatches real RPC workers with worker-cap parity, a pre-abort short-circuit, and a guarded
|
|
11
|
+
stdio fallback. Still experimental: minimal input mapping, raw model passthrough, ephemeral
|
|
12
|
+
sessions (see src/runtime/rpc/README.md).
|
|
13
|
+
- **Skill advertisement dedup (R3-23)** — the worker spawn path no longer duplicates the host's
|
|
14
|
+
`<available_skills>` block with pi-crew's own per-skill index; measured ~232–284 tokens/worker
|
|
15
|
+
(~65% of the block) saved, ~1.9k tokens per 8-role wave. Live-session/scaffold keep the full
|
|
16
|
+
block.
|
|
17
|
+
- **Foreign-pi orphan scan (R3-16)** — `doctor --zombies` now WARN-lists orphaned pi processes
|
|
18
|
+
via `AI_AGENT`/`PI_CODING_AGENT` markers (exact-value match, argv pi-binary gate, self/ancestor
|
|
19
|
+
exclusion). Report-only by design — never a kill candidate.
|
|
20
|
+
- **Worker session labels (R3-15)** — headless workers spawn with `--name crew-<taskId>` for
|
|
21
|
+
human-friendly session pickers.
|
|
22
|
+
- **Live-session scoped models (R3-12)** — live sessions bind `scopedModels` to the configured
|
|
23
|
+
fallback chain (explicit-chain-only; user overrides preserved — scope is visibility, not gate).
|
|
24
|
+
- **OSC-8 dock link (R3-9)** — the crew dock subject is a `file://` hyperlink to the latest run's
|
|
25
|
+
artifacts dir; degrades to plain text on old hosts, escape-safe under truncation.
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
|
|
29
|
+
- **Local pre-push release gate broadened via committed `.githooks/` (D3)** — a new
|
|
30
|
+
`pre-push` hook (activated by the `prepare` script on `npm install`, or manually via
|
|
31
|
+
`git config core.hooksPath .githooks`) runs `check:conflict-markers` + `typecheck` on every
|
|
32
|
+
push, and additionally the FULL `test:unit` suite when pushing to `refs/heads/main` — the
|
|
33
|
+
same gate CI runs — so a leader's local fast-gate-only push can no longer ship red.
|
|
34
|
+
Emergency bypass: `git push --no-verify` (CI still gates). Documented in docs/publishing.md.
|
|
35
|
+
- **`runtime.workerTransport` config plumbed to the run-worker seam (D1/DR2)** — the config key
|
|
36
|
+
is no longer parse+emit-only dead: callers carrying runtimeConfig (child-executor,
|
|
37
|
+
run-coalesced-task-group) thread it to `runWorker`, with the established precedence
|
|
38
|
+
env > config > default stdio (`PI_CREW_WORKER_TRANSPORT` still wins when set; invalid values
|
|
39
|
+
fail safe to stdio). The three stale "not-implemented" doc blocks (config-schema.ts,
|
|
40
|
+
config/types.ts, env-vars.ts) now describe the wired state; the F19-1 comment records that
|
|
41
|
+
emission without a consumer is still dead. dynamic-workflow-context and goal-evaluator have
|
|
42
|
+
no runtimeConfig and deliberately keep default stdio.
|
|
43
|
+
- `setupRenderLoop` extracted byte-identically into `src/extension/registration/render-loop.ts`
|
|
44
|
+
(lifecycle-handlers.ts 1347→897 lines) (QW#2).
|
|
45
|
+
- `formatDuration` name collision resolved with domain names (`formatTaskElapsed`,
|
|
46
|
+
`formatRelativeCompact`) — zero output-format changes (QW#5).
|
|
47
|
+
- wc-gate now scans **all of `src/`** (527 files; 0 violations, max 1908) (QW#3).
|
|
48
|
+
- f19-config-parity test now auto-derives runtime keys 3-way (types ↔ schema ↔ parser) — no hand
|
|
49
|
+
lists; mutation-verified (parse-dead and phantom keys both fail loudly).
|
|
50
|
+
- IME-safe cursors: hand-written text inputs emit pi-tui `CURSOR_MARKER` (R3-6).
|
|
51
|
+
- Bundle benchmark comment refreshed to the re-measured ~36% cold-start gap (QW#6).
|
|
52
|
+
- R3-10 (withFileMutationQueue) skipped with evidence: pi-crew's flock-based mutation locks
|
|
53
|
+
already cover the named paths; the SDK helper is in-process-only — double-lock for no gain.
|
|
54
|
+
|
|
55
|
+
### Added — Pi 1.0.4 adoption wave (see docs/reviews/pi-1.0.4-upgrade-notes-2026-10-06.md)
|
|
56
|
+
|
|
57
|
+
- **devDeps on the pi SDK 1.0.4 (U1, P0)** — all four `@earendil-works` devDeps bumped
|
|
58
|
+
`^1.0.0`→`^1.0.4` with a lockfile refresh. pi-coding-agent@1.0.4 direct-pins
|
|
59
|
+
`brace-expansion 5.0.12`, closing the accepted dev-scope 5.0.9 finding: the top level now
|
|
60
|
+
hoists 5.0.12 and the pi subtree no longer nests a copy.
|
|
61
|
+
- **Thinking level `max` (U4)** — `THINKING_LEVELS` carries all 7 pi levels (was 6);
|
|
62
|
+
frontmatter `thinking: max` was previously rejected by `isValidThinkingLevel` even though
|
|
63
|
+
pi's CLI documents it.
|
|
64
|
+
- **MCP cut for parity spawns (U2-lite)** — pi 1.0.4 no longer cuts MCP under `--tools`, so
|
|
65
|
+
parity (NON-hermetic) spawns fold `mcp__*` into their single `--exclude-tools` value
|
|
66
|
+
(merged comma-sep with frontmatter `disallowedTools`; pi's strict parser rejects duplicate
|
|
67
|
+
flags). Hermetic defaults gain no new flag — `--no-extensions` already kills built-in MCP
|
|
68
|
+
on 1.0.4. Cross-version-safe: on pre-1.0.4 hosts the pattern matches no literal tool name.
|
|
69
|
+
- **Classifier seam, dormant (P2-1)** — `runtime.classifierEnabled` (default **false**) +
|
|
70
|
+
`runtime.classifierModel` (default `opencode/jev-1.13-free`; env `PI_CREW_CLASSIFIER_ENABLED`
|
|
71
|
+
/ `PI_CREW_CLASSIFIER_MODEL` beats config) land with full config ceremony (schema → types →
|
|
72
|
+
validation → env registry → snapshot test). Host-process `classifyBool()` is never-rejects:
|
|
73
|
+
missing registry / no classifier available / classify throw / `stopReason:"error"` all return
|
|
74
|
+
the caller-supplied fallback decision with log-once + `crew.classifier.calls_total` counters —
|
|
75
|
+
never an exception up to the orchestrator. Spike consumer: child-executor retry-triage
|
|
76
|
+
classifies transient-vs-permanent before burning a re-attempt (event `task.retry_triage`,
|
|
77
|
+
metric `crew.classifier.decisions_total`); default-off never touches the registry (zero
|
|
78
|
+
behavior change, test-pinned). Live-fire probe for post-credential runs:
|
|
79
|
+
`scripts/probe-classifier.mjs`.
|
|
80
|
+
- **Pi version floor + `--no-mcp` on parity spawns (U9)** — new `probePiVersion()` (single-flight
|
|
81
|
+
per process, ~5 s timeout, failure → null = unknown) probes the same binary worker spawns
|
|
82
|
+
use, plus hand-rolled `comparePiVersion` (no semver dependency — deliberate, see the module;
|
|
83
|
+
malformed → null, conservative). Non-hermetic parity spawns now append `--no-mcp` when the
|
|
84
|
+
host pi is ≥ 1.0.4 — disconnecting ambient MCP servers, strictly stronger than the U2-lite
|
|
85
|
+
`mcp__*` tool-cut (kept as the cross-version-safe baseline). Below the floor or unknown →
|
|
86
|
+
no flag; hermetic path unchanged.
|
|
87
|
+
|
|
88
|
+
### Fixed
|
|
89
|
+
|
|
90
|
+
- **RPC transport lifecycle hardening (DR1/DR5)** — the experimental RPC worker transport can
|
|
91
|
+
no longer hang a worker-cap slot forever: the settle wait races `client.exited()` + a
|
|
92
|
+
belt-and-suspenders turn timeout (env `PI_CREW_RPC_TURN_TIMEOUT_MS`, default 600 000 ms,
|
|
93
|
+
env-only while RPC stays experimental; invalid/≤0 → default). Exit-before-`agent_settled`
|
|
94
|
+
and turn-timeout map to the early-failure shape so the stdio fallback engages and the slot
|
|
95
|
+
is released. DR5 closes the double-execution window: a session event after the prompt marks
|
|
96
|
+
the turn as started (`result.rpcAgentStarted`), and started-but-unsettled failures are
|
|
97
|
+
surfaced, never retried. New seam tests: crash-before-settle (fallback + slot released),
|
|
98
|
+
started-then-fail (no fallback), turn timeout (early-failure shape).
|
|
99
|
+
- **`consumeAnsi` handles APC sequences (U6/DR4)** — an APC branch (ESC `_` … terminated by
|
|
100
|
+
BEL 0x07 or ST ESC `\`) sits beside the OSC branch with mirrored terminators and
|
|
101
|
+
control-char fallback, so pi-tui's `CURSOR_MARKER` (an APC string) measures zero-width;
|
|
102
|
+
`truncateToWidth`/`wrapHard` no longer count it as ~6 visible columns.
|
|
103
|
+
|
|
104
|
+
- **herdr liveness ping survives ESM hosts** (battery 2026-10-07, T10c) — `pingSocketSync`'s eval'd
|
|
105
|
+
Worker used bare `require(...)`; under a `--input-type=module` host the eval source parses as ESM,
|
|
106
|
+
`require` throws, and the ping fail-closed to false → herdr degraded "socket not live" against a
|
|
107
|
+
LIVE socket (CJS hosts like the pi CLI were unaffected). The worker source is now dual-mode
|
|
108
|
+
(`require` try → dynamic `import()` fallback) and exported for tests;
|
|
109
|
+
`test/unit/runtime/surface/resolve-surface-ping.test.ts` pins both module contexts + fail-closed.
|
|
110
|
+
- **resume-liveness F1 test stabilized** (battery 2026-10-07) — the "re-checks liveness INSIDE the run lock"
|
|
111
|
+
test raced the lock ACQUISITION itself (test vs resume; ~1/3 red even isolated — it blocked the new
|
|
112
|
+
pre-push hook twice). Entered-signal now guarantees the lock is held before the resume starts, making
|
|
113
|
+
both orderings of the pre-lock check deterministic refusals. 8/8 green isolated (was ~2/3).
|
|
114
|
+
|
|
115
|
+
### Ops notes
|
|
116
|
+
|
|
117
|
+
- **Azure provider rename in pi 1.0.3 (U3)** — pi renamed provider id
|
|
118
|
+
`azure-openai-responses`→`azure`; `AZURE_OPENAI_*` env vars are unchanged. User config
|
|
119
|
+
(`auth.json`/`models.json`/`settings.json`) entries under the old id need renaming.
|
|
120
|
+
pi-crew code is unaffected — `env-filter.ts` PROVIDER_ENV_KEY_MAP already keys `azure`
|
|
121
|
+
and `azure-openai` (both → `AZURE_OPENAI_*`).
|
|
122
|
+
|
|
123
|
+
|
|
3
124
|
## [0.11.7] — Pi 1.0.0 adoption waves + deep-learn execution (2026-10-04)
|
|
4
125
|
### Added — Pi 1.0.0 adoption wave (see docs/reviews/pi-1.0.0-adoption-review-2026-10-03.md)
|
|
5
126
|
|
|
@@ -5118,7 +5239,6 @@ the user sees "Goal failed: Background runner died unexpectedly" instead of
|
|
|
5118
5239
|
an infinite "running" state.
|
|
5119
5240
|
|
|
5120
5241
|
|
|
5121
|
-
|
|
5122
5242
|
### `goal` — autonomous goal loop (P0a + P0 + P1)
|
|
5123
5243
|
|
|
5124
5244
|
- `team action='goal' config.subAction='start|status|pause|resume|stop|step|clear'`.
|