pi-minimal 0.2.2 → 0.3.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/CHANGELOG.md +47 -1
- package/README.md +24 -2
- package/dist/codemode-rows.js +109 -0
- package/dist/footer-activity-details.js +45 -0
- package/dist/footer-activity.js +36 -0
- package/dist/footer-contribution-events.js +35 -0
- package/dist/footer-contributions.js +130 -0
- package/dist/footer-plan.js +41 -0
- package/dist/footer.js +49 -7
- package/dist/index.js +24 -4
- package/dist/tools.js +139 -1
- package/doc/footer-contributions.md +132 -0
- package/package.json +1 -1
- package/release-notes.md +20 -20
- package/src/codemode-rows.ts +121 -0
- package/src/footer-activity-details.ts +43 -0
- package/src/footer-activity.ts +31 -0
- package/src/footer-contribution-events.ts +38 -0
- package/src/footer-contributions.ts +132 -0
- package/src/footer-plan.ts +44 -0
- package/src/footer.ts +43 -7
- package/src/index.ts +23 -4
- package/src/tools.ts +138 -1
- package/test/codemode-rows.test.ts +61 -0
- package/test/footer-activity.test.ts +93 -0
- package/test/footer-composition.test.ts +129 -0
- package/test/footer-contribution-events.test.ts +67 -0
- package/test/footer-contributions.test.ts +105 -0
- package/test/footer-plan.test.ts +53 -0
- package/test/index.test.ts +35 -2
- package/test/package.test.ts +5 -1
- package/test/theme.test.ts +28 -0
- package/test/tools.test.ts +72 -2
- package/themes/minimal-dark.json +7 -7
package/test/tools.test.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import assert from "node:assert/strict"
|
|
2
2
|
import test from "node:test"
|
|
3
3
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent"
|
|
4
|
-
import { compactRenderers, installToolRenderers, isToolKind } from "../src/tools.js"
|
|
4
|
+
import { codemodeRenderers, compactRenderers, installToolRenderers, isToolKind, stopLiveWatch } from "../src/tools.js"
|
|
5
5
|
|
|
6
6
|
test("isToolKind recognises the built-in tools only", () => {
|
|
7
7
|
for (const name of ["bash", "read", "edit", "write", "grep", "find", "ls"]) assert.equal(isToolKind(name), true)
|
|
@@ -19,7 +19,9 @@ test("installToolRenderers registers a resolver at load time that only claims bu
|
|
|
19
19
|
installToolRenderers(pi)
|
|
20
20
|
assert.ok(resolver, "resolver registered synchronously, before session_start")
|
|
21
21
|
const fallback = { renderShell: "default" }
|
|
22
|
-
assert.equal(resolver!("
|
|
22
|
+
assert.equal(resolver!("mcp__foo__bar", () => fallback), fallback)
|
|
23
|
+
const codemode = resolver!("codemode", () => fallback) as { renderShell?: string }
|
|
24
|
+
assert.equal(codemode.renderShell, "self")
|
|
23
25
|
const mine = resolver!("bash", () => fallback) as { renderShell?: string }
|
|
24
26
|
assert.equal(mine.renderShell, "self")
|
|
25
27
|
assert.equal(typeof (mine as { renderCall?: unknown }).renderCall, "function")
|
|
@@ -53,3 +55,71 @@ test("compactRenderers render a one-line row with the outcome once the result la
|
|
|
53
55
|
const [line] = row.render(60)
|
|
54
56
|
assert.match(line, /✓ bash\s+ls\s+2 lines · 1.2s$/)
|
|
55
57
|
})
|
|
58
|
+
|
|
59
|
+
function codemodeContext(extra: Record<string, unknown> = {}) {
|
|
60
|
+
return {
|
|
61
|
+
args: { code: "await tools.bash({command:'ls'})\ntext(1)" },
|
|
62
|
+
toolCallId: "c1",
|
|
63
|
+
invalidate() {},
|
|
64
|
+
state: {} as Record<string, unknown>,
|
|
65
|
+
isPartial: false,
|
|
66
|
+
isError: false,
|
|
67
|
+
durationMs: 1200,
|
|
68
|
+
...extra,
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const plainTheme = { fg: (_c: string, s: string) => s } as never
|
|
73
|
+
const codemodeResult = (calls: unknown[], output = "a\nb") => ({
|
|
74
|
+
content: [
|
|
75
|
+
{ type: "text", text: "Script completed\nWall time 1.2 seconds\nOutput:\n" },
|
|
76
|
+
{ type: "text", text: output },
|
|
77
|
+
],
|
|
78
|
+
details: { calls },
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
test("codemode renders one parent row plus one child row per nested call, no script", () => {
|
|
82
|
+
const r = codemodeRenderers()
|
|
83
|
+
const context = codemodeContext()
|
|
84
|
+
const calls = [
|
|
85
|
+
{ name: "plan_tracker", args: '{"action":"update","index":6,"status":"complete"}', status: "ok", durationMs: 309 },
|
|
86
|
+
{ name: "bash", args: '{"command":"cd ~/r && sed -n 1,2p a.md"}', status: "ok", durationMs: 636 },
|
|
87
|
+
]
|
|
88
|
+
const body = r.renderResult!(codemodeResult(calls) as never, { expanded: false, isPartial: false } as never, plainTheme, context as never)
|
|
89
|
+
const lines = r.renderCall!(context.args as never, plainTheme, context as never).render(100)
|
|
90
|
+
assert.equal(lines.length, 3)
|
|
91
|
+
assert.match(lines[0], /✓ code\s+2 calls · plan_tracker, bash\s+2 lines · 1.2s$/)
|
|
92
|
+
assert.match(lines[1], /✓ plan_tracker action=update index=6 status=complete\s+0.3s$/)
|
|
93
|
+
assert.match(lines[2], /✓ bash\s+cd ~\/r && sed -n 1,2p a.md\s+0.6s$/)
|
|
94
|
+
assert.ok(lines.every((line) => !line.includes("await")), "script hidden when collapsed")
|
|
95
|
+
assert.deepEqual(body.render(100), [])
|
|
96
|
+
for (const line of lines) assert.ok(line.length <= 100)
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
test("codemode shows the first failure under the row, and script + output when expanded", () => {
|
|
100
|
+
const r = codemodeRenderers()
|
|
101
|
+
const context = codemodeContext({ durationMs: 274_000 })
|
|
102
|
+
const calls = [{ name: "bash", args: '{"command":"npm test"}', status: "error", durationMs: 274_000, error: "fail 2" }]
|
|
103
|
+
const collapsed = r.renderResult!(codemodeResult(calls, "TEST_EXIT=1") as never, { expanded: false, isPartial: false } as never, plainTheme, context as never)
|
|
104
|
+
const [row, child] = r.renderCall!(context.args as never, plainTheme, context as never).render(100)
|
|
105
|
+
assert.match(row, /✗ code\s+1 call · bash\s+1 failed · 4m 34s$/)
|
|
106
|
+
assert.match(child, /✗ bash npm test\s+failed · 4m 34s$/)
|
|
107
|
+
assert.match(collapsed.render(100).join("\n"), /│ fail 2/)
|
|
108
|
+
|
|
109
|
+
const open = r.renderResult!(codemodeResult(calls, "TEST_EXIT=1") as never, { expanded: true, isPartial: false } as never, plainTheme, { ...context, expanded: true } as never)
|
|
110
|
+
const text = open.render(100).join("\n")
|
|
111
|
+
assert.match(text, /\/\/ script · 2 lines/)
|
|
112
|
+
assert.match(text, /await tools.bash/)
|
|
113
|
+
assert.match(text, /\/\/ output\n.*TEST_EXIT=1/)
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
test("codemode shows nested calls live while the script is still running", () => {
|
|
117
|
+
const r = codemodeRenderers()
|
|
118
|
+
const context = codemodeContext({ isPartial: true, durationMs: undefined })
|
|
119
|
+
r.renderResult!(codemodeResult([{ name: "bash", args: '{"command":"sleep 5"}', status: "running" }], "") as never, { expanded: false, isPartial: true } as never, plainTheme, context as never)
|
|
120
|
+
const lines = r.renderCall!(context.args as never, plainTheme, context as never).render(80)
|
|
121
|
+
assert.match(lines[0], /^\s+[◐◓] code\s+1 call · bash/)
|
|
122
|
+
assert.match(lines[1], /[◐◓] bash sleep 5/)
|
|
123
|
+
assert.equal((context.state as { done?: boolean }).done, undefined)
|
|
124
|
+
stopLiveWatch()
|
|
125
|
+
})
|
package/themes/minimal-dark.json
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
"panel": "okhsl(230 5% 17%)",
|
|
8
8
|
"text": "okhsl(234 3% 90%)",
|
|
9
9
|
"muted": "okhsl(229 6% 64%)",
|
|
10
|
-
"dim": "okhsl(229 7%
|
|
11
|
-
"faint": "okhsl(230 6%
|
|
10
|
+
"dim": "okhsl(229 7% 56%)",
|
|
11
|
+
"faint": "okhsl(230 6% 36%)",
|
|
12
12
|
"violet": "okhsl(295 50% 67%)",
|
|
13
13
|
"violetSoft": "okhsl(295 45% 74%)",
|
|
14
14
|
"blue": "okhsl(232 54% 67%)",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"muted": "muted",
|
|
30
30
|
"dim": "dim",
|
|
31
31
|
"text": "text",
|
|
32
|
-
"thinkingText": "okhsl(229 6%
|
|
32
|
+
"thinkingText": "okhsl(229 6% 58%)",
|
|
33
33
|
"selectedBg": "userBg",
|
|
34
34
|
"scrollbarTrack": "faint",
|
|
35
35
|
"scrollbarThumb": "dim",
|
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
"customMessageBg": "okhsl(295 30% 20%)",
|
|
41
41
|
"customMessageText": "muted",
|
|
42
42
|
"customMessageLabel": "violet",
|
|
43
|
-
"toolPendingBg": "
|
|
44
|
-
"toolSuccessBg": "
|
|
43
|
+
"toolPendingBg": "bg",
|
|
44
|
+
"toolSuccessBg": "bg",
|
|
45
45
|
"toolErrorBg": "errorBg",
|
|
46
46
|
"toolTitle": "text",
|
|
47
47
|
"toolOutput": "dim",
|
|
@@ -60,10 +60,10 @@
|
|
|
60
60
|
"toolDiffContext": "dim",
|
|
61
61
|
"syntaxComment": "dim",
|
|
62
62
|
"syntaxKeyword": "blue",
|
|
63
|
-
"syntaxFunction": "
|
|
63
|
+
"syntaxFunction": "okhsl(265 45% 76%)",
|
|
64
64
|
"syntaxVariable": "okhsl(202 58% 70%)",
|
|
65
65
|
"syntaxString": "okhsl(52 67% 70%)",
|
|
66
|
-
"syntaxNumber": "
|
|
66
|
+
"syntaxNumber": "okhsl(180 40% 68%)",
|
|
67
67
|
"syntaxType": "violet",
|
|
68
68
|
"syntaxOperator": "muted",
|
|
69
69
|
"syntaxPunctuation": "muted",
|