@gotgenes/pi-subagents 6.16.3 → 6.17.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 (54) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/docs/architecture/architecture.md +588 -535
  3. package/docs/architecture/history/phase-1-api-boundary.md +8 -0
  4. package/docs/architecture/history/phase-2-remove-scheduling.md +9 -0
  5. package/docs/architecture/history/phase-3-remove-rpc-groupjoin.md +11 -0
  6. package/docs/architecture/history/phase-4-implement-service.md +8 -0
  7. package/docs/architecture/history/phase-5-decompose-index.md +42 -0
  8. package/docs/architecture/history/phase-7-encapsulation.md +173 -0
  9. package/docs/architecture/history/phase-8-testability.md +103 -0
  10. package/docs/architecture/history/phase-9-observation-ctx.md +122 -0
  11. package/docs/plans/0147-inject-wrap-text-into-conversation-viewer.md +166 -0
  12. package/docs/retro/0147-inject-wrap-text-into-conversation-viewer.md +90 -0
  13. package/package.json +1 -1
  14. package/src/agent-manager.ts +11 -11
  15. package/src/agent-record.ts +6 -6
  16. package/src/agent-runner.ts +6 -6
  17. package/src/agent-types.ts +2 -2
  18. package/src/custom-agents.ts +3 -3
  19. package/src/default-agents.ts +1 -1
  20. package/src/env.ts +2 -2
  21. package/src/handlers/index.ts +2 -2
  22. package/src/index.ts +26 -26
  23. package/src/invocation-config.ts +1 -1
  24. package/src/memory.ts +2 -2
  25. package/src/notification.ts +4 -4
  26. package/src/parent-snapshot.ts +1 -1
  27. package/src/prompts.ts +2 -2
  28. package/src/record-observer.ts +2 -2
  29. package/src/renderer.ts +2 -2
  30. package/src/runtime.ts +2 -2
  31. package/src/service-adapter.ts +5 -5
  32. package/src/service.ts +1 -1
  33. package/src/session-config.ts +5 -5
  34. package/src/skill-loader.ts +2 -2
  35. package/src/tools/agent-tool.ts +11 -11
  36. package/src/tools/background-spawner.ts +8 -8
  37. package/src/tools/foreground-runner.ts +9 -9
  38. package/src/tools/get-result-tool.ts +5 -5
  39. package/src/tools/helpers.ts +4 -4
  40. package/src/tools/spawn-config.ts +6 -6
  41. package/src/tools/steer-tool.ts +3 -3
  42. package/src/types.ts +1 -1
  43. package/src/ui/agent-activity-tracker.ts +1 -1
  44. package/src/ui/agent-config-editor.ts +4 -4
  45. package/src/ui/agent-creation-wizard.ts +5 -5
  46. package/src/ui/agent-menu.ts +12 -10
  47. package/src/ui/agent-widget.ts +5 -5
  48. package/src/ui/conversation-viewer.ts +33 -21
  49. package/src/ui/display.ts +2 -2
  50. package/src/ui/ui-observer.ts +1 -1
  51. package/src/ui/widget-renderer.ts +5 -5
  52. package/src/worktree-state.ts +1 -1
  53. package/src/worktree.ts +1 -1
  54. package/vitest.config.ts +14 -0
@@ -7,10 +7,10 @@
7
7
 
8
8
  import { join } from "node:path";
9
9
 
10
- import type { AgentTypeRegistry } from "../agent-types.js";
11
- import type { AgentConfig } from "../types.js";
12
- import type { AgentFileOps } from "./agent-file-ops.js";
13
- import type { MenuUI } from "./agent-menu.js";
10
+ import type { AgentTypeRegistry } from "../agent-types";
11
+ import type { AgentConfig } from "../types";
12
+ import type { AgentFileOps } from "./agent-file-ops";
13
+ import type { MenuUI } from "./agent-menu";
14
14
 
15
15
  // ---- Factory ----
16
16
 
@@ -7,11 +7,11 @@
7
7
 
8
8
  import { join } from "node:path";
9
9
 
