@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.
- package/CHANGELOG.md +27 -0
- package/docs/architecture/architecture.md +588 -535
- package/docs/architecture/history/phase-1-api-boundary.md +8 -0
- package/docs/architecture/history/phase-2-remove-scheduling.md +9 -0
- package/docs/architecture/history/phase-3-remove-rpc-groupjoin.md +11 -0
- package/docs/architecture/history/phase-4-implement-service.md +8 -0
- package/docs/architecture/history/phase-5-decompose-index.md +42 -0
- package/docs/architecture/history/phase-7-encapsulation.md +173 -0
- package/docs/architecture/history/phase-8-testability.md +103 -0
- package/docs/architecture/history/phase-9-observation-ctx.md +122 -0
- package/docs/plans/0147-inject-wrap-text-into-conversation-viewer.md +166 -0
- package/docs/retro/0147-inject-wrap-text-into-conversation-viewer.md +90 -0
- package/package.json +1 -1
- package/src/agent-manager.ts +11 -11
- package/src/agent-record.ts +6 -6
- package/src/agent-runner.ts +6 -6
- package/src/agent-types.ts +2 -2
- package/src/custom-agents.ts +3 -3
- package/src/default-agents.ts +1 -1
- package/src/env.ts +2 -2
- package/src/handlers/index.ts +2 -2
- package/src/index.ts +26 -26
- package/src/invocation-config.ts +1 -1
- package/src/memory.ts +2 -2
- package/src/notification.ts +4 -4
- package/src/parent-snapshot.ts +1 -1
- package/src/prompts.ts +2 -2
- package/src/record-observer.ts +2 -2
- package/src/renderer.ts +2 -2
- package/src/runtime.ts +2 -2
- package/src/service-adapter.ts +5 -5
- package/src/service.ts +1 -1
- package/src/session-config.ts +5 -5
- package/src/skill-loader.ts +2 -2
- package/src/tools/agent-tool.ts +11 -11
- package/src/tools/background-spawner.ts +8 -8
- package/src/tools/foreground-runner.ts +9 -9
- package/src/tools/get-result-tool.ts +5 -5
- package/src/tools/helpers.ts +4 -4
- package/src/tools/spawn-config.ts +6 -6
- package/src/tools/steer-tool.ts +3 -3
- package/src/types.ts +1 -1
- package/src/ui/agent-activity-tracker.ts +1 -1
- package/src/ui/agent-config-editor.ts +4 -4
- package/src/ui/agent-creation-wizard.ts +5 -5
- package/src/ui/agent-menu.ts +12 -10
- package/src/ui/agent-widget.ts +5 -5
- package/src/ui/conversation-viewer.ts +33 -21
- package/src/ui/display.ts +2 -2
- package/src/ui/ui-observer.ts +1 -1
- package/src/ui/widget-renderer.ts +5 -5
- package/src/worktree-state.ts +1 -1
- package/src/worktree.ts +1 -1
- 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
|
|
11
|
-
import type { AgentConfig } from "../types
|
|
12
|
-
import type { AgentFileOps } from "./agent-file-ops
|
|
13
|
-
import type { MenuUI } from "./agent-menu
|
|
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
|
|
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
|
|
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
|
|
package/src/ui/agent-menu.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
3
|
-
import type {
|
|
4
|
-
import type {
|
|
5
|
-
import type {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
9
|
-
import {
|
|
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
|
|
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
|
{
|
package/src/ui/agent-widget.ts
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
9
|
-
import type { AgentInvocation, SubagentType } from "../types
|
|
8
|
+
import type { AgentConfigLookup } from "../agent-types";
|
|
9
|
+
import type { AgentInvocation, SubagentType } from "../types";
|
|
10
10
|
|
|
11
11
|
// ---- Types ----
|
|
12
12
|
|
package/src/ui/ui-observer.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* turn count, lifetime usage).
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import type { AgentActivityTracker } from "./agent-activity-tracker
|
|
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
|
|
10
|
-
import type { SubagentType } from "../types
|
|
11
|
-
import type { LifetimeUsage, SessionLike } from "../usage
|
|
12
|
-
import { getLifetimeTotal, getSessionContextPercent } from "../usage
|
|
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
|
|
22
|
+
} from "./display";
|
|
23
23
|
|
|
24
24
|
// ── Data interfaces ──────────────────────────────────────────────────────────
|
|
25
25
|
|
package/src/worktree-state.ts
CHANGED
|
@@ -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
|
|
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
|
|
14
|
+
import { debugLog } from "./debug";
|
|
15
15
|
|
|
16
16
|
export interface WorktreeInfo {
|
|
17
17
|
/** Absolute path to the worktree directory. */
|
package/vitest.config.ts
ADDED
|
@@ -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
|
+
});
|