@gamflaz/opencode-todolist 1.0.4 → 1.0.5
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/image-capabilities.d.ts +9 -0
- package/dist/icons/image-capabilities.js +15 -0
- package/dist/icons/svg-icon.d.ts +7 -0
- package/dist/icons/svg-icon.jsx +37 -0
- package/dist/icons/svg-icons.d.ts +5 -0
- package/dist/icons/svg-icons.js +15 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +6 -6
- package/dist/schemas/platform.d.ts +20 -0
- package/dist/schemas/platform.js +21 -0
- package/dist/schemas/status.d.ts +18 -0
- package/dist/schemas/status.js +22 -0
- package/dist/schemas/todo.d.ts +281 -0
- package/dist/schemas/todo.js +112 -0
- package/dist/skills/loader.d.ts +24 -0
- package/dist/skills/loader.js +153 -0
- package/dist/storage/errors.d.ts +4 -0
- package/dist/storage/errors.js +7 -0
- package/dist/storage/todo-store.d.ts +145 -0
- package/dist/storage/todo-store.js +445 -0
- package/dist/todos/display.d.ts +21 -0
- package/dist/todos/display.js +53 -0
- package/dist/todos/hint.d.ts +16 -0
- package/dist/todos/hint.js +187 -0
- package/dist/todos/todo-tree.d.ts +63 -0
- package/dist/todos/todo-tree.js +188 -0
- package/dist/todos/update.d.ts +35 -0
- package/dist/todos/update.js +140 -0
- package/dist/tui/layout.d.ts +18 -0
- package/dist/tui/layout.js +22 -0
- package/dist/tui/text.d.ts +2 -0
- package/dist/tui/text.js +4 -0
- package/dist/tui/todo-panel.d.ts +77 -0
- package/dist/tui/todo-panel.jsx +503 -0
- package/dist/tui.d.ts +0 -97
- package/dist/tui.js +16 -776
- package/dist/tui.jsx +20 -0
- package/package.json +7 -2
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type TerminalCapabilities } from "@opentui/core";
|
|
2
|
+
/** Minimal image capability view needed to decide between image and text icons. */
|
|
3
|
+
export type ImageCapabilitySnapshot = Pick<TerminalCapabilities, "kitty_graphics" | "sixel"> & Partial<Pick<TerminalCapabilities, "image_protocol" | "multiplexer">>;
|
|
4
|
+
/**
|
|
5
|
+
* Whether the terminal can render raster icons. Terminals without Kitty or
|
|
6
|
+
* Sixel support (and any host that still reports unknown capabilities) must
|
|
7
|
+
* fall back to the direct text glyph.
|
|
8
|
+
*/
|
|
9
|
+
export declare function supportsImageRendering(capabilities: ImageCapabilitySnapshot | null | undefined): boolean;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether the terminal can render raster icons. Terminals without Kitty or
|
|
3
|
+
* Sixel support (and any host that still reports unknown capabilities) must
|
|
4
|
+
* fall back to the direct text glyph.
|
|
5
|
+
*/
|
|
6
|
+
export function supportsImageRendering(capabilities) {
|
|
7
|
+
if (!capabilities || capabilities.image_protocol === "blocks")
|
|
8
|
+
return false;
|
|
9
|
+
if (capabilities.multiplexer === "tmux" &&
|
|
10
|
+
capabilities.image_protocol !== "kitty" &&
|
|
11
|
+
capabilities.image_protocol !== "sixel") {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
return capabilities.kitty_graphics || capabilities.sixel;
|
|
15
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { usePlugin } from "@opencode/plugin/tui";
|
|
2
|
+
import { rgbToHex } from "@opentui/core";
|
|
3
|
+
import { Resvg } from "@resvg/resvg-js";
|
|
4
|
+
import { createMemo, createSignal, onCleanup, Show } from "solid-js";
|
|
5
|
+
import { supportsImageRendering } from "./image-capabilities";
|
|
6
|
+
export function SvgIcon(props) {
|
|
7
|
+
const { source: _, color: __, fallback, ...prop } = props;
|
|
8
|
+
const context = usePlugin();
|
|
9
|
+
const [imageSupported, setImageSupported] = createSignal(supportsImageRendering(context.renderer.capabilities));
|
|
10
|
+
const updateImageSupport = (capabilities) => {
|
|
11
|
+
setImageSupported(supportsImageRendering(capabilities));
|
|
12
|
+
};
|
|
13
|
+
context.renderer.on("capabilities", updateImageSupport);
|
|
14
|
+
onCleanup(() => context.renderer.off("capabilities", updateImageSupport));
|
|
15
|
+
const iconColor = () => props.color
|
|
16
|
+
? typeof props.color === "string"
|
|
17
|
+
? props.color
|
|
18
|
+
: rgbToHex(props.color)
|
|
19
|
+
: "currentColor";
|
|
20
|
+
const pngBuffer = createMemo(() => {
|
|
21
|
+
const bgToken = context.theme.background.base;
|
|
22
|
+
const bg = rgbToHex(bgToken);
|
|
23
|
+
let svg = props.source
|
|
24
|
+
.replace(/stroke="[^"]*"/g, `stroke="${iconColor()}"`)
|
|
25
|
+
.replace(/color="[^"]*"/g, `color="${iconColor()}"`);
|
|
26
|
+
const resvg = new Resvg(svg, {
|
|
27
|
+
fitTo: { mode: "width", value: 64 },
|
|
28
|
+
background: bg,
|
|
29
|
+
});
|
|
30
|
+
return resvg.render().asPng();
|
|
31
|
+
});
|
|
32
|
+
return (<Show when={imageSupported()} fallback={<text>
|
|
33
|
+
<span style={{ fg: iconColor() }}>{fallback}</span>
|
|
34
|
+
</text>}>
|
|
35
|
+
<image source={pngBuffer()} width={props.width ?? 2} height={props.height ?? 1} {...prop}/>
|
|
36
|
+
</Show>);
|
|
37
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Inline SVG icons used by the TUI. */
|
|
2
|
+
export declare const removeSvgIcon = "\n<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-mop-sparkles preview-icon\"><path d=\"M10 22a3 3 0 01-3-3\"/><path d=\"M10 22c2.761 0 5-1.79 5-4-4.42 0-4.08-5-8.5-5a4.501 4.501 0 000 9z\"/><path d=\"M10 3H8\"/><path d=\"M12.5 11.5 22 2\"/><path d=\"M20 13v4\"/><path d=\"M22 15h-4\"/><path d=\"M4 5v4\"/><path d=\"M6 7H2\"/><path d=\"m6.98 13.02 2.665-2.664a1.21 1.21 0 011.71 0l2.29 2.288a1.21 1.21 0 010 1.712l-2.088 2.087\"/><path d=\"M9 2v2\"/></svg>\n";
|
|
3
|
+
export declare const arrowDownSvgIcon = "\n<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"m6 9 6 6 6-6\"/>\n</svg>\n";
|
|
4
|
+
export declare const arrowRightSvgIcon = "\n<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path d=\"m9 18 6-6-6-6\"/>\n</svg>\n";
|
|
5
|
+
export declare const continuePromptSvgIcon = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-rotate-cw preview-icon\"><path d=\"M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8\"/><path d=\"M21 3v5h-5\"/></svg>";
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Inline SVG icons used by the TUI. */
|
|
2
|
+
export const removeSvgIcon = `
|
|
3
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-mop-sparkles preview-icon"><path d="M10 22a3 3 0 01-3-3"/><path d="M10 22c2.761 0 5-1.79 5-4-4.42 0-4.08-5-8.5-5a4.501 4.501 0 000 9z"/><path d="M10 3H8"/><path d="M12.5 11.5 22 2"/><path d="M20 13v4"/><path d="M22 15h-4"/><path d="M4 5v4"/><path d="M6 7H2"/><path d="m6.98 13.02 2.665-2.664a1.21 1.21 0 011.71 0l2.29 2.288a1.21 1.21 0 010 1.712l-2.088 2.087"/><path d="M9 2v2"/></svg>
|
|
4
|
+
`;
|
|
5
|
+
export const arrowDownSvgIcon = `
|
|
6
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
7
|
+
<path d="m6 9 6 6 6-6"/>
|
|
8
|
+
</svg>
|
|
9
|
+
`;
|
|
10
|
+
export const arrowRightSvgIcon = `
|
|
11
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
12
|
+
<path d="m9 18 6-6-6-6"/>
|
|
13
|
+
</svg>
|
|
14
|
+
`;
|
|
15
|
+
export const continuePromptSvgIcon = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw preview-icon"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"/><path d="M21 3v5h-5"/></svg>`;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Plugin } from "@opencode/plugin";
|
|
2
|
-
import { type TodoRootItem } from "./
|
|
2
|
+
import { type TodoRootItem } from "./schemas/todo";
|
|
3
3
|
export declare function formatReadOutput(todos: readonly TodoRootItem[]): string;
|
|
4
4
|
export declare function formatTransitionLines(before: readonly TodoRootItem[], after: readonly TodoRootItem[]): string[];
|
|
5
5
|
export declare function formatWriteOutput(todos: readonly TodoRootItem[], before?: readonly TodoRootItem[]): string;
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { Plugin } from "@opencode/plugin";
|
|
2
|
-
import { TodoInputToolSchema, TodoOutputToolSchema, } from "./
|
|
3
|
-
import { registerTodoSkills } from "./skills/
|
|
4
|
-
import { readTodoData, readTodos, updateTodos } from "./
|
|
5
|
-
import { buildTodoHint, consumeTodoHint, findNextTodo, findStuckParent, flattenLeaves, isAnyTodoActive, } from "./
|
|
6
|
-
import { TodoTree } from "./
|
|
7
|
-
import { updateTodoById } from "./
|
|
2
|
+
import { TodoInputToolSchema, TodoOutputToolSchema, } from "./schemas/todo";
|
|
3
|
+
import { registerTodoSkills } from "./skills/loader";
|
|
4
|
+
import { readTodoData, readTodos, updateTodos } from "./storage/todo-store";
|
|
5
|
+
import { buildTodoHint, consumeTodoHint, findNextTodo, findStuckParent, flattenLeaves, isAnyTodoActive, } from "./todos/hint";
|
|
6
|
+
import { TodoTree } from "./todos/todo-tree";
|
|
7
|
+
import { updateTodoById } from "./todos/update";
|
|
8
8
|
export function formatReadOutput(todos) {
|
|
9
9
|
if (todos.length === 0)
|
|
10
10
|
return "No todos recorded.";
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import z from "zod";
|
|
2
|
+
/** Platform fields used to resolve the todo storage location. */
|
|
3
|
+
export declare const PlatformContextSchema: z.ZodObject<{
|
|
4
|
+
platform: z.ZodOptional<z.ZodEnum<{
|
|
5
|
+
aix: "aix";
|
|
6
|
+
android: "android";
|
|
7
|
+
cygwin: "cygwin";
|
|
8
|
+
darwin: "darwin";
|
|
9
|
+
freebsd: "freebsd";
|
|
10
|
+
haiku: "haiku";
|
|
11
|
+
linux: "linux";
|
|
12
|
+
netbsd: "netbsd";
|
|
13
|
+
openbsd: "openbsd";
|
|
14
|
+
sunos: "sunos";
|
|
15
|
+
win32: "win32";
|
|
16
|
+
}>>;
|
|
17
|
+
env: z.ZodOptional<z.ZodDefault<z.ZodObject<{}, z.core.$strip>>>;
|
|
18
|
+
home: z.ZodOptional<z.ZodString>;
|
|
19
|
+
}, z.core.$strip>;
|
|
20
|
+
export type PlatformContext = z.infer<typeof PlatformContextSchema>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import z from "zod";
|
|
2
|
+
/** Platform fields used to resolve the todo storage location. */
|
|
3
|
+
export const PlatformContextSchema = z.object({
|
|
4
|
+
platform: z
|
|
5
|
+
.enum([
|
|
6
|
+
"aix",
|
|
7
|
+
"android",
|
|
8
|
+
"darwin",
|
|
9
|
+
"freebsd",
|
|
10
|
+
"haiku",
|
|
11
|
+
"linux",
|
|
12
|
+
"openbsd",
|
|
13
|
+
"sunos",
|
|
14
|
+
"win32",
|
|
15
|
+
"cygwin",
|
|
16
|
+
"netbsd",
|
|
17
|
+
])
|
|
18
|
+
.optional(),
|
|
19
|
+
env: z.object().default({}).optional(),
|
|
20
|
+
home: z.string().optional(),
|
|
21
|
+
});
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const TodoStatusSchema: z.ZodEnum<{
|
|
3
|
+
cancelled: "cancelled";
|
|
4
|
+
completed: "completed";
|
|
5
|
+
error: "error";
|
|
6
|
+
in_progress: "in_progress";
|
|
7
|
+
pending: "pending";
|
|
8
|
+
}>;
|
|
9
|
+
export type TodoStatus = z.infer<typeof TodoStatusSchema>;
|
|
10
|
+
export declare const PrioritySchema: z.ZodEnum<{
|
|
11
|
+
high: "high";
|
|
12
|
+
low: "low";
|
|
13
|
+
medium: "medium";
|
|
14
|
+
}>;
|
|
15
|
+
export type Priority = z.infer<typeof PrioritySchema>;
|
|
16
|
+
export declare const OPEN_STATUSES: readonly TodoStatus[];
|
|
17
|
+
/** Human-readable labels used in the resume prompt. */
|
|
18
|
+
export declare const StatusLabel: Record<TodoStatus, string>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export const TodoStatusSchema = z.enum([
|
|
3
|
+
"pending",
|
|
4
|
+
"in_progress",
|
|
5
|
+
"completed",
|
|
6
|
+
"cancelled",
|
|
7
|
+
"error",
|
|
8
|
+
]);
|
|
9
|
+
export const PrioritySchema = z.enum(["high", "medium", "low"]);
|
|
10
|
+
export const OPEN_STATUSES = [
|
|
11
|
+
"pending",
|
|
12
|
+
"in_progress",
|
|
13
|
+
"error",
|
|
14
|
+
];
|
|
15
|
+
/** Human-readable labels used in the resume prompt. */
|
|
16
|
+
export const StatusLabel = {
|
|
17
|
+
pending: "not started",
|
|
18
|
+
in_progress: "currently being worked on",
|
|
19
|
+
completed: "completed",
|
|
20
|
+
cancelled: "cancelled",
|
|
21
|
+
error: "needs fixing",
|
|
22
|
+
};
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import z from "zod";
|
|
2
|
+
export declare const TodoChildernItemSchema: z.ZodObject<{
|
|
3
|
+
id: z.ZodNumber;
|
|
4
|
+
content: z.ZodString;
|
|
5
|
+
status: z.ZodEnum<{
|
|
6
|
+
cancelled: "cancelled";
|
|
7
|
+
completed: "completed";
|
|
8
|
+
error: "error";
|
|
9
|
+
in_progress: "in_progress";
|
|
10
|
+
pending: "pending";
|
|
11
|
+
}>;
|
|
12
|
+
priority: z.ZodOptional<z.ZodEnum<{
|
|
13
|
+
high: "high";
|
|
14
|
+
low: "low";
|
|
15
|
+
medium: "medium";
|
|
16
|
+
}>>;
|
|
17
|
+
note: z.ZodOptional<z.ZodString>;
|
|
18
|
+
}, z.core.$strip>;
|
|
19
|
+
export type TodoChildern = z.infer<typeof TodoChildernItemSchema>;
|
|
20
|
+
export declare const TodoRootItemSchema: z.ZodObject<{
|
|
21
|
+
id: z.ZodNumber;
|
|
22
|
+
content: z.ZodString;
|
|
23
|
+
status: z.ZodEnum<{
|
|
24
|
+
cancelled: "cancelled";
|
|
25
|
+
completed: "completed";
|
|
26
|
+
error: "error";
|
|
27
|
+
in_progress: "in_progress";
|
|
28
|
+
pending: "pending";
|
|
29
|
+
}>;
|
|
30
|
+
priority: z.ZodOptional<z.ZodEnum<{
|
|
31
|
+
high: "high";
|
|
32
|
+
low: "low";
|
|
33
|
+
medium: "medium";
|
|
34
|
+
}>>;
|
|
35
|
+
note: z.ZodOptional<z.ZodString>;
|
|
36
|
+
children: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
37
|
+
id: z.ZodNumber;
|
|
38
|
+
content: z.ZodString;
|
|
39
|
+
status: z.ZodEnum<{
|
|
40
|
+
cancelled: "cancelled";
|
|
41
|
+
completed: "completed";
|
|
42
|
+
error: "error";
|
|
43
|
+
in_progress: "in_progress";
|
|
44
|
+
pending: "pending";
|
|
45
|
+
}>;
|
|
46
|
+
priority: z.ZodOptional<z.ZodEnum<{
|
|
47
|
+
high: "high";
|
|
48
|
+
low: "low";
|
|
49
|
+
medium: "medium";
|
|
50
|
+
}>>;
|
|
51
|
+
note: z.ZodOptional<z.ZodString>;
|
|
52
|
+
}, z.core.$strip>>>;
|
|
53
|
+
}, z.core.$strip>;
|
|
54
|
+
export type TodoRootItem = z.infer<typeof TodoRootItemSchema>;
|
|
55
|
+
export declare const formatRootId: (id: number) => string;
|
|
56
|
+
export declare const formatChildId: (id: number) => string;
|
|
57
|
+
export declare const TodoListSchema: z.ZodArray<z.ZodObject<{
|
|
58
|
+
id: z.ZodNumber;
|
|
59
|
+
content: z.ZodString;
|
|
60
|
+
status: z.ZodEnum<{
|
|
61
|
+
cancelled: "cancelled";
|
|
62
|
+
completed: "completed";
|
|
63
|
+
error: "error";
|
|
64
|
+
in_progress: "in_progress";
|
|
65
|
+
pending: "pending";
|
|
66
|
+
}>;
|
|
67
|
+
priority: z.ZodOptional<z.ZodEnum<{
|
|
68
|
+
high: "high";
|
|
69
|
+
low: "low";
|
|
70
|
+
medium: "medium";
|
|
71
|
+
}>>;
|
|
72
|
+
note: z.ZodOptional<z.ZodString>;
|
|
73
|
+
children: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
74
|
+
id: z.ZodNumber;
|
|
75
|
+
content: z.ZodString;
|
|
76
|
+
status: z.ZodEnum<{
|
|
77
|
+
cancelled: "cancelled";
|
|
78
|
+
completed: "completed";
|
|
79
|
+
error: "error";
|
|
80
|
+
in_progress: "in_progress";
|
|
81
|
+
pending: "pending";
|
|
82
|
+
}>;
|
|
83
|
+
priority: z.ZodOptional<z.ZodEnum<{
|
|
84
|
+
high: "high";
|
|
85
|
+
low: "low";
|
|
86
|
+
medium: "medium";
|
|
87
|
+
}>>;
|
|
88
|
+
note: z.ZodOptional<z.ZodString>;
|
|
89
|
+
}, z.core.$strip>>>;
|
|
90
|
+
}, z.core.$strip>>;
|
|
91
|
+
export declare const TodoWriteInputSchema: z.ZodObject<{
|
|
92
|
+
todos: z.ZodArray<z.ZodObject<{
|
|
93
|
+
id: z.ZodNumber;
|
|
94
|
+
content: z.ZodString;
|
|
95
|
+
status: z.ZodEnum<{
|
|
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<{
|
|
130
|
+
operation: z.ZodLiteral<"read">;
|
|
131
|
+
}, z.core.$strict>;
|
|
132
|
+
export declare const TodoWriteOperationSchema: z.ZodObject<{
|
|
133
|
+
operation: z.ZodLiteral<"write">;
|
|
134
|
+
todos: z.ZodArray<z.ZodObject<{
|
|
135
|
+
id: z.ZodNumber;
|
|
136
|
+
content: z.ZodString;
|
|
137
|
+
status: z.ZodEnum<{
|
|
138
|
+
cancelled: "cancelled";
|
|
139
|
+
completed: "completed";
|
|
140
|
+
error: "error";
|
|
141
|
+
in_progress: "in_progress";
|
|
142
|
+
pending: "pending";
|
|
143
|
+
}>;
|
|
144
|
+
priority: z.ZodOptional<z.ZodEnum<{
|
|
145
|
+
high: "high";
|
|
146
|
+
low: "low";
|
|
147
|
+
medium: "medium";
|
|
148
|
+
}>>;
|
|
149
|
+
note: z.ZodOptional<z.ZodString>;
|
|
150
|
+
children: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
151
|
+
id: z.ZodNumber;
|
|
152
|
+
content: z.ZodString;
|
|
153
|
+
status: z.ZodEnum<{
|
|
154
|
+
cancelled: "cancelled";
|
|
155
|
+
completed: "completed";
|
|
156
|
+
error: "error";
|
|
157
|
+
in_progress: "in_progress";
|
|
158
|
+
pending: "pending";
|
|
159
|
+
}>;
|
|
160
|
+
priority: z.ZodOptional<z.ZodEnum<{
|
|
161
|
+
high: "high";
|
|
162
|
+
low: "low";
|
|
163
|
+
medium: "medium";
|
|
164
|
+
}>>;
|
|
165
|
+
note: z.ZodOptional<z.ZodString>;
|
|
166
|
+
}, z.core.$strip>>>;
|
|
167
|
+
}, z.core.$strip>>;
|
|
168
|
+
}, z.core.$strict>;
|
|
169
|
+
export declare const TodoUpdateOperationSchema: z.ZodObject<{
|
|
170
|
+
operation: z.ZodLiteral<"update">;
|
|
171
|
+
id: z.ZodNumber;
|
|
172
|
+
status: z.ZodEnum<{
|
|
173
|
+
cancelled: "cancelled";
|
|
174
|
+
completed: "completed";
|
|
175
|
+
error: "error";
|
|
176
|
+
in_progress: "in_progress";
|
|
177
|
+
pending: "pending";
|
|
178
|
+
}>;
|
|
179
|
+
content: z.ZodOptional<z.ZodString>;
|
|
180
|
+
priority: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
|
|
181
|
+
high: "high";
|
|
182
|
+
low: "low";
|
|
183
|
+
medium: "medium";
|
|
184
|
+
}>>>;
|
|
185
|
+
note: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
186
|
+
}, z.core.$strict>;
|
|
187
|
+
export type TodoUpdateInput = z.infer<typeof TodoUpdateOperationSchema>;
|
|
188
|
+
export declare const TodoInputToolSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
189
|
+
operation: z.ZodLiteral<"read">;
|
|
190
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
191
|
+
operation: z.ZodLiteral<"write">;
|
|
192
|
+
todos: z.ZodArray<z.ZodObject<{
|
|
193
|
+
id: z.ZodNumber;
|
|
194
|
+
content: z.ZodString;
|
|
195
|
+
status: z.ZodEnum<{
|
|
196
|
+
cancelled: "cancelled";
|
|
197
|
+
completed: "completed";
|
|
198
|
+
error: "error";
|
|
199
|
+
in_progress: "in_progress";
|
|
200
|
+
pending: "pending";
|
|
201
|
+
}>;
|
|
202
|
+
priority: z.ZodOptional<z.ZodEnum<{
|
|
203
|
+
high: "high";
|
|
204
|
+
low: "low";
|
|
205
|
+
medium: "medium";
|
|
206
|
+
}>>;
|
|
207
|
+
note: z.ZodOptional<z.ZodString>;
|
|
208
|
+
children: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
209
|
+
id: z.ZodNumber;
|
|
210
|
+
content: z.ZodString;
|
|
211
|
+
status: z.ZodEnum<{
|
|
212
|
+
cancelled: "cancelled";
|
|
213
|
+
completed: "completed";
|
|
214
|
+
error: "error";
|
|
215
|
+
in_progress: "in_progress";
|
|
216
|
+
pending: "pending";
|
|
217
|
+
}>;
|
|
218
|
+
priority: z.ZodOptional<z.ZodEnum<{
|
|
219
|
+
high: "high";
|
|
220
|
+
low: "low";
|
|
221
|
+
medium: "medium";
|
|
222
|
+
}>>;
|
|
223
|
+
note: z.ZodOptional<z.ZodString>;
|
|
224
|
+
}, z.core.$strip>>>;
|
|
225
|
+
}, z.core.$strip>>;
|
|
226
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
227
|
+
operation: z.ZodLiteral<"update">;
|
|
228
|
+
id: z.ZodNumber;
|
|
229
|
+
status: z.ZodEnum<{
|
|
230
|
+
cancelled: "cancelled";
|
|
231
|
+
completed: "completed";
|
|
232
|
+
error: "error";
|
|
233
|
+
in_progress: "in_progress";
|
|
234
|
+
pending: "pending";
|
|
235
|
+
}>;
|
|
236
|
+
content: z.ZodOptional<z.ZodString>;
|
|
237
|
+
priority: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
|
|
238
|
+
high: "high";
|
|
239
|
+
low: "low";
|
|
240
|
+
medium: "medium";
|
|
241
|
+
}>>>;
|
|
242
|
+
note: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
243
|
+
}, z.core.$strict>], "operation">;
|
|
244
|
+
export type TodoInputTool = z.infer<typeof TodoInputToolSchema>;
|
|
245
|
+
export declare const TodoOutputToolSchema: z.ZodObject<{
|
|
246
|
+
todos: z.ZodArray<z.ZodObject<{
|
|
247
|
+
id: z.ZodNumber;
|
|
248
|
+
content: z.ZodString;
|
|
249
|
+
status: z.ZodEnum<{
|
|
250
|
+
cancelled: "cancelled";
|
|
251
|
+
completed: "completed";
|
|
252
|
+
error: "error";
|
|
253
|
+
in_progress: "in_progress";
|
|
254
|
+
pending: "pending";
|
|
255
|
+
}>;
|
|
256
|
+
priority: z.ZodOptional<z.ZodEnum<{
|
|
257
|
+
high: "high";
|
|
258
|
+
low: "low";
|
|
259
|
+
medium: "medium";
|
|
260
|
+
}>>;
|
|
261
|
+
note: z.ZodOptional<z.ZodString>;
|
|
262
|
+
children: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
263
|
+
id: z.ZodNumber;
|
|
264
|
+
content: z.ZodString;
|
|
265
|
+
status: z.ZodEnum<{
|
|
266
|
+
cancelled: "cancelled";
|
|
267
|
+
completed: "completed";
|
|
268
|
+
error: "error";
|
|
269
|
+
in_progress: "in_progress";
|
|
270
|
+
pending: "pending";
|
|
271
|
+
}>;
|
|
272
|
+
priority: z.ZodOptional<z.ZodEnum<{
|
|
273
|
+
high: "high";
|
|
274
|
+
low: "low";
|
|
275
|
+
medium: "medium";
|
|
276
|
+
}>>;
|
|
277
|
+
note: z.ZodOptional<z.ZodString>;
|
|
278
|
+
}, z.core.$strip>>>;
|
|
279
|
+
}, z.core.$strip>>;
|
|
280
|
+
}, z.core.$strip>;
|
|
281
|
+
export type TodoOutputTool = z.infer<typeof TodoOutputToolSchema>;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import z from "zod";
|
|
2
|
+
import { PrioritySchema, TodoStatusSchema } from "./status";
|
|
3
|
+
// Child id format: <root_id>.<n> as a number -> 1.1, 2.3, etc.
|
|
4
|
+
// Only a single decimal digit (1-9) is allowed, see the note below.
|
|
5
|
+
const ChildIdSchema = z
|
|
6
|
+
.number()
|
|
7
|
+
.refine((n) => /^[1-9]\d*\.[1-9]$/.test(String(n)), {
|
|
8
|
+
message: "Child id must follow the format <root_id>.<n> with n from 1 to 9, e.g. 1.1",
|
|
9
|
+
})
|
|
10
|
+
.describe("Unique subtask identifier, format <root_id>.<n> (e.g. 1.1)");
|
|
11
|
+
// TodoItem Children SCHEMA
|
|
12
|
+
export const TodoChildernItemSchema = z.object({
|
|
13
|
+
id: ChildIdSchema,
|
|
14
|
+
content: z.string().describe("Subtask description"),
|
|
15
|
+
status: TodoStatusSchema,
|
|
16
|
+
priority: PrioritySchema.optional(),
|
|
17
|
+
note: z.string().optional(),
|
|
18
|
+
});
|
|
19
|
+
// TodoItem Root SCHEMA
|
|
20
|
+
export const TodoRootItemSchema = z
|
|
21
|
+
.object({
|
|
22
|
+
id: z.number().int().positive().describe("Unique task identifier (e.g. 1)"),
|
|
23
|
+
content: z.string().describe("Main task summary"),
|
|
24
|
+
status: TodoStatusSchema,
|
|
25
|
+
priority: PrioritySchema.optional(),
|
|
26
|
+
note: z.string().optional(),
|
|
27
|
+
children: z.array(TodoChildernItemSchema).max(9).optional(),
|
|
28
|
+
})
|
|
29
|
+
.superRefine((root, ctx) => {
|
|
30
|
+
const seen = new Set();
|
|
31
|
+
if (root.children) {
|
|
32
|
+
root.children.forEach((child, i) => {
|
|
33
|
+
// The integer part of the child id must match the parent root id
|
|
34
|
+
if (Math.floor(child.id) !== root.id) {
|
|
35
|
+
ctx.addIssue({
|
|
36
|
+
code: "custom",
|
|
37
|
+
path: ["children", i, "id"],
|
|
38
|
+
message: `Child id ${child.id} must start with ${root.id}. (e.g. ${root.id}.1)`,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
// Child ids must be unique within the same root
|
|
42
|
+
if (seen.has(child.id)) {
|
|
43
|
+
ctx.addIssue({
|
|
44
|
+
code: "custom",
|
|
45
|
+
path: ["children", i, "id"],
|
|
46
|
+
message: `Duplicate child id ${child.id}`,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
seen.add(child.id);
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
// Display helpers
|
|
54
|
+
export const formatRootId = (id) => `${id}.`;
|
|
55
|
+
export const formatChildId = (id) => String(id);
|
|
56
|
+
// Full todolist: root ids must be unique across the whole list
|
|
57
|
+
export const TodoListSchema = z
|
|
58
|
+
.array(TodoRootItemSchema)
|
|
59
|
+
.superRefine((todos, ctx) => {
|
|
60
|
+
const seen = new Set();
|
|
61
|
+
todos.forEach((todo, i) => {
|
|
62
|
+
if (seen.has(todo.id)) {
|
|
63
|
+
ctx.addIssue({
|
|
64
|
+
code: "custom",
|
|
65
|
+
path: [i, "id"],
|
|
66
|
+
message: `Duplicate root id ${todo.id}`,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
seen.add(todo.id);
|
|
70
|
+
});
|
|
71
|
+
})
|
|
72
|
+
.describe("Hierarchical task list");
|
|
73
|
+
// TodoHook Write Input
|
|
74
|
+
export const TodoWriteInputSchema = z.object({
|
|
75
|
+
todos: TodoListSchema,
|
|
76
|
+
});
|
|
77
|
+
export const TodoTargetIdSchema = z
|
|
78
|
+
.number()
|
|
79
|
+
.positive()
|
|
80
|
+
.refine((id) => Number.isInteger(id) || /^[1-9]\d*\.[1-9]$/.test(String(id)), "ID must be a root number or child number such as 1 or 1.1");
|
|
81
|
+
// TodoHook Tool Schema
|
|
82
|
+
export const TodoReadOperationSchema = z
|
|
83
|
+
.object({
|
|
84
|
+
operation: z.literal("read").describe("'read' to inspect current todos."),
|
|
85
|
+
})
|
|
86
|
+
.strict();
|
|
87
|
+
export const TodoWriteOperationSchema = z
|
|
88
|
+
.object({
|
|
89
|
+
operation: z
|
|
90
|
+
.literal("write")
|
|
91
|
+
.describe("'write' to initialize an empty list."),
|
|
92
|
+
todos: TodoListSchema.describe("Required for 'write'. Pass [] to clear the list."),
|
|
93
|
+
})
|
|
94
|
+
.strict();
|
|
95
|
+
export const TodoUpdateOperationSchema = z
|
|
96
|
+
.object({
|
|
97
|
+
operation: z.literal("update").describe("'update' one root or child todo."),
|
|
98
|
+
id: TodoTargetIdSchema.describe("Root or child todo ID, e.g. 1 or 1.1"),
|
|
99
|
+
status: TodoStatusSchema.describe("New status for the target todo."),
|
|
100
|
+
content: z.string().optional(),
|
|
101
|
+
priority: PrioritySchema.nullable().optional(),
|
|
102
|
+
note: z.string().nullable().optional(),
|
|
103
|
+
})
|
|
104
|
+
.strict();
|
|
105
|
+
export const TodoInputToolSchema = z.discriminatedUnion("operation", [
|
|
106
|
+
TodoReadOperationSchema,
|
|
107
|
+
TodoWriteOperationSchema,
|
|
108
|
+
TodoUpdateOperationSchema,
|
|
109
|
+
]);
|
|
110
|
+
export const TodoOutputToolSchema = z.object({
|
|
111
|
+
todos: z.array(TodoRootItemSchema),
|
|
112
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type Plugin } from "@opencode/plugin";
|
|
2
|
+
export interface ParsedSkill {
|
|
3
|
+
name?: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
license?: string;
|
|
6
|
+
compatibility?: string;
|
|
7
|
+
metadata?: Record<string, string>;
|
|
8
|
+
body: string;
|
|
9
|
+
}
|
|
10
|
+
export interface LocalSkill {
|
|
11
|
+
id: string;
|
|
12
|
+
name: string;
|
|
13
|
+
description?: string;
|
|
14
|
+
license?: string;
|
|
15
|
+
compatibility?: string;
|
|
16
|
+
metadata?: Record<string, string>;
|
|
17
|
+
path: string;
|
|
18
|
+
content: string;
|
|
19
|
+
}
|
|
20
|
+
export declare function parseSkillMarkdown(input: string): ParsedSkill;
|
|
21
|
+
export declare function parseSkillFile(file: string): ParsedSkill | null;
|
|
22
|
+
export declare function getSkillsDirectory(): string;
|
|
23
|
+
export declare function readSkills(dir?: string): LocalSkill[];
|
|
24
|
+
export declare function registerTodoSkills(ctx: Plugin.Context): Promise<void>;
|