@selesai/code 0.10.1 → 0.11.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 +23 -0
- package/dist/config.d.ts +5 -3
- package/dist/config.js +6 -4
- package/dist/core/skills.d.ts +2 -0
- package/dist/core/skills.js +1 -0
- package/dist/defaults/settings.json +0 -3
- package/dist/extensions/auto-session-name.test.ts +157 -0
- package/dist/extensions/auto-session-name.ts +96 -0
- package/dist/extensions/cost-reconcile.test.ts +76 -0
- package/dist/extensions/cost-reconcile.ts +278 -0
- package/dist/extensions/enable-readonly-tools.test.ts +11 -0
- package/dist/extensions/enable-readonly-tools.ts +7 -3
- package/dist/extensions/package.json +3 -0
- package/dist/extensions/pi-tool-display/CHANGELOG.md +329 -0
- package/dist/extensions/pi-tool-display/LICENSE +21 -0
- package/dist/extensions/pi-tool-display/README.md +417 -0
- package/dist/extensions/pi-tool-display/config/config.example.json +40 -0
- package/dist/extensions/pi-tool-display/index.ts +3 -0
- package/dist/extensions/pi-tool-display/package-lock.json +2555 -0
- package/dist/extensions/pi-tool-display/package.json +86 -0
- package/dist/extensions/pi-tool-display/src/agent-dir.ts +35 -0
- package/dist/extensions/pi-tool-display/src/ansi-utils.ts +116 -0
- package/dist/extensions/pi-tool-display/src/bash-display.ts +213 -0
- package/dist/extensions/pi-tool-display/src/capabilities.ts +88 -0
- package/dist/extensions/pi-tool-display/src/config-modal.ts +541 -0
- package/dist/extensions/pi-tool-display/src/config-store.ts +304 -0
- package/dist/extensions/pi-tool-display/src/debug-logger.ts +150 -0
- package/dist/extensions/pi-tool-display/src/diff-presentation.ts +72 -0
- package/dist/extensions/pi-tool-display/src/diff-renderer.ts +2517 -0
- package/dist/extensions/pi-tool-display/src/disposable.ts +34 -0
- package/dist/extensions/pi-tool-display/src/extension-lifecycle.ts +14 -0
- package/dist/extensions/pi-tool-display/src/index.ts +109 -0
- package/dist/extensions/pi-tool-display/src/line-width-safety.ts +93 -0
- package/dist/extensions/pi-tool-display/src/modal-icons.ts +57 -0
- package/dist/extensions/pi-tool-display/src/pending-diff-preview.ts +370 -0
- package/dist/extensions/pi-tool-display/src/presets.ts +117 -0
- package/dist/extensions/pi-tool-display/src/render-utils.ts +186 -0
- package/dist/extensions/pi-tool-display/src/settings-inspector-modal.ts +475 -0
- package/dist/extensions/pi-tool-display/src/thinking-label.ts +343 -0
- package/dist/extensions/pi-tool-display/src/tool-call-box.ts +181 -0
- package/dist/extensions/pi-tool-display/src/tool-metadata.ts +139 -0
- package/dist/extensions/pi-tool-display/src/tool-overrides.ts +2168 -0
- package/dist/extensions/pi-tool-display/src/types.ts +109 -0
- package/dist/extensions/pi-tool-display/src/user-message-box-markdown.ts +64 -0
- package/dist/extensions/pi-tool-display/src/user-message-box-native.ts +66 -0
- package/dist/extensions/pi-tool-display/src/user-message-box-patch.ts +72 -0
- package/dist/extensions/pi-tool-display/src/user-message-box-renderer.ts +419 -0
- package/dist/extensions/pi-tool-display/src/user-message-box-utils.ts +106 -0
- package/dist/extensions/pi-tool-display/src/write-display-utils.ts +31 -0
- package/dist/extensions/pi-tool-display/src/zellij-modal.ts +1027 -0
- package/dist/extensions/pi-tool-display/tests/active-backlog-red.test.ts +65 -0
- package/dist/extensions/pi-tool-display/tests/ansi-utils.test.ts +345 -0
- package/dist/extensions/pi-tool-display/tests/bash-display.test.ts +442 -0
- package/dist/extensions/pi-tool-display/tests/capabilities-edge.test.ts +360 -0
- package/dist/extensions/pi-tool-display/tests/capabilities.test.ts +54 -0
- package/dist/extensions/pi-tool-display/tests/config-modal.test.ts +360 -0
- package/dist/extensions/pi-tool-display/tests/config-store.test.ts +87 -0
- package/dist/extensions/pi-tool-display/tests/custom-tool-overrides.test.ts +415 -0
- package/dist/extensions/pi-tool-display/tests/debug-logger-edge.test.ts +630 -0
- package/dist/extensions/pi-tool-display/tests/debug-logger.test.ts +62 -0
- package/dist/extensions/pi-tool-display/tests/diff-renderer-ansi.test.ts +55 -0
- package/dist/extensions/pi-tool-display/tests/diff-renderer-edge.test.ts +886 -0
- package/dist/extensions/pi-tool-display/tests/diff-renderer-numbering.test.ts +135 -0
- package/dist/extensions/pi-tool-display/tests/diff-renderer-width.test.ts +454 -0
- package/dist/extensions/pi-tool-display/tests/diff-renderer-wrap.test.ts +169 -0
- package/dist/extensions/pi-tool-display/tests/index-integration.test.ts +354 -0
- package/dist/extensions/pi-tool-display/tests/pending-diff-preview.test.ts +79 -0
- package/dist/extensions/pi-tool-display/tests/presets-edge.test.ts +229 -0
- package/dist/extensions/pi-tool-display/tests/presets.test.ts +26 -0
- package/dist/extensions/pi-tool-display/tests/reload-behavior.test.ts +1241 -0
- package/dist/extensions/pi-tool-display/tests/render-utils.test.ts +710 -0
- package/dist/extensions/pi-tool-display/tests/settings-inspector.test.ts +450 -0
- package/dist/extensions/pi-tool-display/tests/thinking-label-edge.test.ts +904 -0
- package/dist/extensions/pi-tool-display/tests/thinking-label.test.ts +72 -0
- package/dist/extensions/pi-tool-display/tests/tool-call-box.test.ts +105 -0
- package/dist/extensions/pi-tool-display/tests/tool-overrides-config.test.ts +613 -0
- package/dist/extensions/pi-tool-display/tests/tool-overrides-mcp.test.ts +499 -0
- package/dist/extensions/pi-tool-display/tests/tool-overrides-registration.test.ts +315 -0
- package/dist/extensions/pi-tool-display/tests/tool-overrides-write-meta.test.ts +68 -0
- package/dist/extensions/pi-tool-display/tests/tool-ui-utils.test.ts +413 -0
- package/dist/extensions/pi-tool-display/tests/user-message-box-performance-red.test.ts +176 -0
- package/dist/extensions/pi-tool-display/tests/user-message-box.test.ts +908 -0
- package/dist/extensions/pi-tool-display/tests/zellij-modal.test.ts +848 -0
- package/dist/extensions/pi-tool-display/tool-display-api-consumer.d.ts +30 -0
- package/dist/extensions/pi-tool-display/tool-display-api-consumer.js +40 -0
- package/dist/extensions/pi-zentui/extensions/zentui/format.ts +46 -1
- package/dist/extensions/pi-zentui/extensions/zentui/index.ts +10 -0
- package/dist/extensions/pi-zentui/extensions/zentui/user-message-styles.ts +1 -1
- package/dist/extensions/pi-zentui/test/extension-compliance.test.ts +3 -3
- package/dist/extensions/pi-zentui/test/format.test.ts +50 -2
- package/dist/modes/interactive/components/startup-box.d.ts +38 -0
- package/dist/modes/interactive/components/startup-box.js +90 -0
- package/dist/modes/interactive/interactive-mode.d.ts +3 -0
- package/dist/modes/interactive/interactive-mode.js +85 -122
- package/dist/skills/agent-browser/SKILL.md +1 -0
- package/dist/skills/batch-grill-me/SKILL.md +1 -0
- package/dist/skills/brandkit/SKILL.md +1 -0
- package/dist/skills/design-references/SKILL.md +1 -0
- package/dist/skills/design-taste-frontend/SKILL.md +1 -0
- package/dist/skills/design-taste-frontend-v1/SKILL.md +1 -0
- package/dist/skills/full-output-enforcement/SKILL.md +1 -0
- package/dist/skills/gpt-taste/SKILL.md +1 -0
- package/dist/skills/grill-me/SKILL.md +1 -0
- package/dist/skills/handoff/SKILL.md +1 -0
- package/dist/skills/handoff-text/SKILL.md +1 -0
- package/dist/skills/high-end-visual-design/SKILL.md +1 -0
- package/dist/skills/image-to-code/SKILL.md +1 -0
- package/dist/skills/imagegen-frontend-mobile/SKILL.md +1 -0
- package/dist/skills/imagegen-frontend-web/SKILL.md +1 -0
- package/dist/skills/implanger/SKILL.md +1 -0
- package/dist/skills/improve-codebase/SKILL.md +1 -0
- package/dist/skills/industrial-brutalist-ui/SKILL.md +1 -0
- package/dist/skills/minimalist-ui/SKILL.md +1 -0
- package/dist/skills/pi-subagents/SKILL.md +1 -0
- package/dist/skills/planger/SKILL.md +1 -0
- package/dist/skills/ponytail/SKILL.md +1 -0
- package/dist/skills/ponytail-audit/SKILL.md +1 -0
- package/dist/skills/ponytail-debt/SKILL.md +1 -0
- package/dist/skills/ponytail-gain/SKILL.md +1 -0
- package/dist/skills/ponytail-help/SKILL.md +1 -0
- package/dist/skills/ponytail-review/SKILL.md +1 -0
- package/dist/skills/redesign-existing-projects/SKILL.md +1 -0
- package/dist/skills/selesai-handoff/SKILL.md +1 -0
- package/dist/skills/stitch-design-taste/SKILL.md +1 -0
- package/dist/skills/unlazy/SKILL.md +1 -0
- package/dist/skills/web-design-guidelines/SKILL.md +1 -0
- package/dist/skills/workflow/SKILL.md +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import test from "node:test";
|
|
3
|
+
import { registerThinkingLabeling } from "../src/thinking-label.ts";
|
|
4
|
+
|
|
5
|
+
type CapturedHandler = (event: unknown, ctx?: unknown) => Promise<void> | void;
|
|
6
|
+
|
|
7
|
+
function captureThinkingHandlers(): Map<string, CapturedHandler> {
|
|
8
|
+
const handlers = new Map<string, CapturedHandler>();
|
|
9
|
+
registerThinkingLabeling({
|
|
10
|
+
on(eventName: string, handler: CapturedHandler): void {
|
|
11
|
+
handlers.set(eventName, handler);
|
|
12
|
+
},
|
|
13
|
+
} as never);
|
|
14
|
+
return handlers;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
test("thinking label formatting prefixes supported provider thinking blocks for display", async () => {
|
|
18
|
+
const handlers = captureThinkingHandlers();
|
|
19
|
+
const event = {
|
|
20
|
+
message: {
|
|
21
|
+
role: "assistant",
|
|
22
|
+
api: "anthropic-messages",
|
|
23
|
+
content: [{ type: "thinking", thinking: "checking options" }],
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
await handlers.get("message_update")?.(event, {
|
|
28
|
+
ui: { theme: { fg: (color: string, text: string) => `[${color}]${text}` } },
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
assert.deepEqual(event.message.content, [
|
|
32
|
+
{ type: "thinking", thinking: "[accent]Thinking: [thinkingText]checking options" },
|
|
33
|
+
]);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test("thinking label formatting leaves unsupported explicit OpenAI APIs unchanged", async () => {
|
|
37
|
+
const handlers = captureThinkingHandlers();
|
|
38
|
+
const thinkingBlock = { type: "thinking", thinking: "raw reasoning" };
|
|
39
|
+
const event = {
|
|
40
|
+
message: {
|
|
41
|
+
role: "assistant",
|
|
42
|
+
api: "openai-chat",
|
|
43
|
+
content: [thinkingBlock],
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
await handlers.get("message_end")?.(event, {});
|
|
48
|
+
|
|
49
|
+
assert.equal(event.message.content[0], thinkingBlock);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test("thinking context sanitization removes presentation labels before model context", async () => {
|
|
53
|
+
const handlers = captureThinkingHandlers();
|
|
54
|
+
const event = {
|
|
55
|
+
messages: [
|
|
56
|
+
{
|
|
57
|
+
role: "assistant",
|
|
58
|
+
content: [
|
|
59
|
+
{ type: "thinking", thinking: "\u001b[31mThinking: \u001b[0mThinking: final answer path" },
|
|
60
|
+
],
|
|
61
|
+
},
|
|
62
|
+
{ role: "user", content: "keep me" },
|
|
63
|
+
],
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
await handlers.get("context")?.(event, {});
|
|
67
|
+
|
|
68
|
+
assert.deepEqual(event.messages[0]?.content, [
|
|
69
|
+
{ type: "thinking", thinking: "final answer path" },
|
|
70
|
+
]);
|
|
71
|
+
assert.deepEqual(event.messages[1], { role: "user", content: "keep me" });
|
|
72
|
+
});
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import test from "node:test";
|
|
3
|
+
import { Text } from "@earendil-works/pi-tui";
|
|
4
|
+
import { boxToolCall, boxToolResult } from "../src/tool-call-box.ts";
|
|
5
|
+
|
|
6
|
+
interface BoxThemeLike {
|
|
7
|
+
fg(color: string, text: string): string;
|
|
8
|
+
bold(text: string): string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const passThroughTheme: BoxThemeLike = {
|
|
12
|
+
fg: (_color: string, text: string): string => text,
|
|
13
|
+
bold: (text: string): string => text,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
function render(component: unknown, width = 60): string[] {
|
|
17
|
+
return (component as { render(totalWidth: number): string[] }).render(width);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
test("boxed call renders the startup-style ASCII top frame around the call", () => {
|
|
21
|
+
const call = boxToolCall(new Text("$ ls", 0, 0), passThroughTheme, true);
|
|
22
|
+
const lines = render(call);
|
|
23
|
+
|
|
24
|
+
assert.match(lines[0] ?? "", /╭─ Tools ─/);
|
|
25
|
+
assert.ok(lines.some((line) => line.includes("$ ls")), "call content should be inside the box");
|
|
26
|
+
assert.match(lines.at(-1) ?? "", /│/, "call row should have side borders");
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test("boxed result renders the bottom frame around the output", () => {
|
|
30
|
+
const result = boxToolResult(new Text("a.txt", 0, 0), passThroughTheme, true);
|
|
31
|
+
const lines = render(result);
|
|
32
|
+
|
|
33
|
+
assert.match(lines.at(-1) ?? "", /╰─+╯/);
|
|
34
|
+
assert.ok(lines.some((line) => line.includes("a.txt")), "result content should be inside the box");
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test("stacked call and result form one contiguous ASCII box", () => {
|
|
38
|
+
const call = boxToolCall(new Text("$ ls", 0, 0), passThroughTheme, true);
|
|
39
|
+
const result = boxToolResult(new Text("a.txt\nb.txt", 0, 0), passThroughTheme, true);
|
|
40
|
+
|
|
41
|
+
// Under renderShell "self" the host stacks the call half then the result
|
|
42
|
+
// half (with a leading spacer), so concatenating their lines is exactly
|
|
43
|
+
// what the TUI shows: one contiguous box.
|
|
44
|
+
const lines = [...render(call), ...render(result)];
|
|
45
|
+
|
|
46
|
+
const tops = lines.filter((line) => /╭/.test(line));
|
|
47
|
+
const bottoms = lines.filter((line) => /╰/.test(line));
|
|
48
|
+
assert.equal(tops.length, 1, "exactly one top border across the pair");
|
|
49
|
+
assert.equal(bottoms.length, 1, "exactly one bottom border across the pair");
|
|
50
|
+
assert.match(lines[0] ?? "", /╭─ Tools ─/);
|
|
51
|
+
assert.match(lines.at(-1) ?? "", /╰─+╯/);
|
|
52
|
+
assert.ok(lines.some((line) => line.includes("$ ls")), "call row present");
|
|
53
|
+
assert.ok(lines.some((line) => line.includes("a.txt")), "first result row present");
|
|
54
|
+
assert.ok(lines.some((line) => line.includes("b.txt")), "second result row present");
|
|
55
|
+
const borderedRows = lines.filter((line) => /[╭╰│]/.test(line));
|
|
56
|
+
assert.ok(borderedRows.length >= 5, "top, two content rows, result row, bottom");
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test("disabled box passthrough keeps the original component", () => {
|
|
60
|
+
const call = new Text("$ ls", 0, 0);
|
|
61
|
+
const result = new Text("a.txt", 0, 0);
|
|
62
|
+
assert.equal(boxToolCall(call, passThroughTheme, false), call);
|
|
63
|
+
assert.equal(boxToolResult(result, passThroughTheme, false), result);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
test("narrow widths fall back to raw rendering instead of overflowing", () => {
|
|
67
|
+
const call = boxToolCall(new Text("$ ls", 0, 0), passThroughTheme, true);
|
|
68
|
+
const lines = render(call, 4);
|
|
69
|
+
assert.equal(lines.join("\n"), "$ ls");
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test("long content is width-safe and does not exceed the border width", () => {
|
|
73
|
+
const long = new Text("a".repeat(200), 0, 0);
|
|
74
|
+
const call = boxToolCall(long, passThroughTheme, true);
|
|
75
|
+
const lines = render(call, 40);
|
|
76
|
+
for (const line of lines) {
|
|
77
|
+
if (/[╭╰│]/.test(line)) {
|
|
78
|
+
assert.ok(line.length <= 41, `border line too long: ${line.length}`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test("framed lines are cached by width and reused across renders", () => {
|
|
84
|
+
const call = boxToolCall(new Text("$ ls", 0, 0), passThroughTheme, true);
|
|
85
|
+
const first = render(call);
|
|
86
|
+
const second = render(call);
|
|
87
|
+
assert.equal(second, first, "unchanged render should reuse the cached array");
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
test("invalidate clears the frame cache", () => {
|
|
91
|
+
const call = boxToolCall(new Text("$ ls", 0, 0), passThroughTheme, true);
|
|
92
|
+
const first = render(call);
|
|
93
|
+
call.invalidate?.();
|
|
94
|
+
const second = render(call);
|
|
95
|
+
assert.notEqual(second, first, "invalidate should force a rebuild");
|
|
96
|
+
assert.deepEqual(second, first, "content is unchanged, so lines must be identical");
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
test("width change re-renders the frame", () => {
|
|
100
|
+
const call = boxToolCall(new Text("$ ls", 0, 0), passThroughTheme, true);
|
|
101
|
+
const narrow = render(call, 30);
|
|
102
|
+
const wide = render(call, 60);
|
|
103
|
+
assert.notEqual(wide, narrow, "different width must rebuild the frame");
|
|
104
|
+
assert.ok(wide[0]?.includes("─"), "wide frame should still be boxed");
|
|
105
|
+
});
|