@jwilger/pi-development-system 0.82.0 → 0.83.0

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jwilger/pi-development-system",
3
- "version": "0.82.0",
3
+ "version": "0.83.0",
4
4
  "description": "A pi extension package representing a seasoned approach to software development using a full AI SDLC.",
5
5
  "keywords": [
6
6
  "pi-package"
@@ -41,3 +41,4 @@ SOFTWARE.
41
41
  6. Empty scope (I5 review): `orch/runtime.ts` `availableScopedModels` treats an empty `/scoped-models` as no restriction (pi's meaning) instead of "matches nothing", because every devsys agent declares `models:` and would otherwise be unspawnable by default. Pinned models are also re-applied on resume (`resolveInitialSettings`), since a restored session may hold only inherited history.
42
42
  7. Bundled agents outside `src/subagents`: `agents/researcher.md` (devsys `models:` family list) and `agents/reviewer.md` (devsys `models:` list and packet format; description rewritten; upstream `icon` and `modelSuggestions` removed) differ from upstream; `agents/{advisor,implementer,lens-*}.md` are new. The agent file format itself is unchanged.
43
43
  8. Thread cap (I7b.1): `orch/manager.ts` `archiveFinished` replaces the hard "Total thread limit reached" check. At `maxThreads` the oldest finished (completed/failed/stopped) thread without a retained descendant is dropped from the registry to make room; the limit is refused only when every kept thread is live, paused or a parent of one. Upstream kept finished threads forever, so long autonomous runs stalled on their own history. A dropped thread cannot be resumed with `agent_steer` (its session file stays on disk).
44
+ 9. Registry writes (OOM fix): `index.ts` `persist` signs the registry with `orch/persist-signature.ts` `registrySignature`, which leaves a starting or running thread's status line and partial output out of the change signature. Upstream wrote the whole registry (every thread, about 12 KB each) on every status change; pi never rewrites session entries, so one session grew to 2.3 GB (5,909 snapshots) and pi died loading it. Writes now happen when a thread is added or removed, starts, settles, pauses or is stopped.
@@ -10,6 +10,7 @@ import { buildSessionContext, getAgentDir } from "@earendil-works/pi-coding-agen
10
10
  import { fuzzyFilter } from "@earendil-works/pi-tui";
11
11
  import { createInheritedToolSource } from "./orch/inherited-tools.ts";
12
12
  import { ThreadManager } from "./orch/manager.ts";
13
+ import { registrySignature } from "./orch/persist-signature.ts";
13
14
  import { subagentPrompt } from "./orch/prompt.ts";
14
15
  import { createDriverFactory } from "./orch/runtime.ts";
15
16
  import { agentTools } from "./orch/tools.ts";
@@ -191,7 +192,7 @@ export default function piSubagent(pi: ExtensionAPI): void {
191
192
  const persist = () => {
192
193
  if (!manager) return;
193
194
  const threads = manager.saved();
194
- const signature = JSON.stringify(threads);
195
+ const signature = registrySignature(threads);
195
196
  if (signature !== persistenceSignature) {
196
197
  pi.appendEntry(REGISTRY_ENTRY, {
197
198
  version: 1,
@@ -0,0 +1,24 @@
1
+ import type { SavedThread } from "../types.ts";
2
+
3
+ const LIVE = new Set(["starting", "running"]);
4
+
5
+ /**
6
+ * What decides whether the registry needs writing again.
7
+ *
8
+ * pi appends every `appendEntry` to the session file and never rewrites it, and each
9
+ * registry entry holds every thread (about 12 KB each). A running thread changes its
10
+ * status line on every tool call, so signing the full snapshot wrote hundreds of
11
+ * kilobytes per tool call: one session reached 2.3 GB and pi ran out of memory loading
12
+ * it. A live thread's status and output are not needed to restore it (a reload marks it
13
+ * interrupted), so they stay out of the signature. Starting, settling, pausing and
14
+ * adding or removing a thread still write.
15
+ */
16
+ export function registrySignature(threads: readonly SavedThread[]): string {
17
+ return JSON.stringify(
18
+ threads.map((thread) =>
19
+ LIVE.has(thread.view.state)
20
+ ? { ...thread, view: { ...thread.view, status: "", output: undefined } }
21
+ : thread,
22
+ ),
23
+ );
24
+ }