@pi-unipi/unipi 3.0.0-alpha.40 → 3.0.0-alpha.41

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.
Files changed (51) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/package.json +23 -23
  3. package/packages/app-bridge/package.json +2 -2
  4. package/packages/app-bridge/src/bridge.ts +31 -5
  5. package/packages/app-bridge/src/wire.ts +19 -0
  6. package/packages/app-bridge/src/work.ts +1 -0
  7. package/packages/ask-user/package.json +2 -2
  8. package/packages/autocomplete/package.json +1 -1
  9. package/packages/background-tasks/package.json +2 -2
  10. package/packages/btw/package.json +2 -2
  11. package/packages/compactor/package.json +3 -3
  12. package/packages/core/bus.ts +15 -0
  13. package/packages/core/package.json +1 -1
  14. package/packages/core/src/work/index.ts +21 -0
  15. package/packages/dream/package.json +2 -2
  16. package/packages/footer/package.json +3 -3
  17. package/packages/fusion/package.json +4 -4
  18. package/packages/info-screen/package.json +2 -2
  19. package/packages/input-shortcuts/package.json +2 -2
  20. package/packages/kanboard/package.json +7 -7
  21. package/packages/long-horizon/README.md +11 -3
  22. package/packages/long-horizon/index.ts +198 -18
  23. package/packages/long-horizon/package.json +2 -2
  24. package/packages/long-horizon/src/commands.ts +25 -7
  25. package/packages/long-horizon/src/engine/continuation.ts +166 -4
  26. package/packages/long-horizon/src/engine/goal-state.ts +69 -3
  27. package/packages/long-horizon/src/engine/ralph.ts +74 -4
  28. package/packages/long-horizon/src/engine/task-gate.ts +109 -0
  29. package/packages/long-horizon/src/gate.ts +1 -2
  30. package/packages/long-horizon/src/graph/engine.ts +929 -0
  31. package/packages/long-horizon/src/graph/runner.ts +49 -0
  32. package/packages/long-horizon/src/modes.ts +2 -2
  33. package/packages/long-horizon/src/progress-snapshot.ts +40 -64
  34. package/packages/long-horizon/src/runtime.ts +13 -0
  35. package/packages/long-horizon/src/tools/graph.ts +285 -332
  36. package/packages/long-horizon/src/tools/ralph.ts +1 -1
  37. package/packages/mcp/package.json +2 -2
  38. package/packages/memory/package.json +3 -3
  39. package/packages/notify/package.json +2 -2
  40. package/packages/skill-registry/package.json +2 -2
  41. package/packages/subagents/package.json +3 -3
  42. package/packages/subagents/src/index.ts +53 -1
  43. package/packages/subagents/src/manager-shared.ts +31 -0
  44. package/packages/unipi/bundled.js +2031 -973
  45. package/packages/updater/package.json +2 -2
  46. package/packages/utility/package.json +2 -2
  47. package/packages/watchdog/package.json +3 -3
  48. package/packages/web-api/package.json +2 -2
  49. package/packages/workflow/package.json +2 -2
  50. package/packages/workflow/src/permission/decide.ts +1 -1
  51. package/packages/long-horizon/src/tools/swarm.ts +0 -238