10
- import { BUILTIN_TOOL_NAMES } from "../agent-types.js";
11
- import type { ParentSnapshot } from "../parent-snapshot.js";
12
- import type { AgentRecord } from "../types.js";
13
- import type { AgentFileOps } from "./agent-file-ops.js";
14
- import type { MenuUI } from "./agent-menu.js";
10
+ import { BUILTIN_TOOL_NAMES } from "../agent-types";
11
+ import type { ParentSnapshot } from "../parent-snapshot";
12
+ import type { AgentRecord } from "../types";
13
+ import type { AgentFileOps } from "./agent-file-ops";
14
+ import type { MenuUI } from "./agent-menu";
15
15
 
16
16
  // ---- Deps interface ----
17
17
 
@@ -1,12 +1,13 @@
1
- import { AgentTypeRegistry } from "../agent-types.js";
2
- import type { ModelRegistry } from "../model-resolver.js";
3
- import type { ParentSnapshot } from "../parent-snapshot.js";
4
- import type { AgentConfig, AgentRecord } from "../types.js";
5
- import type { AgentActivityTracker } from "./agent-activity-tracker.js";
6
- import { createAgentConfigEditor } from "./agent-config-editor.js";
7
- import { createAgentCreationWizard } from "./agent-creation-wizard.js";
8
- import type { AgentFileOps } from "./agent-file-ops.js";
9
- import { formatDuration, getDisplayName } from "./display.js";
1
+ import { wrapTextWithAnsi } from "@earendil-works/pi-tui";
2
+ import { AgentTypeRegistry } from "../agent-types";
3
+ import type { ModelRegistry } from "../model-resolver";
4
+ import type { ParentSnapshot } from "../parent-snapshot";
5
+ import type { AgentConfig, AgentRecord } from "../types";
6
+ import type { AgentActivityTracker } from "./agent-activity-tracker";
7
+ import { createAgentConfigEditor } from "./agent-config-editor";
8
+ import { createAgentCreationWizard } from "./agent-creation-wizard";
9
+ import type { AgentFileOps } from "./agent-file-ops";
10
+ import { formatDuration, getDisplayName } from "./display";
10
11
 
11
12
  // ---- Deps interface ----
12
13
 
@@ -246,7 +247,7 @@ export function createAgentsMenuHandler({
246
247
  }
247
248
 
248
249
  const { ConversationViewer, VIEWPORT_HEIGHT_PCT } = await import(
249
- "./conversation-viewer.js"
250
+ "./conversation-viewer"
250
251
  );
251
252
  const activity = agentActivity.get(record.id);
252
253
 
@@ -260,6 +261,7 @@ export function createAgentsMenuHandler({
260
261
  theme,
261
262
  done,
262
263
  registry,
264
+ wrapText: wrapTextWithAnsi,
263
265
  });
264
266
  },
