@pi-unipi/unipi 2.9.0 → 2.10.1

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 (35) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/README.md +5 -1
  3. package/package.json +23 -22
  4. package/packages/ask-user/package.json +3 -3
  5. package/packages/autocomplete/package.json +2 -2
  6. package/packages/autocomplete/src/constants.ts +7 -0
  7. package/packages/background-tasks/package.json +3 -3
  8. package/packages/btw/package.json +3 -3
  9. package/packages/compactor/package.json +4 -4
  10. package/packages/core/package.json +1 -1
  11. package/packages/footer/package.json +3 -3
  12. package/packages/image/package.json +2 -2
  13. package/packages/info-screen/package.json +3 -3
  14. package/packages/input-shortcuts/package.json +3 -3
  15. package/packages/kanboard/package.json +3 -3
  16. package/packages/mcp/package.json +3 -3
  17. package/packages/memory/package.json +3 -3
  18. package/packages/milestone/package.json +3 -3
  19. package/packages/notify/package.json +3 -3
  20. package/packages/ralph/package.json +3 -3
  21. package/packages/subagents/package.json +3 -3
  22. package/packages/trajectory/README.md +47 -0
  23. package/packages/trajectory/index.ts +80 -0
  24. package/packages/trajectory/package.json +43 -0
  25. package/packages/trajectory/src/capture.ts +83 -0
  26. package/packages/trajectory/src/project.ts +193 -0
  27. package/packages/trajectory/src/server.ts +88 -0
  28. package/packages/trajectory/src/telemetry.ts +75 -0
  29. package/packages/trajectory/src/ui.ts +67 -0
  30. package/packages/unipi/bundled.js +8259 -2621
  31. package/packages/unipi/index.ts +2 -0
  32. package/packages/updater/package.json +3 -3
  33. package/packages/utility/package.json +3 -3
  34. package/packages/web-api/package.json +2 -2
  35. package/packages/workflow/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -6,6 +6,34 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [2.10.1] — 2026-08-25
10
+
11
+ Patch release: `/unipi:trajectory` now registers argument auto-completion so users discover its `stop`, `off`, and `toggle` options inline instead of having to read the docs.
12
+
13
+ ### Fixed
14
+
15
+ - `trajectory`: `/unipi:trajectory` registered its command with only a `description` and `handler`, so the TUI never offered argument completions and users had no way to learn that `stop`/`off`/`toggle` (or running it bare to open the server) existed. Added `getArgumentCompletions` to the registered command, returning `stop`, `off`, `toggle`, and a `(no argument)` hint that opens/reuses the server — matching the action set the handler already accepts.
16
+
17
+ ### Changed
18
+
19
+ - All `@pi-unipi/*` packages and the umbrella re-versioned to `2.10.1` so npm installs keep a single synchronized workspace set and avoid nested stale package copies.
20
+
21
+ ## [2.10.0] — 2026-08-25
22
+
23
+ This release adds UniPi Trajectory, a localhost-only live inspector for the current Pi session, with durable redacted sidecar telemetry for exact request/tool timings and provider metadata.
24
+
25
+ ### Added
26
+
27
+ - `@pi-unipi/trajectory`: new `/unipi:trajectory` command that opens or reuses a local session inspector on `127.0.0.1:8176-8186`.
28
+ - Trajectory UI: turn-aware ledger, Input/Model/Tools overview timeline, search, turn/tool folding, drag-to-focus, detail tabs, light/dark theme toggle, and responsive inspector.
29
+ - Trajectory projection: current `SessionManager.getBranch()` is projected into user, assistant, tool, compaction, and branch records without mutating Pi session history or provider context.
30
+ - Trajectory telemetry: append-only `~/.unipi/trajectory/<session-id>.jsonl` sidecars capture redacted provider payload/options, tool schemas, response status/headers, TTFT, decoding/total request timing, token/cache usage, and tool execution duration when Pi hooks expose them.
31
+
32
+ ### Changed
33
+
34
+ - Umbrella `@pi-unipi/unipi` now includes trajectory and the autocomplete registry lists `/unipi:trajectory`.
35
+ - All `@pi-unipi/*` packages re-versioned to `2.10.0` so npm installs keep a single synchronized workspace set and avoid nested stale package copies.
36
+
9
37
  ## [2.9.0] — 2026-08-24
10
38
 