package/CHANGELOG.md CHANGED
@@ -6,6 +6,21 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [3.0.0-alpha.41] — 2026-10-13
10
+
11
+ ### Changed
12
+ - Graph and swarm now follow Maka's agent graph. The model adds work with dependencies, and pi runs each step as a background subagent. Before, the model had to start every subagent and report back by hand, and weaker models skipped it. The model yields while steps run, and pi wakes it once at each checkpoint (a failure, nothing left to run, or everything settled). A graph closes only when the model finishes it with the results it chose. Swarm is the same graph with Maka's swarm instructions. New tools: `update_agent_graph` (`add_work` / `stop` / `finish`), `view_agent_graph`, `yield_agent_graph`, `agent_output`, `agent_swarm_status`. Removed: `swarm_report`, `swarm_status`, `swarm_yield`, `graph_output`, and the declare-once `update_agent_graph`. (UNI-279, UNI-280, UNI-281)
13
+
14
+ ### Added
15
+ - The agent graph is saved in the project's state folder. It survives restarts: steps that were running when pi closed resume once in their own subagent session. `/unipi:graph history` and `/unipi:swarm history` list past graphs, and a new graph can reuse results a finished one selected. (UNI-279, UNI-280)
16
+ - The UniPi app's Progress sheet shows finished and past graphs with their chart. It adds each step's details, its full result and its subagent session, plus Stop graph and a picker for earlier runs. The app can also open any subagent's transcript. (UNI-282)
17
+ - Goal: the next continuation is saved before it is sent. If pi crashes, the next start sends it again, up to 2 times, then pauses the goal. A completion claim while the todo list still has open items gets a task reminder first, up to 2 times. (UNI-283)
18
+
19
+ ### Fixed
20
+ - `/unipi:ralph start` from an empty prompt started the loop but never ran the first iteration. (UNI-283)
21
+ - After a restart, `ralph_done` failed with "no active loop". Prompts and tools also pointed the model at the wrong task-file path. (UNI-283)
22
+ - Stopping a ralph loop with `/unipi:regular` left its goal active, so the next `/unipi:goal` resumed the old checklist. (UNI-283)
23
+
9
24
  ## [3.0.0-alpha.40] — 2026-10-12
10
25
 
11
26
  ### Added
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/unipi",
3
- "version": "3.0.0-alpha.40",
3
+ "version": "3.0.0-alpha.41",
4
4
  "description": "All-in-one extension suite for Pi coding agent",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -80,28 +80,28 @@
80
80
  "typebox": "^1.1.38"
81
81
  },
82
82
  "dependencies": {
83
- "@pi-unipi/app-bridge": "3.0.0-alpha.40",
84
- "@pi-unipi/ask-user": "3.0.0-alpha.40",
85
- "@pi-unipi/background-tasks": "3.0.0-alpha.40",
86
- "@pi-unipi/btw": "3.0.0-alpha.40",
87
- "@pi-unipi/command-enchantment": "3.0.0-alpha.40",
88
- "@pi-unipi/compactor": "3.0.0-alpha.40",
89
- "@pi-unipi/core": "3.0.0-alpha.40",
90
- "@pi-unipi/dream": "3.0.0-alpha.40",
91
- "@pi-unipi/footer": "3.0.0-alpha.40",
92
- "@pi-unipi/fusion": "3.0.0-alpha.40",
93
- "@pi-unipi/info-screen": "3.0.0-alpha.40",
94
- "@pi-unipi/input-shortcuts": "3.0.0-alpha.40",
95
- "@pi-unipi/kanboard": "3.0.0-alpha.40",
96
- "@pi-unipi/mcp": "3.0.0-alpha.40",
97
- "@pi-unipi/memory": "3.0.0-alpha.40",
98
- "@pi-unipi/notify": "3.0.0-alpha.40",
99
- "@pi-unipi/skill-registry": "3.0.0-alpha.40",
100
- "@pi-unipi/subagents": "3.0.0-alpha.40",
101
- "@pi-unipi/updater": "3.0.0-alpha.40",
102
- "@pi-unipi/utility": "3.0.0-alpha.40",
103
- "@pi-unipi/web-api": "3.0.0-alpha.40",
104
- "@pi-unipi/workflow": "3.0.0-alpha.40",
83
+ "@pi-unipi/app-bridge": "3.0.0-alpha.41",
84
+ "@pi-unipi/ask-user": "3.0.0-alpha.41",
85
+ "@pi-unipi/background-tasks": "3.0.0-alpha.41",
86
+ "@pi-unipi/btw": "3.0.0-alpha.41",
87
+ "@pi-unipi/command-enchantment": "3.0.0-alpha.41",
88
+ "@pi-unipi/compactor": "3.0.0-alpha.41",
89
+ "@pi-unipi/core": "3.0.0-alpha.41",
90
+ "@pi-unipi/dream": "3.0.0-alpha.41",
91
+ "@pi-unipi/footer": "3.0.0-alpha.41",
92
+ "@pi-unipi/fusion": "3.0.0-alpha.41",
93
+ "@pi-unipi/info-screen": "3.0.0-alpha.41",
94
+ "@pi-unipi/input-shortcuts": "3.0.0-alpha.41",
95
+ "@pi-unipi/kanboard": "3.0.0-alpha.41",
96
+ "@pi-unipi/mcp": "3.0.0-alpha.41",
97
+ "@pi-unipi/memory": "3.0.0-alpha.41",
98
+ "@pi-unipi/notify": "3.0.0-alpha.41",
99
+ "@pi-unipi/skill-registry": "3.0.0-alpha.41",
100
+ "@pi-unipi/subagents": "3.0.0-alpha.41",
101
+ "@pi-unipi/updater": "3.0.0-alpha.41",
102
+ "@pi-unipi/utility": "3.0.0-alpha.41",
103
+ "@pi-unipi/web-api": "3.0.0-alpha.41",
104
+ "@pi-unipi/workflow": "3.0.0-alpha.41",
105
105
  "@resvg/resvg-wasm": "^2.6.2",
106
106
  "beautiful-mermaid": "^1.1.3"
107
107
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/app-bridge",
3
- "version": "3.0.0-alpha.40",
3
+ "version": "3.0.0-alpha.41",
4
4
  "description": "Live bridge between a pi TUI session and the UniPi phone app — streaming chat, prompts, steering and dialogs from the phone",
5
5
  "type": "module",
6
6
  "main": "index.ts",
@@ -31,7 +31,7 @@
31
31
  "access": "public"
32
32
  },