265
267
  {
@@ -5,11 +5,11 @@
5
5
  * Uses the callback form of setWidget for themed rendering.
6
6
  */
7
7
 
8
- import type { AgentManager } from "../agent-manager.js";
9
- import { AgentTypeRegistry } from "../agent-types.js";
10
- import type { AgentActivityTracker } from "./agent-activity-tracker.js";
11
- import { ERROR_STATUSES, type Theme } from "./display.js";
12
- import { renderWidgetLines } from "./widget-renderer.js";
8
+ import type { AgentManager } from "../agent-manager";
9
+ import { AgentTypeRegistry } from "../agent-types";
10
+ import type { AgentActivityTracker } from "./agent-activity-tracker";
11
+ import { ERROR_STATUSES, type Theme } from "./display";
12
+ import { renderWidgetLines } from "./widget-renderer";
13
13
 
14
14
  // ---- Types ----
15
15
 
@@ -6,13 +6,13 @@
6
6
  */
7
7
 
8
8
  import type { AgentSession } from "@earendil-works/pi-coding-agent";
9
- import { type Component, matchesKey, type TUI, truncateToWidth, visibleWidth, wrapTextWithAnsi } from "@earendil-works/pi-tui";
10
- import type { AgentConfigLookup } from "../agent-types.js";
11
- import { extractText } from "../context.js";
12
- import type { AgentRecord } from "../types.js";
13
- import { getLifetimeTotal, getSessionContextPercent } from "../usage.js";
14
- import type { AgentActivityTracker } from "./agent-activity-tracker.js";
15
- import { buildInvocationTags, describeActivity, formatDuration, formatSessionTokens, getDisplayName, getPromptModeLabel, type Theme } from "./display.js";
9
+ import { type Component, matchesKey, type TUI, truncateToWidth, visibleWidth } from "@earendil-works/pi-tui";
10
+ import type { AgentConfigLookup } from "../agent-types";
11
+ import { extractText } from "../context";
12
+ import type { AgentRecord } from "../types";
13
+ import { getLifetimeTotal, getSessionContextPercent } from "../usage";
14
+ import type { AgentActivityTracker } from "./agent-activity-tracker";
15
+ import { buildInvocationTags, describeActivity, formatDuration, formatSessionTokens, getDisplayName, getPromptModeLabel, type Theme } from "./display";
16
16
 
17
17
  // ── Local message-shape types ───────────────────────────────────────────────
18
18
  // The Pi SDK does not export narrow types for all message content variants.
@@ -59,6 +59,7 @@ export interface ConversationViewerOptions {
59
59
  theme: Theme;
60
60
  done: (result: undefined) => void;
61
61
  registry: AgentConfigLookup;
62
+ wrapText: (text: string, width: number) => string[];
62
63
  }
63
64
 
64
65
  export class ConversationViewer implements Component {
@@ -75,16 +76,27 @@ export class ConversationViewer implements Component {
75
76
  private theme: Theme;
76
77
  private done: (result: undefined) => void;
77
78
  private registry: AgentConfigLookup;
78
-
79
- constructor(options: ConversationViewerOptions) {
80
- this.tui = options.tui;
81
- this.session = options.session;
82
- this.record = options.record;
83
- this.activity = options.activity;
84
- this.theme = options.theme;
85
- this.done = options.done;
86
- this.registry = options.registry;
87
- this.unsubscribe = options.session.subscribe(() => {
79
+ private wrapText: (text: string, width: number) => string[];
80
+
81
+ constructor({
82
+ tui,
83
+ session,
84
+ record,
85
+ activity,
86
+ theme,
87
+ done,
88
+ registry,
89
+ wrapText,
90
+ }: ConversationViewerOptions) {
91
+ this.tui = tui;
92
+ this.session = session;
93
+ this.record = record;
94
+ this.activity = activity;
95
+ this.theme = theme;
96
+ this.done = done;
97
+ this.registry = registry;
98
+ this.wrapText = wrapText;
99
+ this.unsubscribe = session.subscribe(() => {
88
100
  if (this.closed) return;
89
101
  this.tui.requestRender();
90
102
  });
@@ -253,7 +265,7 @@ export class ConversationViewer implements Component {
253
265
  if (!text.trim()) continue;
254
266
  if (needsSeparator) lines.push(th.fg("dim", "───"));
255
267
  lines.push(th.fg("accent", "[User]"));
256
- for (const line of wrapTextWithAnsi(text.trim(), width)) {
268
+ for (const line of this.wrapText(text.trim(), width)) {
257
269
  lines.push(line);
258
270
  }
259
271
  } else if (msg.role === "assistant") {
@@ -268,7 +280,7 @@ export class ConversationViewer implements Component {
268
280
  if (needsSeparator) lines.push(th.fg("dim", "───"));
269
281
  lines.push(th.bold("[Assistant]"));
270
282
  if (textParts.length > 0) {
271
- for (const line of wrapTextWithAnsi(textParts.join("\n").trim(), width)) {
283
+ for (const line of this.wrapText(textParts.join("\n").trim(), width)) {
272
284
  lines.push(line);
273
285
  }
274
286
  }
@@ -281,7 +293,7 @@ export class ConversationViewer implements Component {
281
293
  if (!truncated.trim()) continue;
282
294
  if (needsSeparator) lines.push(th.fg("dim", "───"));
283
295
  lines.push(th.fg("dim", "[Result]"));
284
- for (const line of wrapTextWithAnsi(truncated.trim(), width)) {
296
+ for (const line of this.wrapText(truncated.trim(), width)) {
285
297
  lines.push(th.fg("dim", line));
286
298
  }
287
299
  } else if (isBashExecution(msg)) {
@@ -291,7 +303,7 @@ export class ConversationViewer implements Component {
291
303
  const out = msg.output.length > 500
292
304
  ? msg.output.slice(0, 500) + "... (truncated)"
293
305
  : msg.output;
294
- for (const line of wrapTextWithAnsi(out.trim(), width)) {
306
+ for (const line of this.wrapText(out.trim(), width)) {
295
307
  lines.push(th.fg("dim", line));
296
308
  }
297
309
  }
package/src/ui/display.ts CHANGED
@@ -5,8 +5,8 @@
5
5
  * Consumed by the widget, the menu, tool modules, and the notification renderer.
6
6
  */
7
7
 
8
- import type { AgentConfigLookup } from "../agent-types.js";
9
- import type { AgentInvocation, SubagentType } from "../types.js";
8
+ import type { AgentConfigLookup } from "../agent-types";
9
+ import type { AgentInvocation, SubagentType } from "../types";
10
10
 
11
11
  // ---- Types ----
12
12
 
@@ -6,7 +6,7 @@
6
6
  * turn count, lifetime usage).
7
7
  */
8
8
 
9
- import type { AgentActivityTracker } from "./agent-activity-tracker.js";
9
+ import type { AgentActivityTracker } from "./agent-activity-tracker";
10
10
 
11
11
  /** Narrow session interface — only the subscribe method needed by the observer. */
12
12
  interface SubscribableSession {
@@ -6,10 +6,10 @@
6
6
  */
7
7
 
8
8
  import { truncateToWidth } from "@earendil-works/pi-tui";
9
- import type { AgentConfigLookup } from "../agent-types.js";
10
- import type { SubagentType } from "../types.js";
11
- import type { LifetimeUsage, SessionLike } from "../usage.js";
12
- import { getLifetimeTotal, getSessionContextPercent } from "../usage.js";
9
+ import type { AgentConfigLookup } from "../agent-types";
10
+ import type { SubagentType } from "../types";
11
+ import type { LifetimeUsage, SessionLike } from "../usage";
12
+ import { getLifetimeTotal, getSessionContextPercent } from "../usage";
13
13
  import {
14
14
  describeActivity,
15
15
  formatMs,
@@ -19,7 +19,7 @@ import {
19
19
  getPromptModeLabel,
20
20
  SPINNER,
21
21
  type Theme,
22
- } from "./display.js";
22
+ } from "./display";
23
23
 
24
24
  // ── Data interfaces ──────────────────────────────────────────────────────────
25
25
 
@@ -6,7 +6,7 @@
6
6
  * cleanupResult is recorded once at completion or error — it is not set at construction.
7
7
  */
8
8
 
9
- import type { WorktreeCleanupResult, WorktreeInfo } from "./worktree.js";
9
+ import type { WorktreeCleanupResult, WorktreeInfo } from "./worktree";
10
10
 
11
11
  export type { WorktreeCleanupResult, WorktreeInfo };
12
12
 
package/src/worktree.ts CHANGED
@@ -11,7 +11,7 @@ import { randomUUID } from "node:crypto";
11
11
  import { existsSync } from "node:fs";
12
12
  import { tmpdir } from "node:os";
13
13
  import { join } from "node:path";
14
- import { debugLog } from "./debug.js";
14
+ import { debugLog } from "./debug";
15
15
 
16
16
  export interface WorktreeInfo {
17
17
  /** Absolute path to the worktree directory. */
@@ -0,0 +1,14 @@
1
+ import path from "node:path";
2
+ import { defineConfig } from "vitest/config";
3
+
4
+ export default defineConfig({
5
+ resolve: {
6
+ alias: {
7
+ "#src": path.resolve(import.meta.dirname, "src"),
8
+ "#test": path.resolve(import.meta.dirname, "test"),
9
+ },
10
+ },
11
+ test: {
12
+ include: ["test/**/*.test.ts"],
13
+ },
14
+ });