11
39
  This release upgrades the Pi SDK floor to `^0.84.0` (resolves to 0.84.2) across all packages and re-synchronizes every package onto a single shared version (2.9.0) after the 2.6/2.8 version drift caused npm to resolve registry copies of workspace packages — stale peers that broke clean installs (ERESOLVE) and shipped nested stale copies. It also ships the compactor auto-compaction abort fix (issue #30).
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Unipi
2
2
 
3
- 21 workspace packages that turn Pi into a full development workstation. Structured workflows, persistent memory, parallel agents, web research, notifications, context management, command autocomplete, and a live status bar — all wired together through a shared event system.
3
+ 22 workspace packages that turn Pi into a full development workstation. Structured workflows, persistent memory, parallel agents, web research, notifications, context management, command autocomplete, and a live status bar — all wired together through a shared event system.
4
4
 
5
5
  One command installs everything:
6
6
  ```bash
@@ -43,6 +43,8 @@ pi install npm:@pi-unipi/unipi
43
43
 
44
44
  **[Kanboard](./packages/kanboard/README.md)** — Web UI and TUI overlay for kanban boards. Parses all workflow documents into cards with progress indicators.
45
45
 
46
+ **[Trajectory](./packages/trajectory/README.md)** — Live localhost session inspector. Explore turns, reasoning, tool payloads/results, timing, token/cache usage, and compactions for the current session.
47
+
46
48
  **[Info Screen](./packages/info-screen/README.md)** — Dashboard overlay showing module status, tools, and custom data groups.
47
49
 
48
50
  **[Utility](./packages/utility/README.md)** — Environment info, diagnostics, cleanup, name badge, and Shiki-powered diff rendering.
@@ -95,6 +97,7 @@ Coexists triggers enhance behavior when packages are installed together. Workflo
95
97
  | Utility | `/unipi:` | env, doctor, status, cleanup, badge-name |
96
98
  | Milestone | `/unipi:milestone-` | onboard, update |
97
99
  | Kanboard | `/unipi:kanboard` | toggle, doctor |
100
+ | Trajectory | `/unipi:trajectory` | open the live current-session inspector |
98
101
  | Footer | `/unipi:footer` | toggle, settings |
99
102
  | Updater | `/unipi:` | readme, changelog, updater-settings |
100
103
  | Info | `/unipi:info` | dashboard, settings |
@@ -143,6 +146,7 @@ unipi/
143
146
  │ ├── ask-user/ # Structured input
144
147
  │ ├── milestone/ # Goal tracking
145
148
  │ ├── kanboard/ # Kanban visualization
149
+ │ ├── trajectory/ # Live session trajectory inspector
146
150
  │ ├── info-screen/ # Dashboard overlay
147
151
  │ ├── utility/ # Diagnostics, diff rendering
148
152
  │ ├── updater/ # Auto-update, browsers
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/unipi",
3
- "version": "2.9.0",
3
+ "version": "2.10.1",
4
4
  "description": "All-in-one extension suite for Pi coding agent",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -82,27 +82,28 @@
82
82
  "typebox": "^1.1.38"
83
83
  },
84
84
  "dependencies": {
85
- "@pi-unipi/ask-user": "2.9.0",
86
- "@pi-unipi/background-tasks": "2.9.0",
87
- "@pi-unipi/btw": "2.9.0",
88
- "@pi-unipi/command-enchantment": "2.9.0",
89
- "@pi-unipi/compactor": "2.9.0",
90
- "@pi-unipi/core": "2.9.0",
91
- "@pi-unipi/footer": "2.9.0",
92
- "@pi-unipi/image": "2.9.0",
93
- "@pi-unipi/info-screen": "2.9.0",
94
- "@pi-unipi/input-shortcuts": "2.9.0",
95
- "@pi-unipi/kanboard": "2.9.0",
96
- "@pi-unipi/mcp": "2.9.0",
97
- "@pi-unipi/memory": "2.9.0",
98
- "@pi-unipi/milestone": "2.9.0",
99
- "@pi-unipi/notify": "2.9.0",
100
- "@pi-unipi/ralph": "2.9.0",
101
- "@pi-unipi/subagents": "2.9.0",
102
- "@pi-unipi/updater": "2.9.0",
103
- "@pi-unipi/utility": "2.9.0",
104
- "@pi-unipi/web-api": "2.9.0",
105
- "@pi-unipi/workflow": "2.9.0"
85
+ "@pi-unipi/ask-user": "2.10.0",
86
+ "@pi-unipi/background-tasks": "2.10.0",
87
+ "@pi-unipi/btw": "2.10.0",
88
+ "@pi-unipi/command-enchantment": "2.10.0",
89
+ "@pi-unipi/compactor": "2.10.0",
90
+ "@pi-unipi/core": "2.10.0",
91
+ "@pi-unipi/footer": "2.10.0",
92
+ "@pi-unipi/image": "2.10.0",
93
+ "@pi-unipi/info-screen": "2.10.0",
94
+ "@pi-unipi/input-shortcuts": "2.10.0",
95
+ "@pi-unipi/kanboard": "2.10.0",
96
+ "@pi-unipi/mcp": "2.10.0",
97
+ "@pi-unipi/memory": "2.10.0",
98
+ "@pi-unipi/milestone": "2.10.0",
99
+ "@pi-unipi/notify": "2.10.0",
100
+ "@pi-unipi/ralph": "2.10.0",
101
+ "@pi-unipi/subagents": "2.10.0",
102
+ "@pi-unipi/trajectory": "2.10.0",
103
+ "@pi-unipi/updater": "2.10.0",
104
+ "@pi-unipi/utility": "2.10.0",
105
+ "@pi-unipi/web-api": "2.10.0",
106
+ "@pi-unipi/workflow": "2.10.0"
106
107
  },
107
108
  "devDependencies": {
108
109
  "@earendil-works/pi-agent-core": "^0.84.0",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pi-unipi/ask-user",
3
- "version": "2.9.0",
4
- "description": "Structured user input tool for Pi coding agent \u2014 single-select, multi-select, freeform",
3
+ "version": "2.10.1",
4
+ "description": "Structured user input tool for Pi coding agent single-select, multi-select, freeform",
5
5
  "type": "module",
6
6
  "main": "index.ts",
7
7
  "license": "MIT",
@@ -40,7 +40,7 @@
40
40
  "access": "public"
41
41
  },
42
42
  "dependencies": {
43
- "@pi-unipi/core": "2.9.0"
43
+ "@pi-unipi/core": "2.10.0"
44
44
  },
45
45
  "peerDependencies": {
46
46
  "@earendil-works/pi-coding-agent": "^0.84.0",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pi-unipi/command-enchantment",
3
- "version": "2.9.0",
4
- "description": "Enhanced TUI autocomplete for /unipi:* commands \u2014 colored, sorted, and grouped by package",
3
+ "version": "2.10.1",
4
+ "description": "Enhanced TUI autocomplete for /unipi:* commands colored, sorted, and grouped by package",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
7
7
  "license": "MIT",
@@ -30,6 +30,7 @@ export const PACKAGE_ORDER: string[] = [
30
30
  "compact",
31
31
  "notify",
32
32
  "kanboard",
33
+ "trajectory",
33
34
  "footer",
34
35
  "updater",
35
36
  "input-shortcuts",
@@ -54,6 +55,7 @@ export const PACKAGE_COLORS: Record<string, string> = {
54
55
  compact: `${ESC}[37m`, // White
55
56
  notify: `${ESC}[96m`, // Bright Cyan
56
57
  kanboard: `${ESC}[92m`, // Bright Green
58
+ trajectory: `${ESC}[94m`, // Bright Blue
57
59
  footer: `${ESC}[34m`, // Blue
58
60
  updater: `${ESC}[93m`, // Bright Yellow
59
61
  "input-shortcuts": `${ESC}[95m`, // Bright Magenta
@@ -190,6 +192,9 @@ export const COMMAND_REGISTRY: Record<string, string> = {
190
192
  "unipi:kanboard": "kanboard",
191
193
  "unipi:kanboard-doctor": "kanboard",
192
194
 
195
+ // trajectory (1 command)
196
+ "unipi:trajectory": "trajectory",
197
+
193
198
  // footer (3 commands)
194
199
  "unipi:footer": "footer",
195
200
  "unipi:footer-settings": "footer",
@@ -267,6 +272,7 @@ export const COMMAND_DESCRIPTIONS: Record<string, string> = {
267
272
  "unipi:util-settings": "Unified settings — badge + diff rendering config",
268
273
  "unipi:kanboard": "Start the kanboard visualization server",
269
274
  "unipi:kanboard-doctor": "Diagnose and fix kanboard parser issues",
275
+ "unipi:trajectory": "Open/reuse trajectory; add stop/off or toggle to close it",
270
276
 
271
277
  "unipi:ask-user-settings": "Configure ask-user settings",
272
278
 
@@ -340,6 +346,7 @@ export const PACKAGE_LABELS: Record<string, string> = {
340
346
  compact: "compact",
341
347
  notify: "notify",
342
348
  kanboard: "kanboard",
349
+ trajectory: "trajectory",
343
350
  footer: "footer",
344
351
  updater: "updater",
345
352
  "input-shortcuts": "input-shortcuts",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pi-unipi/background-tasks",
3
- "version": "2.9.0",
4
- "description": "Background tasks for UniPi \u2014 durable shell jobs, delegated agents, attested Pi runs, and fixed-purpose Fusion workflows",
3
+ "version": "2.10.1",
4
+ "description": "Background tasks for UniPi durable shell jobs, delegated agents, attested Pi runs, and fixed-purpose Fusion workflows",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
7
7
  "types": "src/index.ts",
@@ -10,7 +10,7 @@
10
10
  },
11
11
  "dependencies": {
12
12
  "@earendil-works/pi-ai": "^0.84.0",
13
- "@pi-unipi/core": "2.9.0",
13
+ "@pi-unipi/core": "2.10.0",
14
14
  "turndown": "^7.2.4"
15
15
  },
16
16
  "devDependencies": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pi-unipi/btw",
3
- "version": "2.9.0",
4
- "description": "A pi extension for parallel side conversations with /unipi:btw \u2014 part of the Unipi suite",
3
+ "version": "2.10.1",
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",
7
7
  "license": "MIT",
@@ -37,7 +37,7 @@
37
37
  "@earendil-works/pi-tui": "^0.84.0"
38
38
  },
39
39
  "dependencies": {
40
- "@pi-unipi/core": "2.9.0"
40
+ "@pi-unipi/core": "2.10.0"
41
41
  },
42
42
  "pi": {
43
43
  "extensions": [
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pi-unipi/compactor",
3
- "version": "2.9.0",
4
- "description": "Context engine for Pi \u2014 zero-LLM compaction, session continuity, sandbox execution, and tool display optimization",
3
+ "version": "2.10.1",
4
+ "description": "Context engine for Pi zero-LLM compaction, session continuity, sandbox execution, and tool display optimization",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
7
7
  "license": "MIT",
@@ -34,8 +34,8 @@
34
34
  "access": "public"
35
35
  },
36
36
  "dependencies": {
37
- "@pi-unipi/core": "2.9.0",
38
- "@pi-unipi/info-screen": "2.9.0",
37
+ "@pi-unipi/core": "2.10.0",
38
+ "@pi-unipi/info-screen": "2.10.0",
39
39
  "@earendil-works/pi-agent-core": "^0.84.0"
40
40
  },
41
41
  "peerDependencies": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/core",
3
- "version": "2.9.0",
3
+ "version": "2.10.1",
4
4
  "description": "Shared utilities, event types, and constants for Unipi extension suite",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pi-unipi/footer",
3
- "version": "2.9.0",
4
- "description": "Persistent status bar for Unipi \u2014 subscribes to UNIPI_EVENTS and renders key stats from all unipi packages",
3
+ "version": "2.10.1",
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",
7
7
  "license": "MIT",
@@ -32,7 +32,7 @@
32
32
  "access": "public"
33
33
  },
34
34
  "dependencies": {
35
- "@pi-unipi/core": "2.9.0"
35
+ "@pi-unipi/core": "2.10.0"
36
36
  },
37
37
  "peerDependencies": {
38
38
  "@earendil-works/pi-coding-agent": "^0.84.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/image",
3
- "version": "2.9.0",
3
+ "version": "2.10.1",
4
4
  "description": "Image generation and image recognition tools for the Pi coding agent",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -34,7 +34,7 @@
34
34
  "access": "public"
35
35
  },
36
36
  "dependencies": {
37
- "@pi-unipi/core": "2.9.0"
37
+ "@pi-unipi/core": "2.10.0"
38
38
  },
39
39
  "peerDependencies": {
40
40
  "@earendil-works/pi-ai": "^0.84.0",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pi-unipi/info-screen",
3
- "version": "2.9.0",
4
- "description": "Dashboard and module registry for Unipi \u2014 configurable info overlay with tabbed groups",
3
+ "version": "2.10.1",
4
+ "description": "Dashboard and module registry for Unipi configurable info overlay with tabbed groups",
5
5
  "type": "module",
6
6
  "main": "index.ts",
7
7
  "license": "MIT",
@@ -33,7 +33,7 @@
33
33
  "access": "public"
34
34
  },
35
35
  "dependencies": {
36
- "@pi-unipi/core": "2.9.0"
36
+ "@pi-unipi/core": "2.10.0"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "@earendil-works/pi-coding-agent": "^0.84.0",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pi-unipi/input-shortcuts",
3
- "version": "2.9.0",
4
- "description": "Keyboard shortcuts for stash/restore, undo/redo, clipboard, and thinking toggle \u2014 chord-based overlay system",
3
+ "version": "2.10.1",
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",
7
7
  "license": "MIT",
@@ -33,7 +33,7 @@
33
33
  "access": "public"
34
34
  },
35
35
  "dependencies": {
36
- "@pi-unipi/core": "2.9.0"
36
+ "@pi-unipi/core": "2.10.0"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "@earendil-works/pi-coding-agent": "^0.84.0",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pi-unipi/kanboard",
3
- "version": "2.9.0",
4
- "description": "Visualization layer for unipi workflow \u2014 HTTP server with htmx/Alpine.js UI, modular parsers, TUI overlay, and kanban board",
3
+ "version": "2.10.1",
4
+ "description": "Visualization layer for unipi workflow HTTP server with htmx/Alpine.js UI, modular parsers, TUI overlay, and kanban board",
5
5
  "type": "module",
6
6
  "main": "index.ts",
7
7
  "license": "MIT",
@@ -39,7 +39,7 @@
39
39
  "access": "public"
40
40
  },
41
41
  "dependencies": {
42
- "@pi-unipi/core": "2.9.0"
42
+ "@pi-unipi/core": "2.10.0"
43
43
  },
44
44
  "peerDependencies": {
45
45
  "@earendil-works/pi-coding-agent": "^0.84.0",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pi-unipi/mcp",
3
- "version": "2.9.0",
4
- "description": "MCP server management extension for Pi coding agent \u2014 browse, add, configure, and use MCP servers",
3
+ "version": "2.10.1",
4
+ "description": "MCP server management extension for Pi coding agent browse, add, configure, and use MCP servers",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
7
7
  "license": "MIT",
@@ -30,7 +30,7 @@
30
30
  "test": "npx tsx --test tests/**/*.test.ts"
31
31
  },
32
32
  "dependencies": {
33
- "@pi-unipi/core": "2.9.0"
33
+ "@pi-unipi/core": "2.10.0"
34
34
  },
35
35
  "peerDependencies": {
36
36
  "@earendil-works/pi-coding-agent": "^0.84.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/memory",
3
- "version": "2.9.0",
3
+ "version": "2.10.1",
4
4
  "description": "Persistent cross-session memory with MemPalace backend (auto-installed) and SQLite fallback for Pi coding agent",
5
5
  "type": "module",
6
6
  "main": "index.ts",
@@ -39,8 +39,8 @@
39
39
  "README.md"
40
40
  ],
41
41
  "dependencies": {
42
- "@pi-unipi/core": "2.9.0",
43
- "@pi-unipi/info-screen": "2.9.0",
42
+ "@pi-unipi/core": "2.10.0",
43
+ "@pi-unipi/info-screen": "2.10.0",
44
44
  "js-yaml": "^4.1.0"
45
45
  },
46
46
  "peerDependencies": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pi-unipi/milestone",
3
- "version": "2.9.0",
4
- "description": "Lifecycle layer for project-level goals \u2014 MILESTONES.md tracking, session hooks, auto-sync",
3
+ "version": "2.10.1",
4
+ "description": "Lifecycle layer for project-level goals MILESTONES.md tracking, session hooks, auto-sync",
5
5
  "type": "module",
6
6
  "main": "index.ts",
7
7
  "scripts": {
@@ -32,7 +32,7 @@
32
32
  "access": "public"
33
33
  },
34
34
  "dependencies": {
35
- "@pi-unipi/core": "2.9.0"
35
+ "@pi-unipi/core": "2.10.0"
36
36
  },
37
37
  "peerDependencies": {
38
38
  "@earendil-works/pi-coding-agent": "^0.84.0",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pi-unipi/notify",
3
- "version": "2.9.0",
4
- "description": "Cross-platform notification extension for Pi \u2014 native OS, Gotify, and Telegram notifications for agent lifecycle events",
3
+ "version": "2.10.1",
4
+ "description": "Cross-platform notification extension for Pi native OS, Gotify, and Telegram notifications for agent lifecycle events",
5
5
  "type": "module",
6
6
  "main": "index.ts",
7
7
  "license": "MIT",
@@ -34,7 +34,7 @@
34
34
  "access": "public"
35
35
  },
36
36
  "dependencies": {
37
- "@pi-unipi/core": "2.9.0",
37
+ "@pi-unipi/core": "2.10.0",
38
38
  "node-notifier": "^10.0.1"
39
39
  },
40
40
  "peerDependencies": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-unipi/ralph",
3
- "version": "2.9.0",
3
+ "version": "2.10.1",
4
4
  "description": "Long-running iterative development loops for Pi coding agent",
5
5
  "type": "module",
6
6
  "main": "index.ts",
@@ -31,8 +31,8 @@
31
31
  "test": "npx tsx --test reminder.test.ts"
32
32
  },
33
33
  "dependencies": {
34
- "@pi-unipi/core": "2.9.0",
35
- "@pi-unipi/info-screen": "2.9.0"
34
+ "@pi-unipi/core": "2.10.0",
35
+ "@pi-unipi/info-screen": "2.10.0"
36
36
  },
37
37
  "peerDependencies": {
38
38
  "@earendil-works/pi-ai": "^0.84.0",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@pi-unipi/subagents",
3
- "version": "2.9.0",
4
- "description": "Subagents for UniPi \u2014 parallel execution, file locking, workflow integration",
3
+ "version": "2.10.1",
4
+ "description": "Subagents for UniPi parallel execution, file locking, workflow integration",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
7
7
  "types": "src/index.ts",
@@ -9,7 +9,7 @@
9
9
  "test": "npx tsx --test src/__tests__/*.test.ts"
10
10
  },
11
11
  "dependencies": {
12
- "@pi-unipi/core": "2.9.0",
12
+ "@pi-unipi/core": "2.10.0",
13
13
  "@earendil-works/pi-agent-core": "^0.84.0",
14
14
  "acorn": "8.18.0"
15
15
  },
@@ -0,0 +1,47 @@
1
+ # @pi-unipi/trajectory
2
+
3
+ Live, localhost-only UniPi trajectory inspector for the current Pi session.
4
+
5
+ ## Usage
6
+
7
+ ```text
8
+ /unipi:trajectory # open or reuse the server
9
+ /unipi:trajectory stop # stop this session's server
10
+ /unipi:trajectory off # alias of stop
11
+ /unipi:trajectory toggle # open when stopped, stop when running
12
+ ```
13
+
14
+ Typing `/unipi:trajectory` followed by a space auto-completes the available
15
+ actions (`stop`, `off`, `toggle`), so the options are discoverable without
16
+ reading the docs. Running it with no argument opens or reuses the server.
17
+
18
+ The command starts or reuses an in-process server on `127.0.0.1:8176-8186` and opens it in the default browser. The page follows the active session every 500 ms. The server is owned by the current Pi process and is stopped on any Pi session shutdown/reload/resume/new/fork event.
19
+
20
+ ## What it shows
21
+
22
+ - Turn-aware User, Assistant, Tool, Compaction, and Branch ledger
23
+ - Assistant reasoning and final output
24
+ - Tool payloads, results, errors, and measured call duration
25
+ - Provider, model, stop reason, token usage, cache reads/writes, and cost
26
+ - Provider, model, thinking level, request payload/options, tool schemas, response status/headers
27
+ - Exact TTFT, decoding/total request timing, and tool execution timing
28
+ - Input/Model/Tools overview timeline with drag-to-focus
29
+ - Search, turn folding, call folding, and a local record inspector
30
+
31
+ ## Privacy and model behavior
32
+
33
+ The server binds only to `127.0.0.1`. It reads `SessionManager.getBranch()` and never appends or changes session entries, prompts, provider requests, or model context. It therefore has no prefix-cache effect.
34
+
35
+ Detailed telemetry is appended to `~/.unipi/trajectory/<session-id>.jsonl` with a private directory/file mode. Authorization, API-key, token, cookie, secret, password, and credential fields and credential-shaped values are recursively redacted before persistence.
36
+
37
+ Detailed request fields appear when captured by the trajectory telemetry sidecar.
38
+
39
+ ## Lifecycle
40
+
41
+ Each Pi process owns its own trajectory server. A second Pi process running `/unipi:trajectory` picks the next free localhost port in `8176-8186`; it never attaches to or controls another Pi process's server. When the owning Pi session exits, reloads, resumes another session, starts a new session, or forks, its server is closed.
42
+
43
+ ## Limitations
44
+
45
+ - Live transport uses 500 ms polling rather than a push stream.
46
+ - Very large branches are rendered in one table; browser virtualization can be added if measured sessions require it.
47
+ - Tool duration uses exact executor telemetry when captured and session timestamps otherwise.
@@ -0,0 +1,80 @@
1
+ import type { ExtensionAPI, ExtensionContext, SessionEntry } from "@earendil-works/pi-coding-agent";
2
+ import { registerTelemetryCapture } from "./src/capture.js";
3
+ import { projectTrajectory } from "./src/project.js";
4
+ import { openBrowser, TrajectoryServer } from "./src/server.js";
5
+
6
+ let server: TrajectoryServer | null = null;
7
+ let currentContext: ExtensionContext | null = null;
8
+
9
+ function stopServer(): boolean {
10
+ if (!server?.url) return false;
11
+ server.stop();
12
+ server = null;
13
+ return true;
14
+ }
15
+
16
+ export default function trajectory(pi: ExtensionAPI): void {
17
+ const readTelemetry = registerTelemetryCapture(pi);
18
+
19
+ pi.registerCommand("unipi:trajectory", {
20
+ description: "Open or manage UniPi's live trajectory for the current session",
21
+ getArgumentCompletions: (argumentPrefix: string) => {
22
+ const prefix = argumentPrefix.trim().toLowerCase();
23
+ const actions = [
24
+ { value: "stop", label: "stop", description: "Stop this session's trajectory server" },
25
+ { value: "off", label: "off", description: "Alias of stop" },
26
+ { value: "toggle", label: "toggle", description: "Open when stopped, stop when running" },
27
+ ];
28
+ const matches = prefix
29
+ ? actions.filter((a) => a.value.startsWith(prefix) || a.label.startsWith(prefix))
30
+ : actions;
31
+ // With no prefix (or a matching one) also surface a hint that running bare
32
+ // opens/reuses the server, so users learn the default behavior exists.
33
+ const items = matches.map((a) => ({ value: a.value, label: a.label, description: a.description }));
34
+ if (!prefix) {
35
+ items.unshift({
36
+ value: "",
37
+ label: "(no argument)",
38
+ description: "Open or reuse the trajectory server in the browser",
39
+ });
40
+ }
41
+ return items;
42
+ },
43
+ handler: async (args, ctx) => {
44
+ const action = String(args ?? "").trim().toLowerCase();
45
+ const wantsStop = ["stop", "off", "--stop", "--off"].includes(action);
46
+ const wantsToggle = ["toggle", "--toggle"].includes(action);
47
+ if (wantsStop || (wantsToggle && server?.url)) {
48
+ ctx.ui.notify(stopServer() ? "Trajectory stopped" : "Trajectory is not running", "info");
49
+ return;
50
+ }
51
+
52
+ currentContext = ctx;
53
+ if (!server) {
54
+ server = new TrajectoryServer({
55
+ snapshot: () => {
56
+ const active = currentContext ?? ctx;
57
+ return projectTrajectory(active.sessionManager.getBranch() as SessionEntry[], {
58
+ sessionId: active.sessionManager.getSessionId(),
59
+ name: active.sessionManager.getSessionName(),
60
+ cwd: active.cwd,
61
+ }, readTelemetry());
62
+ },
63
+ });
64
+ }
65
+ try {
66
+ const url = await server.start();
67
+ openBrowser(url);
68
+ ctx.ui.notify(`Trajectory running at ${url}`, "info");
69
+ } catch (error) {
70
+ ctx.ui.notify(`Trajectory error: ${error instanceof Error ? error.message : String(error)}`, "error");
71
+ }
72
+ },
73
+ });
74
+
75
+ pi.on("session_start", (_event, ctx) => { currentContext = ctx; });
76
+ pi.on("session_shutdown", () => {
77
+ currentContext = null;
78
+ stopServer();
79
+ });
80
+ }