33
33
  "dependencies": {
34
- "@pi-unipi/core": "3.0.0-alpha.40"
34
+ "@pi-unipi/core": "3.0.0-alpha.41"
35
35
  },
36
36
  "peerDependencies": {
37
37
  "@earendil-works/pi-coding-agent": "^0.87.1",
@@ -44,7 +44,7 @@ import { setRemoteDialogs } from "./remote.js";
44
44
  import { fileSuggestions } from "./files.js";
45
45
  import { statPaths } from "./paths.js";
46
46
  import { registerPath, resolveMedia } from "./media.js";
47
- import { listWorkItems, stopWorkItem, backgroundWorkItem, workLogPage } from "./work.js";
47
+ import { listWorkItems, stopWorkItem, backgroundWorkItem, workLogPage, workTranscript } from "./work.js";
48
48
  import { bus, callCommandRunner, commandArgCompleters, pendingWorkLabel, silenceCommandEcho, subscribePendingWork, UNIPI_EVENTS } from "@pi-unipi/core";
49
49
  import type { BtwListPage } from "./wire.js";
50
50
 
@@ -62,6 +62,8 @@ export function recordLhMode(state: LhModeInfo | undefined): { lhMode: string |
62
62
 
63
63
  /** UNI-269: long-horizon's command runner behind `set_lh_mode` (packages/long-horizon/src/commands.ts). */
64
64
  export const LH_MODE_RUNNER = "unipi:lh-mode";
65
+ /** UNI-282: long-horizon's agent graph ops runner (packages/long-horizon/index.ts). */
66
+ export const LH_GRAPH_RUNNER = "unipi:lh-graph";
65
67
  /** UNI-118: dream_status pushes coalesce within this window. */
66
68
  export const DREAM_COALESCE_MS = 250;
67
69
 
@@ -1581,6 +1583,26 @@ export function createBridge(pi: ExtensionAPI, deps: BridgeDeps = defaultDeps) {
1581
1583
  }
1582
1584
  return;
1583
1585
  }
1586
+ case "lh_graph": {
1587
+ try {
1588
+ const out = await callCommandRunner<{ ok: boolean; reason?: string; output?: { text?: string }; runs?: unknown[] }>(LH_GRAPH_RUNNER, ctx, { op: msg.op, id: msg.id, graphId: msg.graphId });
1589
+ if (!out.found) return fail("The agent graph needs a newer unipi on this PC.");
1590
+ if (!out.result?.ok) return fail(out.result?.reason ?? "The graph op failed.");
1591
+ if (msg.op === "stop") {
1592
+ ack();
1593
+ return;
1594
+ }
1595
+ if (msg.op === "output") {
1596
+ const o = out.result.output ?? {};
1597
+ write(sock, { t: "lh_graph", op: "output", output: { ...o, ...(typeof o.text === "string" ? { text: clipText(o.text, 256 * 1024) } : {}) }, ref: msg.ref });
1598
+ return;
1599
+ }
1600
+ write(sock, { t: "lh_graph", op: "history", runs: out.result.runs ?? [], ref: msg.ref });
1601
+ } catch (error) {
1602
+ fail(error instanceof Error ? error.message : String(error));
1603
+ }
1604
+ return;
1605
+ }
1584
1606
  case "dream_get":
1585
1607
  write(sock, { t: "dream_status", status: dreamStatus(), ref: msg.ref });
1586
1608
  return;
@@ -1640,10 +1662,14 @@ export function createBridge(pi: ExtensionAPI, deps: BridgeDeps = defaultDeps) {
1640
1662
  return;
1641
1663
  }
1642
1664
  case "work_transcript": {
1643
- // Subagent mini-transcripts need @pi-unipi/subagents' transcript
1644
- // builder (TUI-flavoured); UNI-160 ships the live-log half (bg tasks)
1645
- // first and reports this a known gap (see the task report).
1646
- fail("Subagent transcripts aren't available yet.");
1665
+ // UNI-282: a subagent's mini-transcript (work id `agent-<id>` or a
1666
+ // graph step's operator id) from @pi-unipi/subagents' builder.
1667
+ const out = workTranscript(msg.id);
1668
+ if ("error" in out) return fail(out.error);
1669
+ const items = out.items.slice(-400).map((item) =>
1670
+ item.kind === "tool" ? { ...item, output: clipText(item.output, 8 * 1024) } : { ...item, text: clipText(item.text, 32 * 1024) },
1671
+ );
1672
+ write(sock, { t: "work_transcript", id: msg.id, items, ...(out.report !== undefined ? { report: clipText(out.report, 256 * 1024) } : {}), ref: msg.ref });
1647
1673
  return;
1648
1674
  }
1649
1675
  case "work_stop": {
@@ -325,6 +325,8 @@ export type OutMsg =
325
325
  | { t: "lh_progress"; progress: LhProgressInfo | undefined; ref?: string }
326
326
  /** UNI-269: the working mode changed (pushed to every client, coalesced). */
327
327
  | { t: "lh_mode"; mode: LhModeInfo | undefined }
328
+ /** UNI-282: reply to `lh_graph` (stop replies `ack` instead). */
329
+ | { t: "lh_graph"; op: "output" | "history"; output?: unknown; runs?: unknown[]; ref?: string }
328
330
  /** UNI-118: Dream status changed (pushed to every client, coalesced), or the
329
331
  * reply to `dream_get` (`ref`). `status` undefined = the dream module isn't loaded. */
330
332
  | { t: "dream_status"; status: DreamStatusInfo | undefined; ref?: string }
@@ -464,6 +466,11 @@ export type InMsg =
464
466
  /** UNI-269: switch the working mode (no prompt); `none` = /unipi:regular.
465
467
  * Replies `ack` (then an `lh_mode` push) or `error{message}`. */
466
468
  | { t: "set_lh_mode"; mode: LhModeId; ref?: string }
469
+ /** UNI-282: agent graph ops for the Progress sheet. `output` = one step's
470
+ * full committed result (`id` = work id or result id, `graphId?` for a past
471
+ * graph); `stop` = stop the running graph; `history` = past graphs as runs.
472
+ * Replies `lh_graph{op, output? | runs?, ref}` or `error`. */
473
+ | { t: "lh_graph"; op: "output" | "stop" | "history"; id?: string; graphId?: string; ref?: string }
467
474
  /** UNI-118: the current Dream status; replies `dream_status{status, ref}`. */
468
475
  | { t: "dream_get"; ref?: string }
469
476
  /** UNI-118: one run's report + trajectory; replies `dream_detail` (or `error`). */
@@ -510,6 +517,7 @@ const IN_TYPES = new Set([
510
517
  "work_background",
511
518
  "lh_progress_get",
512
519
  "set_lh_mode",
520
+ "lh_graph",
513
521
  "dream_get",
514
522
  "dream_detail",
515
523
  "dream_action",
@@ -654,6 +662,17 @@ export function parseIn(line: string): InMsg | { bad: string; ref?: string } | u
654
662
  return { bad: "set_lh_mode.mode must be goal|ralph|swarm|graph|none", ref };
655
663
  }
656
664
  return { t: "set_lh_mode", mode: m.mode as LhModeId, ref };
665
+ case "lh_graph": {
666
+ if (m.op !== "output" && m.op !== "stop" && m.op !== "history") return { bad: "lh_graph.op must be output|stop|history", ref };
667
+ if (m.op === "output" && (typeof m.id !== "string" || !m.id)) return { bad: "lh_graph output needs id", ref };
668
+ return {
669
+ t: "lh_graph",
670
+ op: m.op,
671
+ ...(typeof m.id === "string" && m.id ? { id: m.id } : {}),
672
+ ...(typeof m.graphId === "string" && m.graphId ? { graphId: m.graphId } : {}),
673
+ ref,
674
+ };
675
+ }
657
676
  case "dream_get":
658
677
  return { t: "dream_get", ref };
659
678
  case "dream_detail":
@@ -11,6 +11,7 @@ export {
11
11
  stopWorkItem,
12
12
  backgroundWorkItem,
13
13
  workLogPage,
14
+ workTranscript,
14
15
  type WorkItem,
15
16
  type WorkDot,
16
17
  } from "@pi-unipi/core";
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/ask-user",
3
- "version": "3.0.0-alpha.40",
3
+ "version": "3.0.0-alpha.41",
4
4
  "description": "Structured user input tool for Pi coding agent — single-select, multi-select, freeform",
5
5
  "type": "module",
6
6
  "main": "index.ts",
@@ -42,7 +42,7 @@
42
42
  "access": "public"
43
43
  },
44
44
  "dependencies": {
45
- "@pi-unipi/core": "3.0.0-alpha.40"
45
+ "@pi-unipi/core": "3.0.0-alpha.41"
46
46
  },
47
47
  "peerDependencies": {
48
48
  "@earendil-works/pi-coding-agent": "^0.87.1",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/command-enchantment",
3
- "version": "3.0.0-alpha.40",
3
+ "version": "3.0.0-alpha.41",
4
4
  "description": "Enhanced TUI autocomplete for /unipi:* commands — colored, sorted, and grouped by package",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/background-tasks",
3
- "version": "3.0.0-alpha.40",
3
+ "version": "3.0.0-alpha.41",
4
4
  "description": "Background tasks for UniPi — durable shell jobs and delegated background agents with a footer dock",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -10,7 +10,7 @@
10
10
  },
11
11
  "dependencies": {
12
12
  "@earendil-works/pi-ai": "^0.87.1",
13
- "@pi-unipi/core": "3.0.0-alpha.40",
13
+ "@pi-unipi/core": "3.0.0-alpha.41",
14
14
  "turndown": "^7.2.4"
15
15
  },
16
16
  "devDependencies": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/btw",
3
- "version": "3.0.0-alpha.40",
3
+ "version": "3.0.0-alpha.41",
4
4
  "description": "A pi extension for parallel side conversations with /unipi:btw — part of the Unipi suite",
5
5
  "type": "module",
6
6
  "main": "extensions/btw.ts",
@@ -37,7 +37,7 @@
37
37
  "@earendil-works/pi-tui": "^0.87.1"
38
38
  },
39
39
  "dependencies": {
40
- "@pi-unipi/core": "3.0.0-alpha.40"
40
+ "@pi-unipi/core": "3.0.0-alpha.41"
41
41
  },
42
42
  "pi": {
43
43
  "extensions": [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/compactor",
3
- "version": "3.0.0-alpha.40",
3
+ "version": "3.0.0-alpha.41",
4
4
  "description": "Compaction for Pi — lossless zero-LLM or model summaries, rebuilt from full history, with session recall",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -33,8 +33,8 @@
33
33
  "access": "public"
34
34
  },
35
35
  "dependencies": {
36
- "@pi-unipi/core": "3.0.0-alpha.40",
37
- "@pi-unipi/info-screen": "3.0.0-alpha.40",
36
+ "@pi-unipi/core": "3.0.0-alpha.41",
37
+ "@pi-unipi/info-screen": "3.0.0-alpha.41",
38
38
  "@earendil-works/pi-agent-core": "^0.87.1"
39
39
  },
40
40
  "peerDependencies": {
@@ -58,6 +58,17 @@ export interface LhProgressItem {
58
58
  /** The committed result / failure note, clipped. */
59
59
  summary?: string;
60
60
  attempts?: number;
61
+ /** UNI-282 (graph/swarm): the subagent that runs/ran it (opens its transcript). */
62
+ operatorId?: string;
63
+ /** Committed result id (`r-<id>`) — read the full text with the graph output op. */
64
+ resultId?: string;
65
+ /** Subagent profile (graph/swarm). */
66
+ profile?: string;
67
+ startedAt?: number;
68
+ endedAt?: number;
69
+ toolCalls?: number;
70
+ /** Input + output tokens of the child run (settled). */
71
+ tokens?: number;
61
72
  }
62
73
 
63
74
  /** One long-horizon run (the current one or the last finished one). */
@@ -73,6 +84,10 @@ export interface LhProgressRun {
73
84
  ralph?: { name: string; iteration: number; maxIterations: number; checked: number; total: number };
74
85
  goal?: { objective: string; status: string; turn: number; maxTurns: number; percent?: number; summary?: string; estimatedAt?: number };
75
86
  endedAt?: number;
87
+ /** UNI-282 (graph/swarm): the durable graph id (history / output ops). */
88
+ graphId?: string;
89
+ /** Graph/swarm: result ids the supervisor's finish selected. */
90
+ selected?: string[];
76
91
  }
77
92
 
78
93
  /** One line of the shared progress log, generated from state transitions (never hand-written). */
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/core",
3
- "version": "3.0.0-alpha.40",
3
+ "version": "3.0.0-alpha.41",
4
4
  "description": "Shared utilities, event types, and constants for Unipi extension suite",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -272,6 +272,27 @@ export async function workLogPage(
272
272
  }
273
273
  }
274
274
 
275
+ /** UNI-282: a subagent's mini-transcript (published by @pi-unipi/subagents). */
276
+ export type WorkTranscriptItem =
277
+ | { kind: "task"; text: string }
278
+ | { kind: "text"; text: string }
279
+ | { kind: "tool"; name: string; arg: string; output: string; isError: boolean; running: boolean; durationMs?: number };
280
+
281
+ const SUBAGENT_TRANSCRIPT_KEY = Symbol.for("unipi.subagents.transcript");
282
+
283
+ /** Transcript items + final report of a subagent (work id `agent-<id>`, or a bare subagent id). */
284
+ export function workTranscript(id: string): { items: WorkTranscriptItem[]; report?: string; status?: string } | { error: string } {
285
+ const [kind, rest] = splitId(id);
286
+ const agentId = kind === "agent" ? rest : kind === "bg" || kind === "sidekick" ? undefined : id;
287
+ if (agentId === undefined) return { error: "Only subagents have a transcript." };
288
+ const read = (globalThis as unknown as Record<symbol, unknown>)[SUBAGENT_TRANSCRIPT_KEY] as
289
+ | ((id: string) => { items: WorkTranscriptItem[]; report?: string; status?: string } | undefined)
290
+ | undefined;
291
+ if (!read) return { error: "Subagents are not available." };
292
+ const out = read(agentId);
293
+ return out ?? { error: "That subagent is gone." };
294
+ }
295
+
275
296
  // ── change signal ────────────────────────────────────────────────────────
276
297
  //
277
298
  // A cheap "something in the work list might have changed" notifier so a TUI
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/dream",
3
- "version": "3.0.0-alpha.40",
3
+ "version": "3.0.0-alpha.41",
4
4
  "description": "A pi extension that dreams: reviews past session struggles in the background, turns repeated false paths into memory lessons, and crafts skills from errors — part of the Unipi suite",
5
5
  "type": "module",
6
6
  "main": "extensions/dream.ts",
@@ -39,7 +39,7 @@
39
39
  "@earendil-works/pi-tui": "^0.87.1"
40
40
  },
41
41
  "dependencies": {
42
- "@pi-unipi/core": "3.0.0-alpha.40"
42
+ "@pi-unipi/core": "3.0.0-alpha.41"
43
43
  },
44
44
  "pi": {
45
45
  "extensions": [
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/footer",
3
- "version": "3.0.0-alpha.40",
3
+ "version": "3.0.0-alpha.41",
4
4
  "description": "Persistent status bar for Unipi — subscribes to UNIPI_EVENTS and renders key stats from all unipi packages",
5
5
  "type": "module",
6
6
  "main": "index.ts",
@@ -32,8 +32,8 @@
32
32
  "access": "public"
33
33
  },
34
34
  "dependencies": {
35
- "@pi-unipi/core": "3.0.0-alpha.40",
36
- "@pi-unipi/background-tasks": "3.0.0-alpha.40"
35
+ "@pi-unipi/core": "3.0.0-alpha.41",
36
+ "@pi-unipi/background-tasks": "3.0.0-alpha.41"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "@earendil-works/pi-coding-agent": "^0.87.1",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/fusion",
3
- "version": "3.0.0-alpha.40",
3
+ "version": "3.0.0-alpha.41",
4
4
  "description": "Devin-style model picker, fusion presets (lead + sidekick), and Local Fusion runtime for UniPi",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -32,9 +32,9 @@
32
32
  "access": "public"
33
33
  },
34
34
  "dependencies": {
35
- "@pi-unipi/core": "3.0.0-alpha.40",
36
- "@pi-unipi/subagents": "3.0.0-alpha.40",
37
- "@pi-unipi/utility": "3.0.0-alpha.40"
35
+ "@pi-unipi/core": "3.0.0-alpha.41",
36
+ "@pi-unipi/subagents": "3.0.0-alpha.41",
37
+ "@pi-unipi/utility": "3.0.0-alpha.41"
38
38
  },
39
39
  "peerDependencies": {
40
40
  "@earendil-works/pi-ai": "^0.87.1",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/info-screen",
3
- "version": "3.0.0-alpha.40",
3
+ "version": "3.0.0-alpha.41",
4
4
  "description": "Unicrab startup splash and the /unipi:info dashboard — this session, context, usage, compaction savings",
5
5
  "type": "module",
6
6
  "main": "index.ts",
@@ -33,7 +33,7 @@
33
33
  "access": "public"
34
34
  },
35
35
  "dependencies": {
36
- "@pi-unipi/core": "3.0.0-alpha.40"
36
+ "@pi-unipi/core": "3.0.0-alpha.41"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "@earendil-works/pi-coding-agent": "^0.87.1",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/input-shortcuts",
3
- "version": "3.0.0-alpha.40",
3
+ "version": "3.0.0-alpha.41",
4
4
  "description": "Keyboard shortcuts for stash/restore, undo/redo, clipboard, and thinking toggle — chord-based overlay system",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -33,7 +33,7 @@
33
33
  "access": "public"
34
34
  },
35
35
  "dependencies": {
36
- "@pi-unipi/core": "3.0.0-alpha.40"
36
+ "@pi-unipi/core": "3.0.0-alpha.41"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "@earendil-works/pi-coding-agent": "^0.87.1",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/kanboard",
3
- "version": "3.0.0-alpha.40",
3
+ "version": "3.0.0-alpha.41",
4
4
  "description": "Kanboard v3 — deferred-work board: CLI/daemon bridge, task runner and skill",
5
5
  "type": "module",
6
6
  "main": "index.ts",
@@ -31,7 +31,7 @@
31
31
  "access": "public"
32
32
  },
33
33
  "dependencies": {
34
- "@pi-unipi/core": "3.0.0-alpha.40"
34
+ "@pi-unipi/core": "3.0.0-alpha.41"
35
35
  },
36
36
  "peerDependencies": {
37
37
  "@earendil-works/pi-coding-agent": "^0.87.1",
@@ -48,10 +48,10 @@
48
48
  "themes": []
49
49
  },
50
50
  "optionalDependencies": {
51
- "@pi-unipi/kanboard-linux-x64": "3.0.0-alpha.40",
52
- "@pi-unipi/kanboard-linux-arm64": "3.0.0-alpha.40",
53
- "@pi-unipi/kanboard-darwin-x64": "3.0.0-alpha.40",
54
- "@pi-unipi/kanboard-darwin-arm64": "3.0.0-alpha.40",
55
- "@pi-unipi/kanboard-win32-x64": "3.0.0-alpha.40"
51
+ "@pi-unipi/kanboard-linux-x64": "3.0.0-alpha.41",
52
+ "@pi-unipi/kanboard-linux-arm64": "3.0.0-alpha.41",
53
+ "@pi-unipi/kanboard-darwin-x64": "3.0.0-alpha.41",
54
+ "@pi-unipi/kanboard-darwin-arm64": "3.0.0-alpha.41",
55
+ "@pi-unipi/kanboard-win32-x64": "3.0.0-alpha.41"
56
56
  }
57
57
  }
@@ -41,7 +41,8 @@ when the task finishes or cannot continue.
41
41
  | `/unipi:ralph <prompt>` | Runs the prompt in `ralph` mode. |
42
42
  | `/unipi:swarm <prompt>` | Runs the prompt in `swarm` mode. |
43
43
  | `/unipi:graph <prompt>` | Runs the prompt in `graph` mode. |
44
- | `/unipi:<mode> status` | Shows the owner, the park slot and the judge settings. |
44
+ | `/unipi:<mode> status` | Shows the owner, the park slot and the judge settings. For `graph` and `swarm`, also the graph's step counts. |
45
+ | `/unipi:graph history`, `/unipi:swarm history` | Lists past agent graphs and the results each one selected. |
45
46
  | `/unipi:<mode> stop` | Ends the active owner. For `ralph`, it parks the loop. |
46
47
  | `/unipi:<mode> resume` | Starts the parked owner again. |
47
48
  | `/unipi:<mode> clear` | Removes the parked owner. |
@@ -58,8 +59,15 @@ Each tool shows only in its mode. `todowrite` shows in all four modes.
58
59
  |---|---|---|
59
60
  | `create_goal`, `get_goal`, `update_goal` | `goal` | Creates, reads and finishes the goal. Also changes the token budget. |
60
61
  | `ralph_done`, `loop_status` | `ralph` | Ends one iteration. Reads the loop state. |
61
- | `swarm_report`, `swarm_status`, `swarm_yield` | `swarm` | Records item results. Reads the state. Ends the turn while workers run. |
62
- | `update_agent_graph`, `graph_output`, `view_agent_graph` | `graph` | Declares the graph. Records item results. Reads the graph. |
62
+ | `update_agent_graph`, `view_agent_graph`, `yield_agent_graph`, `agent_output`, `agent_swarm_status` | `graph`, `swarm` | Adds, stops or finishes work on the agent graph. Reads the graph, a step's result and the swarm status. Ends the turn while steps run. |
63
+
64
+ `graph` and `swarm` share one durable agent graph (the Maka model). The model
65
+ adds work with dependencies (`input_ids`), and the host runs each step as a
66
+ background subagent. The model yields, and pi wakes it once at each
67
+ checkpoint: a failure, nothing left to run, or everything settled. A graph
68
+ closes only when the model finishes it with the results it chose. The graph is
69
+ saved in the project's state folder, so it survives a restart. Steps that
70
+ were running resume once in their own subagent session.
63
71
  | `todowrite` | all | Replaces the visible task list. |
64
72
 
65
73
  ## Settings