@gamflaz/opencode-todolist 1.0.12 → 1.1.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/dist/icons/glyph.d.ts +77 -0
- package/dist/icons/glyph.js +103 -0
- package/dist/icons/glyphs.d.ts +51 -0
- package/dist/icons/glyphs.js +56 -0
- package/dist/index.d.ts +21 -2
- package/dist/index.js +41 -3
- package/dist/schemas/todo.d.ts +76 -58
- package/dist/schemas/todo.js +73 -18
- package/dist/storage/db.d.ts +71 -0
- package/dist/storage/db.js +59 -0
- package/dist/storage/migrate-json.d.ts +82 -0
- package/dist/storage/migrate-json.js +278 -0
- package/dist/storage/schema.d.ts +775 -0
- package/dist/storage/schema.js +108 -0
- package/dist/storage/todo-store.d.ts +104 -56
- package/dist/storage/todo-store.js +178 -297
- package/dist/todos/hint.d.ts +13 -2
- package/dist/todos/hint.js +16 -19
- package/dist/todos/todo-tree.d.ts +16 -3
- package/dist/todos/todo-tree.js +22 -4
- package/dist/todos/update.js +2 -2
- package/dist/tui/todo-panel.js +73 -65
- package/drizzle/20261014050406_eminent_zaran/migration.sql +49 -0
- package/drizzle/20261014050406_eminent_zaran/snapshot.json +470 -0
- package/package.json +7 -5
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { type ColorInput } from "@opentui/core";
|
|
2
|
+
/** Cell size accepted by the layout engine. */
|
|
3
|
+
export type GlyphSize = number | "auto" | `${number}%`;
|
|
4
|
+
export type GlyphProps = {
|
|
5
|
+
/**
|
|
6
|
+
* The glyph to draw. Pass a function to keep it reactive (the arrow depends
|
|
7
|
+
* on `isCollapsed()`), or a plain string for a fixed symbol.
|
|
8
|
+
*/
|
|
9
|
+
glyph: (() => string) | string;
|
|
10
|
+
color?: ColorInput;
|
|
11
|
+
/** Shortcut: stretch to `100%` on both axes (fill the parent). */
|
|
12
|
+
fill?: boolean;
|
|
13
|
+
/** Shorthand that sets both `width` and `height`. */
|
|
14
|
+
size?: GlyphSize;
|
|
15
|
+
/** Horizontal cells; overrides `fill` and `size`. Defaults to `"auto"`. */
|
|
16
|
+
width?: GlyphSize;
|
|
17
|
+
/** Vertical cells; overrides `fill` and `size`. Defaults to `"auto"`. */
|
|
18
|
+
height?: GlyphSize;
|
|
19
|
+
};
|
|
20
|
+
export type GlyphBox = {
|
|
21
|
+
readonly width: GlyphSize;
|
|
22
|
+
readonly height: GlyphSize;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Resolves the box for a glyph.
|
|
26
|
+
*
|
|
27
|
+
* Precedence per axis: `width`/`height` > `fill` (100%) > `size` > `"auto"`.
|
|
28
|
+
*
|
|
29
|
+
* The default is `"auto"`, so the zero-configuration case fills exactly what
|
|
30
|
+
* the glyph needs. `fill` switches both axes to `100%` in one word, which is
|
|
31
|
+
* the simple "just stretch to whatever space there is" form.
|
|
32
|
+
*
|
|
33
|
+
* Kept pure so the rules are testable without a live renderer.
|
|
34
|
+
*/
|
|
35
|
+
export declare function ResolveGlyphBox(props: {
|
|
36
|
+
fill?: boolean;
|
|
37
|
+
size?: GlyphSize;
|
|
38
|
+
width?: GlyphSize;
|
|
39
|
+
height?: GlyphSize;
|
|
40
|
+
}): GlyphBox;
|
|
41
|
+
/**
|
|
42
|
+
* A colored terminal glyph in a single text node.
|
|
43
|
+
*
|
|
44
|
+
* Matches OpenCode's own MCP sidebar, which renders
|
|
45
|
+
* `<text fg={...}>{open ? "▼" : "▶"}</text>`
|
|
46
|
+
* (packages/tui/src/feature-plugins/sidebar/mcp.tsx). A `fg` attribute on
|
|
47
|
+
* `<text>` is reactive: TextBufferRenderable's fg setter calls requestRender().
|
|
48
|
+
*
|
|
49
|
+
* `glyph` accepts either an accessor or a plain string. Solid hands components
|
|
50
|
+
* getters, so an accessor stays live while a string is simply constant.
|
|
51
|
+
*
|
|
52
|
+
* Sizing: `width` and `height` default to `"auto"`. `fill` stretches both axes
|
|
53
|
+
* to `100%` in one word, `size` sets a square box, and explicit `width`/`height`
|
|
54
|
+
* win over both.
|
|
55
|
+
*
|
|
56
|
+
* A terminal cannot scale a character — a glyph always paints in one cell, so
|
|
57
|
+
* `size`/`fill` reserve layout space rather than enlarging the symbol. To make a
|
|
58
|
+
* control read as larger, give it a bigger box (or use the SVG icon path where
|
|
59
|
+
* the terminal supports images).
|
|
60
|
+
*/
|
|
61
|
+
export declare function Glyph(props: GlyphProps): import("solid-js").JSX.Element;
|
|
62
|
+
/**
|
|
63
|
+
* The zero-configuration variant: only a glyph and an optional colour, with
|
|
64
|
+
* auto width and height. Use this unless a specific box is required.
|
|
65
|
+
*/
|
|
66
|
+
export declare function GlyphAuto(props: {
|
|
67
|
+
glyph: (() => string) | string;
|
|
68
|
+
color?: ColorInput;
|
|
69
|
+
}): import("solid-js").JSX.Element;
|
|
70
|
+
/**
|
|
71
|
+
* The stretch variant: fills `100%` of the parent on both axes, so the size
|
|
72
|
+
* follows the surrounding layout without hand-tuned numbers.
|
|
73
|
+
*/
|
|
74
|
+
export declare function GlyphFill(props: {
|
|
75
|
+
glyph: (() => string) | string;
|
|
76
|
+
color?: ColorInput;
|
|
77
|
+
}): import("solid-js").JSX.Element;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { createComponent as _$createComponent } from "@opentui/solid";
|
|
2
|
+
import { effect as _$effect } from "@opentui/solid";
|
|
3
|
+
import { insert as _$insert } from "@opentui/solid";
|
|
4
|
+
import { setProp as _$setProp } from "@opentui/solid";
|
|
5
|
+
import { createElement as _$createElement } from "@opentui/solid";
|
|
6
|
+
/** Cell size accepted by the layout engine. */
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Resolves the box for a glyph.
|
|
10
|
+
*
|
|
11
|
+
* Precedence per axis: `width`/`height` > `fill` (100%) > `size` > `"auto"`.
|
|
12
|
+
*
|
|
13
|
+
* The default is `"auto"`, so the zero-configuration case fills exactly what
|
|
14
|
+
* the glyph needs. `fill` switches both axes to `100%` in one word, which is
|
|
15
|
+
* the simple "just stretch to whatever space there is" form.
|
|
16
|
+
*
|
|
17
|
+
* Kept pure so the rules are testable without a live renderer.
|
|
18
|
+
*/
|
|
19
|
+
export function ResolveGlyphBox(props) {
|
|
20
|
+
const fillSize = "100%";
|
|
21
|
+
return {
|
|
22
|
+
width: props.width ?? (props.fill ? fillSize : undefined) ?? props.size ?? "auto",
|
|
23
|
+
height: props.height ?? (props.fill ? fillSize : undefined) ?? props.size ?? "auto"
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* A colored terminal glyph in a single text node.
|
|
29
|
+
*
|
|
30
|
+
* Matches OpenCode's own MCP sidebar, which renders
|
|
31
|
+
* `<text fg={...}>{open ? "▼" : "▶"}</text>`
|
|
32
|
+
* (packages/tui/src/feature-plugins/sidebar/mcp.tsx). A `fg` attribute on
|
|
33
|
+
* `<text>` is reactive: TextBufferRenderable's fg setter calls requestRender().
|
|
34
|
+
*
|
|
35
|
+
* `glyph` accepts either an accessor or a plain string. Solid hands components
|
|
36
|
+
* getters, so an accessor stays live while a string is simply constant.
|
|
37
|
+
*
|
|
38
|
+
* Sizing: `width` and `height` default to `"auto"`. `fill` stretches both axes
|
|
39
|
+
* to `100%` in one word, `size` sets a square box, and explicit `width`/`height`
|
|
40
|
+
* win over both.
|
|
41
|
+
*
|
|
42
|
+
* A terminal cannot scale a character — a glyph always paints in one cell, so
|
|
43
|
+
* `size`/`fill` reserve layout space rather than enlarging the symbol. To make a
|
|
44
|
+
* control read as larger, give it a bigger box (or use the SVG icon path where
|
|
45
|
+
* the terminal supports images).
|
|
46
|
+
*/
|
|
47
|
+
export function Glyph(props) {
|
|
48
|
+
const text = () => {
|
|
49
|
+
const glyph = props.glyph;
|
|
50
|
+
return typeof glyph === "function" ? glyph() : glyph;
|
|
51
|
+
};
|
|
52
|
+
const box = () => ResolveGlyphBox(props);
|
|
53
|
+
return (() => {
|
|
54
|
+
var _el$ = _$createElement("text");
|
|
55
|
+
_$setProp(_el$, "wrapMode", "none");
|
|
56
|
+
_$insert(_el$, text);
|
|
57
|
+
_$effect(_p$ => {
|
|
58
|
+
var _v$ = props.color,
|
|
59
|
+
_v$2 = box().width,
|
|
60
|
+
_v$3 = box().height;
|
|
61
|
+
_v$ !== _p$.e && (_p$.e = _$setProp(_el$, "fg", _v$, _p$.e));
|
|
62
|
+
_v$2 !== _p$.t && (_p$.t = _$setProp(_el$, "width", _v$2, _p$.t));
|
|
63
|
+
_v$3 !== _p$.a && (_p$.a = _$setProp(_el$, "height", _v$3, _p$.a));
|
|
64
|
+
return _p$;
|
|
65
|
+
}, {
|
|
66
|
+
e: undefined,
|
|
67
|
+
t: undefined,
|
|
68
|
+
a: undefined
|
|
69
|
+
});
|
|
70
|
+
return _el$;
|
|
71
|
+
})();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* The zero-configuration variant: only a glyph and an optional colour, with
|
|
76
|
+
* auto width and height. Use this unless a specific box is required.
|
|
77
|
+
*/
|
|
78
|
+
export function GlyphAuto(props) {
|
|
79
|
+
return _$createComponent(Glyph, {
|
|
80
|
+
get glyph() {
|
|
81
|
+
return props.glyph;
|
|
82
|
+
},
|
|
83
|
+
get color() {
|
|
84
|
+
return props.color;
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* The stretch variant: fills `100%` of the parent on both axes, so the size
|
|
91
|
+
* follows the surrounding layout without hand-tuned numbers.
|
|
92
|
+
*/
|
|
93
|
+
export function GlyphFill(props) {
|
|
94
|
+
return _$createComponent(Glyph, {
|
|
95
|
+
get glyph() {
|
|
96
|
+
return props.glyph;
|
|
97
|
+
},
|
|
98
|
+
get color() {
|
|
99
|
+
return props.color;
|
|
100
|
+
},
|
|
101
|
+
fill: true
|
|
102
|
+
});
|
|
103
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal glyphs for the TUI widget.
|
|
3
|
+
*
|
|
4
|
+
* These are plain Unicode characters rather than rendered SVG images. Terminal
|
|
5
|
+
* image protocols (Kitty, Sixel) are advertised inconsistently — Termius, for
|
|
6
|
+
* example, advertises Kitty support but fails to load the payload — so a
|
|
7
|
+
* capability probe can select an image branch that never actually renders and
|
|
8
|
+
* never falls back.
|
|
9
|
+
*
|
|
10
|
+
* Reference: OpenCode's own MCP sidebar uses exactly this shape
|
|
11
|
+
* (`packages/tui/src/feature-plugins/sidebar/mcp.tsx`):
|
|
12
|
+
*
|
|
13
|
+
* <text fg={theme.text.base}>{view.open ? "▼" : "▶"}</text>
|
|
14
|
+
*
|
|
15
|
+
* A terminal cannot scale a character: one code point paints in one cell, so
|
|
16
|
+
* `size`/`width`/`height` on a glyph reserve layout space and never enlarge the
|
|
17
|
+
* symbol. To make an indicator look bigger it must be drawn from several cells
|
|
18
|
+
* (block art) or rendered as an image on terminals that support it.
|
|
19
|
+
*/
|
|
20
|
+
/** Collapsed indicator. */
|
|
21
|
+
export declare const ARROW_RIGHT = "\u25B6";
|
|
22
|
+
/** Expanded indicator. */
|
|
23
|
+
export declare const ARROW_DOWN = "\u25BC";
|
|
24
|
+
/** Continue action. */
|
|
25
|
+
export declare const CONTINUE = "\u21BB";
|
|
26
|
+
/** Clear action. */
|
|
27
|
+
export declare const CLEAR = "\u2A2F";
|
|
28
|
+
export declare const ALL_GLYPHS: {
|
|
29
|
+
readonly ARROW_RIGHT: "▶";
|
|
30
|
+
readonly ARROW_DOWN: "▼";
|
|
31
|
+
readonly CONTINUE: "↻";
|
|
32
|
+
readonly CLEAR: "⨯";
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Exact codepoints shipped. Pinned so tests catch an accidental swap to a
|
|
36
|
+
* visually similar character that may not exist in every terminal font.
|
|
37
|
+
*
|
|
38
|
+
* Update these whenever a glyph above changes; the test compares the two.
|
|
39
|
+
*/
|
|
40
|
+
export declare const GLYPH_CODEPOINTS: {
|
|
41
|
+
readonly ARROW_RIGHT: 9654;
|
|
42
|
+
readonly ARROW_DOWN: 9660;
|
|
43
|
+
readonly CONTINUE: 8635;
|
|
44
|
+
readonly CLEAR: 10799;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Rejected look-alikes: characters that are visually similar but too small or
|
|
48
|
+
* not universally available in terminal fonts. Kept so a regression cannot
|
|
49
|
+
* quietly reintroduce a shrunk indicator.
|
|
50
|
+
*/
|
|
51
|
+
export declare const REJECTED_GLYPHS: readonly ["▸", "▾", "▷", "◁"];
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal glyphs for the TUI widget.
|
|
3
|
+
*
|
|
4
|
+
* These are plain Unicode characters rather than rendered SVG images. Terminal
|
|
5
|
+
* image protocols (Kitty, Sixel) are advertised inconsistently — Termius, for
|
|
6
|
+
* example, advertises Kitty support but fails to load the payload — so a
|
|
7
|
+
* capability probe can select an image branch that never actually renders and
|
|
8
|
+
* never falls back.
|
|
9
|
+
*
|
|
10
|
+
* Reference: OpenCode's own MCP sidebar uses exactly this shape
|
|
11
|
+
* (`packages/tui/src/feature-plugins/sidebar/mcp.tsx`):
|
|
12
|
+
*
|
|
13
|
+
* <text fg={theme.text.base}>{view.open ? "▼" : "▶"}</text>
|
|
14
|
+
*
|
|
15
|
+
* A terminal cannot scale a character: one code point paints in one cell, so
|
|
16
|
+
* `size`/`width`/`height` on a glyph reserve layout space and never enlarge the
|
|
17
|
+
* symbol. To make an indicator look bigger it must be drawn from several cells
|
|
18
|
+
* (block art) or rendered as an image on terminals that support it.
|
|
19
|
+
*/
|
|
20
|
+
/** Collapsed indicator. */
|
|
21
|
+
export const ARROW_RIGHT = "▶";
|
|
22
|
+
/** Expanded indicator. */
|
|
23
|
+
export const ARROW_DOWN = "▼";
|
|
24
|
+
/** Continue action. */
|
|
25
|
+
export const CONTINUE = "↻";
|
|
26
|
+
/** Clear action. */
|
|
27
|
+
export const CLEAR = "⨯";
|
|
28
|
+
export const ALL_GLYPHS = {
|
|
29
|
+
ARROW_RIGHT,
|
|
30
|
+
ARROW_DOWN,
|
|
31
|
+
CONTINUE,
|
|
32
|
+
CLEAR,
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Exact codepoints shipped. Pinned so tests catch an accidental swap to a
|
|
36
|
+
* visually similar character that may not exist in every terminal font.
|
|
37
|
+
*
|
|
38
|
+
* Update these whenever a glyph above changes; the test compares the two.
|
|
39
|
+
*/
|
|
40
|
+
export const GLYPH_CODEPOINTS = {
|
|
41
|
+
ARROW_RIGHT: 0x25b6, // ▶
|
|
42
|
+
ARROW_DOWN: 0x25bc, // ▼
|
|
43
|
+
CONTINUE: 0x21bb, // ↻
|
|
44
|
+
CLEAR: 0x2a2f, // ⨯
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Rejected look-alikes: characters that are visually similar but too small or
|
|
48
|
+
* not universally available in terminal fonts. Kept so a regression cannot
|
|
49
|
+
* quietly reintroduce a shrunk indicator.
|
|
50
|
+
*/
|
|
51
|
+
export const REJECTED_GLYPHS = [
|
|
52
|
+
"▸", // U+25B8 small triangle, too small at this size
|
|
53
|
+
"▾", // U+25BE small triangle, too small at this size
|
|
54
|
+
"▷", // U+25B7 outline triangle, too small
|
|
55
|
+
"◁", // U+25C1 outline triangle, too small
|
|
56
|
+
];
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,30 @@
|
|
|
1
1
|
import { Plugin } from "@opencode/plugin";
|
|
2
|
-
import { type TodoRootItem } from "./schemas/todo";
|
|
3
|
-
export declare function formatReadOutput(todos: readonly TodoRootItem[]
|
|
2
|
+
import { type TodoReadInput, type TodoRootItem } from "./schemas/todo";
|
|
3
|
+
export declare function formatReadOutput(todos: readonly TodoRootItem[], options?: {
|
|
4
|
+
visibleIds?: readonly number[];
|
|
5
|
+
}): string;
|
|
4
6
|
export declare function formatTransitionLines(before: readonly TodoRootItem[], after: readonly TodoRootItem[]): string[];
|
|
5
7
|
export declare function formatWriteOutput(todos: readonly TodoRootItem[], before?: readonly TodoRootItem[]): string;
|
|
6
8
|
export declare function assertWriteIsInitialization(existing: readonly TodoRootItem[], incoming: readonly TodoRootItem[]): void;
|
|
7
9
|
/** Update response: progress, next step, and transition lines without resending the list. */
|
|
8
10
|
export declare function formatUpdateOutput(todos: readonly TodoRootItem[], before?: readonly TodoRootItem[]): string;
|
|
11
|
+
/**
|
|
12
|
+
* Narrows a list for a scoped read.
|
|
13
|
+
*
|
|
14
|
+
* - `scope: "root"` returns one root with every subtask, so the whole branch is
|
|
15
|
+
* visible.
|
|
16
|
+
* - `scope: "children"` prints the root line as context plus the targeted
|
|
17
|
+
* subtask line, matching a "show me this subtask within its root" read.
|
|
18
|
+
* - `scope: "item"` prints only the targeted row.
|
|
19
|
+
*
|
|
20
|
+
* Either way the root keeps every subtask in the *data*, because the root's
|
|
21
|
+
* `(completed/total)` label is computed from them — dropping them would
|
|
22
|
+
* silently turn `(2/2)` into `(1/1)`.
|
|
23
|
+
*/
|
|
24
|
+
export declare function selectReadScope(todos: readonly TodoRootItem[], input: TodoReadInput): {
|
|
25
|
+
todos: TodoRootItem[];
|
|
26
|
+
visibleIds?: readonly number[];
|
|
27
|
+
};
|
|
9
28
|
export declare function registerTodoTools(ctx: Plugin.Context): Promise<void>;
|
|
10
29
|
export declare function registerTodoPromptHook(ctx: Plugin.Context): Promise<void>;
|
|
11
30
|
declare const _default: Plugin.Plugin;
|
package/dist/index.js
CHANGED
|
@@ -5,10 +5,10 @@ import { readTodoData, readTodos, updateTodos } from "./storage/todo-store.js";
|
|
|
5
5
|
import { buildTodoHint, consumeTodoHint, findNextTodo, findStuckParent, flattenLeaves, isAnyTodoActive, } from "./todos/hint.js";
|
|
6
6
|
import { TodoTree } from "./todos/todo-tree.js";
|
|
7
7
|
import { updateTodoById } from "./todos/update.js";
|
|
8
|
-
export function formatReadOutput(todos) {
|
|
8
|
+
export function formatReadOutput(todos, options) {
|
|
9
9
|
if (todos.length === 0)
|
|
10
10
|
return "No todos recorded.";
|
|
11
|
-
const tree = new TodoTree(todos).render();
|
|
11
|
+
const tree = new TodoTree(todos).render(options);
|
|
12
12
|
const check = new TodoTree(todos).validateAndNormalize();
|
|
13
13
|
if (check.valid)
|
|
14
14
|
return tree;
|
|
@@ -75,6 +75,38 @@ export function formatUpdateOutput(todos, before = []) {
|
|
|
75
75
|
const progress = `Todos (${stats.completedSubTasks}/${stats.totalSubTasks}).`;
|
|
76
76
|
return formatWriteOutput(todos, before).replace(/^Todos \(\d+\/\d+\) updated\./, progress.slice(0, -1));
|
|
77
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* Narrows a list for a scoped read.
|
|
80
|
+
*
|
|
81
|
+
* - `scope: "root"` returns one root with every subtask, so the whole branch is
|
|
82
|
+
* visible.
|
|
83
|
+
* - `scope: "children"` prints the root line as context plus the targeted
|
|
84
|
+
* subtask line, matching a "show me this subtask within its root" read.
|
|
85
|
+
* - `scope: "item"` prints only the targeted row.
|
|
86
|
+
*
|
|
87
|
+
* Either way the root keeps every subtask in the *data*, because the root's
|
|
88
|
+
* `(completed/total)` label is computed from them — dropping them would
|
|
89
|
+
* silently turn `(2/2)` into `(1/1)`.
|
|
90
|
+
*/
|
|
91
|
+
export function selectReadScope(todos, input) {
|
|
92
|
+
if (input.scope !== "item" && input.scope !== "children" && input.scope !== "root") {
|
|
93
|
+
return { todos: [...todos] };
|
|
94
|
+
}
|
|
95
|
+
const target = input.target;
|
|
96
|
+
const rootId = Number.isInteger(target) ? target : Math.floor(target);
|
|
97
|
+
const root = todos.find((item) => item.id === rootId);
|
|
98
|
+
const child = Number.isInteger(target)
|
|
99
|
+
? undefined
|
|
100
|
+
: root?.children?.find((item) => item.id === target);
|
|
101
|
+
if (!root || (!Number.isInteger(target) && !child)) {
|
|
102
|
+
throw new Error(`[manage_todo_list] todo id ${target} was not found`);
|
|
103
|
+
}
|
|
104
|
+
// `root` shows the branch as-is; it needs no row filter at all.
|
|
105
|
+
if (input.scope === "root")
|
|
106
|
+
return { todos: [root] };
|
|
107
|
+
const visibleIds = input.scope === "children" ? [rootId, target] : [target];
|
|
108
|
+
return { todos: [root], visibleIds };
|
|
109
|
+
}
|
|
78
110
|
export async function registerTodoTools(ctx) {
|
|
79
111
|
await ctx.tool.transform((tools) => {
|
|
80
112
|
tools.add({
|
|
@@ -97,7 +129,13 @@ export async function registerTodoTools(ctx) {
|
|
|
97
129
|
}
|
|
98
130
|
if (parsed.data.operation === "read") {
|
|
99
131
|
const todos = await readTodos(toolContext.sessionID);
|
|
100
|
-
|
|
132
|
+
const scoped = selectReadScope(todos, parsed.data);
|
|
133
|
+
return {
|
|
134
|
+
output: { todos: scoped.todos },
|
|
135
|
+
content: formatReadOutput(scoped.todos, {
|
|
136
|
+
visibleIds: scoped.visibleIds,
|
|
137
|
+
}),
|
|
138
|
+
};
|
|
101
139
|
}
|
|
102
140
|
if (parsed.data.operation === "update") {
|
|
103
141
|
const updateInput = parsed.data;
|
package/dist/schemas/todo.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import z from "zod";
|
|
2
|
-
|
|
2
|
+
/** A top-level id only: `1`, `2`, ... — never a dotted subtask id. */
|
|
3
|
+
export declare const RootIdSchema: z.ZodNumber;
|
|
4
|
+
export declare const ChildIdSchema: z.ZodNumber;
|
|
5
|
+
export declare const TodoTargetIdSchema: z.ZodUnion<readonly [z.ZodNumber, z.ZodNumber]>;
|
|
6
|
+
export declare const TodoChildrenItemSchema: z.ZodObject<{
|
|
3
7
|
id: z.ZodNumber;
|
|
4
8
|
content: z.ZodString;
|
|
5
9
|
status: z.ZodEnum<{
|
|
@@ -15,8 +19,7 @@ export declare const TodoChildernItemSchema: z.ZodObject<{
|
|
|
15
19
|
medium: "medium";
|
|
16
20
|
}>>;
|
|
17
21
|
note: z.ZodOptional<z.ZodString>;
|
|
18
|
-
}, z.core.$
|
|
19
|
-
export type TodoChildern = z.infer<typeof TodoChildernItemSchema>;
|
|
22
|
+
}, z.core.$strict>;
|
|
20
23
|
export declare const TodoRootItemSchema: z.ZodObject<{
|
|
21
24
|
id: z.ZodNumber;
|
|
22
25
|
content: z.ZodString;
|
|
@@ -49,9 +52,8 @@ export declare const TodoRootItemSchema: z.ZodObject<{
|
|
|
49
52
|
medium: "medium";
|
|
50
53
|
}>>;
|
|
51
54
|
note: z.ZodOptional<z.ZodString>;
|
|
52
|
-
}, z.core.$
|
|
53
|
-
}, z.core.$
|
|
54
|
-
export type TodoRootItem = z.infer<typeof TodoRootItemSchema>;
|
|
55
|
+
}, z.core.$strict>>>;
|
|
56
|
+
}, z.core.$strict>;
|
|
55
57
|
export declare const formatRootId: (id: number) => string;
|
|
56
58
|
export declare const formatChildId: (id: number) => string;
|
|
57
59
|
export declare const TodoListSchema: z.ZodArray<z.ZodObject<{
|
|
@@ -86,49 +88,43 @@ export declare const TodoListSchema: z.ZodArray<z.ZodObject<{
|
|
|
86
88
|
medium: "medium";
|
|
87
89
|
}>>;
|
|
88
90
|
note: z.ZodOptional<z.ZodString>;
|
|
89
|
-
}, z.core.$
|
|
90
|
-
}, z.core.$
|
|
91
|
-
export declare const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
cancelled: "cancelled";
|
|
97
|
-
completed: "completed";
|
|
98
|
-
error: "error";
|
|
99
|
-
in_progress: "in_progress";
|
|
100
|
-
pending: "pending";
|
|
101
|
-
}>;
|
|
102
|
-
priority: z.ZodOptional<z.ZodEnum<{
|
|
103
|
-
high: "high";
|
|
104
|
-
low: "low";
|
|
105
|
-
medium: "medium";
|
|
106
|
-
}>>;
|
|
107
|
-
note: z.ZodOptional<z.ZodString>;
|
|
108
|
-
children: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
109
|
-
id: z.ZodNumber;
|
|
110
|
-
content: z.ZodString;
|
|
111
|
-
status: z.ZodEnum<{
|
|
112
|
-
cancelled: "cancelled";
|
|
113
|
-
completed: "completed";
|
|
114
|
-
error: "error";
|
|
115
|
-
in_progress: "in_progress";
|
|
116
|
-
pending: "pending";
|
|
117
|
-
}>;
|
|
118
|
-
priority: z.ZodOptional<z.ZodEnum<{
|
|
119
|
-
high: "high";
|
|
120
|
-
low: "low";
|
|
121
|
-
medium: "medium";
|
|
122
|
-
}>>;
|
|
123
|
-
note: z.ZodOptional<z.ZodString>;
|
|
124
|
-
}, z.core.$strip>>>;
|
|
125
|
-
}, z.core.$strip>>;
|
|
126
|
-
}, z.core.$strip>;
|
|
127
|
-
export type TodoWriteInput = z.infer<typeof TodoWriteInputSchema>;
|
|
128
|
-
export declare const TodoTargetIdSchema: z.ZodNumber;
|
|
129
|
-
export declare const TodoReadOperationSchema: z.ZodObject<{
|
|
91
|
+
}, z.core.$strict>>>;
|
|
92
|
+
}, z.core.$strict>>;
|
|
93
|
+
export declare const TodoReadAllSchema: z.ZodObject<{
|
|
94
|
+
operation: z.ZodLiteral<"read">;
|
|
95
|
+
scope: z.ZodDefault<z.ZodLiteral<"all">>;
|
|
96
|
+
}, z.core.$strict>;
|
|
97
|
+
export declare const TodoReadItemSchema: z.ZodObject<{
|
|
130
98
|
operation: z.ZodLiteral<"read">;
|
|
99
|
+
scope: z.ZodLiteral<"item">;
|
|
100
|
+
target: z.ZodUnion<readonly [z.ZodNumber, z.ZodNumber]>;
|
|
131
101
|
}, z.core.$strict>;
|
|
102
|
+
export declare const TodoReadChildrenSchema: z.ZodObject<{
|
|
103
|
+
operation: z.ZodLiteral<"read">;
|
|
104
|
+
scope: z.ZodLiteral<"children">;
|
|
105
|
+
target: z.ZodNumber;
|
|
106
|
+
}, z.core.$strict>;
|
|
107
|
+
export declare const TodoReadRootSchema: z.ZodObject<{
|
|
108
|
+
operation: z.ZodLiteral<"read">;
|
|
109
|
+
scope: z.ZodLiteral<"root">;
|
|
110
|
+
target: z.ZodNumber;
|
|
111
|
+
}, z.core.$strict>;
|
|
112
|
+
export declare const TodoReadOperationSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
113
|
+
operation: z.ZodLiteral<"read">;
|
|
114
|
+
scope: z.ZodDefault<z.ZodLiteral<"all">>;
|
|
115
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
116
|
+
operation: z.ZodLiteral<"read">;
|
|
117
|
+
scope: z.ZodLiteral<"item">;
|
|
118
|
+
target: z.ZodUnion<readonly [z.ZodNumber, z.ZodNumber]>;
|
|
119
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
120
|
+
operation: z.ZodLiteral<"read">;
|
|
121
|
+
scope: z.ZodLiteral<"children">;
|
|
122
|
+
target: z.ZodNumber;
|
|
123
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
124
|
+
operation: z.ZodLiteral<"read">;
|
|
125
|
+
scope: z.ZodLiteral<"root">;
|
|
126
|
+
target: z.ZodNumber;
|
|
127
|
+
}, z.core.$strict>], "scope">;
|
|
132
128
|
export declare const TodoWriteOperationSchema: z.ZodObject<{
|
|
133
129
|
operation: z.ZodLiteral<"write">;
|
|
134
130
|
todos: z.ZodArray<z.ZodObject<{
|
|
@@ -163,12 +159,12 @@ export declare const TodoWriteOperationSchema: z.ZodObject<{
|
|
|
163
159
|
medium: "medium";
|
|
164
160
|
}>>;
|
|
165
161
|
note: z.ZodOptional<z.ZodString>;
|
|
166
|
-
}, z.core.$
|
|
167
|
-
}, z.core.$
|
|
162
|
+
}, z.core.$strict>>>;
|
|
163
|
+
}, z.core.$strict>>;
|
|
168
164
|
}, z.core.$strict>;
|
|
169
165
|
export declare const TodoUpdateOperationSchema: z.ZodObject<{
|
|
170
166
|
operation: z.ZodLiteral<"update">;
|
|
171
|
-
id: z.ZodNumber
|
|
167
|
+
id: z.ZodUnion<readonly [z.ZodNumber, z.ZodNumber]>;
|
|
172
168
|
status: z.ZodEnum<{
|
|
173
169
|
cancelled: "cancelled";
|
|
174
170
|
completed: "completed";
|
|
@@ -184,10 +180,22 @@ export declare const TodoUpdateOperationSchema: z.ZodObject<{
|
|
|
184
180
|
}>>>;
|
|
185
181
|
note: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
186
182
|
}, z.core.$strict>;
|
|
187
|
-
export
|
|
188
|
-
|
|
183
|
+
export declare const TodoInputToolSchema: z.ZodDiscriminatedUnion<[z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
184
|
+
operation: z.ZodLiteral<"read">;
|
|
185
|
+
scope: z.ZodDefault<z.ZodLiteral<"all">>;
|
|
186
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
189
187
|
operation: z.ZodLiteral<"read">;
|
|
188
|
+
scope: z.ZodLiteral<"item">;
|
|
189
|
+
target: z.ZodUnion<readonly [z.ZodNumber, z.ZodNumber]>;
|
|
190
190
|
}, z.core.$strict>, z.ZodObject<{
|
|
191
|
+
operation: z.ZodLiteral<"read">;
|
|
192
|
+
scope: z.ZodLiteral<"children">;
|
|
193
|
+
target: z.ZodNumber;
|
|
194
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
195
|
+
operation: z.ZodLiteral<"read">;
|
|
196
|
+
scope: z.ZodLiteral<"root">;
|
|
197
|
+
target: z.ZodNumber;
|
|
198
|
+
}, z.core.$strict>], "scope">, z.ZodObject<{
|
|
191
199
|
operation: z.ZodLiteral<"write">;
|
|
192
200
|
todos: z.ZodArray<z.ZodObject<{
|
|
193
201
|
id: z.ZodNumber;
|
|
@@ -221,11 +229,11 @@ export declare const TodoInputToolSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
221
229
|
medium: "medium";
|
|
222
230
|
}>>;
|
|
223
231
|
note: z.ZodOptional<z.ZodString>;
|
|
224
|
-
}, z.core.$
|
|
225
|
-
}, z.core.$
|
|
232
|
+
}, z.core.$strict>>>;
|
|
233
|
+
}, z.core.$strict>>;
|
|
226
234
|
}, z.core.$strict>, z.ZodObject<{
|
|
227
235
|
operation: z.ZodLiteral<"update">;
|
|
228
|
-
id: z.ZodNumber
|
|
236
|
+
id: z.ZodUnion<readonly [z.ZodNumber, z.ZodNumber]>;
|
|
229
237
|
status: z.ZodEnum<{
|
|
230
238
|
cancelled: "cancelled";
|
|
231
239
|
completed: "completed";
|
|
@@ -241,7 +249,6 @@ export declare const TodoInputToolSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
241
249
|
}>>>;
|
|
242
250
|
note: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
243
251
|
}, z.core.$strict>], "operation">;
|
|
244
|
-
export type TodoInputTool = z.infer<typeof TodoInputToolSchema>;
|
|
245
252
|
export declare const TodoOutputToolSchema: z.ZodObject<{
|
|
246
253
|
todos: z.ZodArray<z.ZodObject<{
|
|
247
254
|
id: z.ZodNumber;
|
|
@@ -275,7 +282,18 @@ export declare const TodoOutputToolSchema: z.ZodObject<{
|
|
|
275
282
|
medium: "medium";
|
|
276
283
|
}>>;
|
|
277
284
|
note: z.ZodOptional<z.ZodString>;
|
|
278
|
-
}, z.core.$
|
|
279
|
-
}, z.core.$
|
|
285
|
+
}, z.core.$strict>>>;
|
|
286
|
+
}, z.core.$strict>>;
|
|
280
287
|
}, z.core.$strip>;
|
|
288
|
+
export type TodoChildren = z.infer<typeof TodoChildrenItemSchema>;
|
|
289
|
+
export type TodoRootItem = z.infer<typeof TodoRootItemSchema>;
|
|
290
|
+
export type TodoReadAllInput = z.infer<typeof TodoReadAllSchema>;
|
|
291
|
+
export type TodoReadItemInput = z.infer<typeof TodoReadItemSchema>;
|
|
292
|
+
export type TodoReadChildrenInput = z.infer<typeof TodoReadChildrenSchema>;
|
|
293
|
+
export type TodoReadRootInput = z.infer<typeof TodoReadRootSchema>;
|
|
294
|
+
export type TodoReadInput = z.infer<typeof TodoReadOperationSchema>;
|
|
295
|
+
export type TodoReadScope = TodoReadInput["scope"];
|
|
296
|
+
export type TodoWriteOperationInput = z.infer<typeof TodoWriteOperationSchema>;
|
|
297
|
+
export type TodoUpdateInput = z.infer<typeof TodoUpdateOperationSchema>;
|
|
298
|
+
export type TodoInputTool = z.infer<typeof TodoInputToolSchema>;
|
|
281
299
|
export type TodoOutputTool = z.infer<typeof TodoOutputToolSchema>;
|