@xynogen/pix-todo 0.3.0 → 0.3.2
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/package.json +2 -2
- package/src/todo.test.ts +8 -5
- package/src/todo.ts +7 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xynogen/pix-todo",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Pi tool — durable execution checklist (todo)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.ts",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"access": "public"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@xynogen/pix-pretty": "^1.
|
|
37
|
+
"@xynogen/pix-pretty": "^1.19.0",
|
|
38
38
|
"@xynogen/pix-runtime": "^0.8.0",
|
|
39
39
|
"typebox": "^1.1.38"
|
|
40
40
|
},
|
package/src/todo.test.ts
CHANGED
|
@@ -886,6 +886,7 @@ describe("todo card layout", () => {
|
|
|
886
886
|
expect(rendered).toContain("alpha");
|
|
887
887
|
expect(rendered).toContain("[text]○ alpha"); // pending card, no id number
|
|
888
888
|
expect(rendered).not.toContain("[success]✓ [/] [toolTitle]<b>todo</b>[/]");
|
|
889
|
+
expect(rendered.split("\n")[0]).toBe(`[success]${"─".repeat(80)}[/]`);
|
|
889
890
|
});
|
|
890
891
|
|
|
891
892
|
test("opening a new todo card collapses the previously open one", async () => {
|
|
@@ -931,7 +932,8 @@ describe("todo card layout", () => {
|
|
|
931
932
|
.join("\n")
|
|
932
933
|
.trimEnd();
|
|
933
934
|
|
|
934
|
-
expect(rendered).toBe("
|
|
935
|
+
expect(rendered.split("\n")[0]).toBe(`[error]${"─".repeat(80)}[/]`);
|
|
936
|
+
expect(rendered).toContain("No todo with id 99.");
|
|
935
937
|
});
|
|
936
938
|
|
|
937
939
|
test("a collapsed result is exactly one shared-style line", async () => {
|
|
@@ -954,8 +956,9 @@ describe("todo card layout", () => {
|
|
|
954
956
|
|
|
955
957
|
expect(result.details).toBeDefined();
|
|
956
958
|
expect(lines).toHaveLength(1);
|
|
959
|
+
expect(lines[0]).not.toContain("────");
|
|
957
960
|
expect(lines[0]?.trimEnd()).toBe(
|
|
958
|
-
"[success]✓ [/] [toolTitle]<b>todo</b>[/] [
|
|
961
|
+
"[success]✓ [/] [toolTitle]<b>todo</b>[/] [dim]#2 todo renderer[/] [muted]·[/] [muted]1/2 done[/]",
|
|
959
962
|
);
|
|
960
963
|
});
|
|
961
964
|
});
|
|
@@ -986,14 +989,14 @@ describe("renderResult snapshot isolation", () => {
|
|
|
986
989
|
describe("renderTodoSummaryLine (collapsed one-liner)", () => {
|
|
987
990
|
test("empty list renders a compact tool row", () => {
|
|
988
991
|
expect(renderTodoSummaryLine([], tagTheme)).toBe(
|
|
989
|
-
"[success]✓ [/] [toolTitle]<b>todo</b>[/] [
|
|
992
|
+
"[success]✓ [/] [toolTitle]<b>todo</b>[/] [dim]empty[/]",
|
|
990
993
|
);
|
|
991
994
|
});
|
|
992
995
|
|
|
993
996
|
test("uses warning status when work is blocked", () => {
|
|
994
997
|
const items: TodoItem[] = [{ id: 1, text: "Need approval", status: "blocked" }];
|
|
995
998
|
expect(renderTodoSummaryLine(items, tagTheme)).toBe(
|
|
996
|
-
"[warning]⚠ [/] [toolTitle]<b>todo</b>[/] [
|
|
999
|
+
"[warning]⚠ [/] [toolTitle]<b>todo</b>[/] [dim]checklist[/] [muted]·[/] [muted]0/1 done · 1 blocked[/]",
|
|
997
1000
|
);
|
|
998
1001
|
});
|
|
999
1002
|
|
|
@@ -1003,7 +1006,7 @@ describe("renderTodoSummaryLine (collapsed one-liner)", () => {
|
|
|
1003
1006
|
{ id: 2, text: "b", status: "in_progress" },
|
|
1004
1007
|
];
|
|
1005
1008
|
expect(renderTodoSummaryLine(items, tagTheme)).toBe(
|
|
1006
|
-
"[success]✓ [/] [toolTitle]<b>todo</b>[/] [
|
|
1009
|
+
"[success]✓ [/] [toolTitle]<b>todo</b>[/] [dim]#2 b[/] [muted]·[/] [muted]1/2 done[/]",
|
|
1007
1010
|
);
|
|
1008
1011
|
});
|
|
1009
1012
|
});
|
package/src/todo.ts
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
13
13
|
import { Text } from "@earendil-works/pi-tui";
|
|
14
14
|
import { icon } from "@xynogen/pix-pretty/icon-catalog";
|
|
15
|
-
import { dotJoin, formatCollapsedToolRow, termW } from "@xynogen/pix-pretty/utils";
|
|
15
|
+
import { dotJoin, formatCollapsedToolRow, frameToolResult, termW } from "@xynogen/pix-pretty/utils";
|
|
16
16
|
import { type CollapseState, tickCollapse } from "@xynogen/pix-runtime/collapse";
|
|
17
17
|
import { once } from "@xynogen/pix-runtime/once";
|
|
18
18
|
import { Type } from "typebox";
|
|
@@ -271,7 +271,7 @@ export default function registerTodo(pi: ExtensionAPI): void {
|
|
|
271
271
|
const t = theme as TodoTheme;
|
|
272
272
|
const action = (args as { action?: string })?.action ?? "";
|
|
273
273
|
const title = t.fg("toolTitle", t.bold("todo"));
|
|
274
|
-
return new Text(action ? `${title} ${t.fg("
|
|
274
|
+
return new Text(action ? `${title} ${t.fg("dim", action)}` : title, 0, 0);
|
|
275
275
|
},
|
|
276
276
|
renderResult(result, options, theme, context) {
|
|
277
277
|
const details = result.details as TodoResultDetails | undefined;
|
|
@@ -279,8 +279,10 @@ export default function registerTodo(pi: ExtensionAPI): void {
|
|
|
279
279
|
.filter((part) => part.type === "text")
|
|
280
280
|
.map((part) => part.text)
|
|
281
281
|
.join("\n");
|
|
282
|
+
const isPartial = options.isPartial === true;
|
|
282
283
|
if (context.isError || details?.outcome === "error" || !details) {
|
|
283
|
-
|
|
284
|
+
const component = new Text(resultText, 0, 0);
|
|
285
|
+
return isPartial ? component : frameToolResult(component, theme, true);
|
|
284
286
|
}
|
|
285
287
|
|
|
286
288
|
const collapsed = tickCollapse(
|
|
@@ -292,7 +294,8 @@ export default function registerTodo(pi: ExtensionAPI): void {
|
|
|
292
294
|
// An open card claims focus, collapsing any earlier open board.
|
|
293
295
|
if (!collapsed) focusCard(context.state as CollapseState, context.invalidate);
|
|
294
296
|
const render = collapsed ? renderTodoSummaryLine : renderTodoLines;
|
|
295
|
-
|
|
297
|
+
const component = new Text(render(details.snapshot, theme as TodoTheme), 0, 0);
|
|
298
|
+
return collapsed || isPartial ? component : frameToolResult(component, theme, false);
|
|
296
299
|
},
|
|
297
300
|
|
|
298
301
|
async execute(_id, params) {
|