@gamflaz/opencode-todolist 0.0.0-stage → 1.0.1
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/LICENSE +21 -0
- package/README.md +149 -2
- package/dist/icons/capabilities.d.ts +9 -0
- package/dist/icons/capabilities.js +16 -0
- package/dist/icons/capabilities.js.map +1 -0
- package/dist/icons/convert.d.ts +7 -0
- package/dist/icons/convert.js +75 -0
- package/dist/icons/convert.jsx +38 -0
- package/dist/icons/convert.jsx.map +1 -0
- package/dist/icons/icons.d.ts +4 -0
- package/dist/icons/icons.js +15 -0
- package/dist/icons/icons.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +187 -0
- package/dist/index.js.map +1 -0
- package/dist/schema/status.schema.d.ts +16 -0
- package/dist/schema/status.schema.js +15 -0
- package/dist/schema/status.schema.js.map +1 -0
- package/dist/schema/store.schema.d.ts +19 -0
- package/dist/schema/store.schema.js +21 -0
- package/dist/schema/store.schema.js.map +1 -0
- package/dist/schema/todo.schema.d.ts +281 -0
- package/dist/schema/todo.schema.js +113 -0
- package/dist/schema/todo.schema.js.map +1 -0
- package/dist/skills/skill.d.ts +24 -0
- package/dist/skills/skill.js +154 -0
- package/dist/skills/skill.js.map +1 -0
- package/dist/store/errors.d.ts +3 -0
- package/dist/store/errors.js +7 -0
- package/dist/store/errors.js.map +1 -0
- package/dist/store/store.d.ts +145 -0
- package/dist/store/store.js +446 -0
- package/dist/store/store.js.map +1 -0
- package/dist/todo/display.d.ts +21 -0
- package/dist/todo/display.js +54 -0
- package/dist/todo/display.js.map +1 -0
- package/dist/todo/hint.d.ts +16 -0
- package/dist/todo/hint.js +188 -0
- package/dist/todo/hint.js.map +1 -0
- package/dist/todo/todo.d.ts +63 -0
- package/dist/todo/todo.js +189 -0
- package/dist/todo/todo.js.map +1 -0
- package/dist/todo/update.d.ts +35 -0
- package/dist/todo/update.js +141 -0
- package/dist/todo/update.js.map +1 -0
- package/dist/tui.d.ts +100 -0
- package/dist/tui.js +783 -0
- package/dist/tui.jsx +562 -0
- package/dist/tui.jsx.map +1 -0
- package/index.js +1 -0
- package/package.json +58 -4
- package/skills/continue-todolist/SKILL.md +94 -0
- package/skills/todolist/SKILL.md +220 -0
- package/tui.js +1 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Gamflaz
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,150 @@
|
|
|
1
|
-
#
|
|
1
|
+
# OpenCode Todo List Plugin
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A local OpenCode plugin for hierarchical todo tracking: a `manage_todo_list` tool
|
|
4
|
+
plus a TUI widget above the composer that shows progress in real time.
|
|
5
|
+
|
|
6
|
+
## Features
|
|
7
|
+
|
|
8
|
+
- Hierarchical tasks: any number of root tasks, each with up to 9 subtasks.
|
|
9
|
+
- Numeric IDs only: root `1`, `2`, … and subtasks `1.1`, `1.2`, … (`1.9` max).
|
|
10
|
+
- Small partial updates: change one item without resending the whole list.
|
|
11
|
+
- Strict forward-only progress with enforced order between root tasks.
|
|
12
|
+
- Real-time TUI widget with collapse, scroll, `↻ Continue`, and clear controls.
|
|
13
|
+
- Bundled skills that teach the agent how to drive the tool.
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
Requires [Bun](https://bun.sh/) and OpenCode V2.
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
git clone https://github.com/MomoPi-Dark/opencode-todolist.git \
|
|
21
|
+
~/.config/opencode/plugins/todolist
|
|
22
|
+
cd ~/.config/opencode/plugins/todolist
|
|
23
|
+
bun install
|
|
24
|
+
bun run build
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
OpenCode loads local plugins from the plugins directory, but it does not install
|
|
28
|
+
their dependencies, so `bun install` is required before use.
|
|
29
|
+
|
|
30
|
+
## Tool: `manage_todo_list`
|
|
31
|
+
|
|
32
|
+
### Read
|
|
33
|
+
|
|
34
|
+
```json
|
|
35
|
+
{ "operation": "read" }
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Returns the current list as a progress tree:
|
|
39
|
+
|
|
40
|
+
```text
|
|
41
|
+
[~] 1. Design architecture (1/2)
|
|
42
|
+
↳ note: Keep the hierarchy shallow
|
|
43
|
+
[x] 1.1 Database schema
|
|
44
|
+
[~] 1.2 API endpoints
|
|
45
|
+
[ ] 2. Write tests
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Markers: `[ ]` pending, `[~]` in progress, `[x]` completed, `[-]` cancelled,
|
|
49
|
+
`[!]` error. Notes render under their item as `↳ note: …`.
|
|
50
|
+
|
|
51
|
+
### Write
|
|
52
|
+
|
|
53
|
+
`write` initializes a session or clears it. A non-empty list is only accepted
|
|
54
|
+
while the session has no todos yet.
|
|
55
|
+
|
|
56
|
+
```json
|
|
57
|
+
{
|
|
58
|
+
"operation": "write",
|
|
59
|
+
"todos": [
|
|
60
|
+
{
|
|
61
|
+
"id": 1,
|
|
62
|
+
"content": "Add auth endpoint",
|
|
63
|
+
"status": "in_progress",
|
|
64
|
+
"note": "Return 401 on bad token",
|
|
65
|
+
"children": [
|
|
66
|
+
{ "id": 1.1, "content": "Write handler", "status": "pending" }
|
|
67
|
+
]
|
|
68
|
+
},
|
|
69
|
+
{ "id": 2, "content": "Update docs", "status": "pending" }
|
|
70
|
+
]
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Clear the current list:
|
|
75
|
+
|
|
76
|
+
```json
|
|
77
|
+
{ "operation": "write", "todos": [] }
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Update
|
|
81
|
+
|
|
82
|
+
`update` changes one existing root or subtask. Send only the fields that change;
|
|
83
|
+
`status` is required.
|
|
84
|
+
|
|
85
|
+
```json
|
|
86
|
+
{
|
|
87
|
+
"operation": "update",
|
|
88
|
+
"id": 1.1,
|
|
89
|
+
"status": "completed",
|
|
90
|
+
"note": "Tests passing"
|
|
91
|
+
}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Field values:
|
|
95
|
+
|
|
96
|
+
| Field | Required | Notes |
|
|
97
|
+
| ---------- | -------- | ------------------------------------------------------------ |
|
|
98
|
+
| `id` | Yes | Root number or subtask number (`1`, `1.1`). |
|
|
99
|
+
| `status` | Yes | `pending`, `in_progress`, `completed`, `cancelled`, `error`. |
|
|
100
|
+
| `content` | No | One-line summary shown in the widget. |
|
|
101
|
+
| `note` | No | Technical context or evidence. Pass `null` to remove. |
|
|
102
|
+
| `priority` | No | `high`, `medium`, or `low`. Pass `null` to remove. |
|
|
103
|
+
|
|
104
|
+
## Rules
|
|
105
|
+
|
|
106
|
+
1. **One root at a time, in order.** Root `2` cannot start while root `1` is
|
|
107
|
+
still open. Finish or cancel root `1` first.
|
|
108
|
+
2. **One active subtask per root.** Starting a second `in_progress` subtask is
|
|
109
|
+
rejected until the first one finishes or is cancelled.
|
|
110
|
+
3. **Forward-only progress.** `in_progress` never returns to `pending`, and
|
|
111
|
+
`completed` or `cancelled` items are locked.
|
|
112
|
+
4. **Error exception.** A root that reports `error` may be fixed early, but only
|
|
113
|
+
that root and its own subtasks; every other root still waits its turn.
|
|
114
|
+
5. **Evidence in `note`.** Record what was verified before marking an item
|
|
115
|
+
`completed`.
|
|
116
|
+
|
|
117
|
+
Every response reports progress, the next step, and any status transitions, for
|
|
118
|
+
example:
|
|
119
|
+
|
|
120
|
+
```text
|
|
121
|
+
Todos (2/4) updated. Next: 2 "Write tests". Continue immediately.
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## TUI widget
|
|
125
|
+
|
|
126
|
+
The widget sits above the session composer:
|
|
127
|
+
|
|
128
|
+
- Collapsed view shows the progress count and the active item.
|
|
129
|
+
- Expand it to see every task; long lists scroll.
|
|
130
|
+
- `↻ Continue` asks the session to resume the next open item with a short
|
|
131
|
+
summary of what remains.
|
|
132
|
+
- `✕` clears the list.
|
|
133
|
+
|
|
134
|
+
## Skills
|
|
135
|
+
|
|
136
|
+
`skills/todolist` and `skills/continue-todolist` ship with the plugin and are
|
|
137
|
+
registered automatically. They explain how to use the tool and how to resume
|
|
138
|
+
tracked work.
|
|
139
|
+
|
|
140
|
+
## Development
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
bun install
|
|
144
|
+
bun run check # typecheck + tests
|
|
145
|
+
bun run build # compile the plugin entrypoints
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Publishing notes
|
|
149
|
+
|
|
150
|
+
Do not commit environment files, local dependencies, or generated build output.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type TerminalCapabilities } from "@opentui/core";
|
|
2
|
+
/** Minimal 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,16 @@
|
|
|
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
|
+
}
|
|
16
|
+
//# sourceMappingURL=capabilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../src/icons/capabilities.ts"],"names":[],"mappings":"AASA;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CACpC,YAAwD;IAExD,IAAI,CAAC,YAAY,IAAI,YAAY,CAAC,cAAc,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5E,IACE,YAAY,CAAC,WAAW,KAAK,MAAM;QACnC,YAAY,CAAC,cAAc,KAAK,OAAO;QACvC,YAAY,CAAC,cAAc,KAAK,OAAO,EACvC,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,YAAY,CAAC,cAAc,IAAI,YAAY,CAAC,KAAK,CAAC;AAC3D,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { setProp as _$setProp } from "@opentui/solid";
|
|
2
|
+
import { effect as _$effect } from "@opentui/solid";
|
|
3
|
+
import { insertNode as _$insertNode } from "@opentui/solid";
|
|
4
|
+
import { insert as _$insert } from "@opentui/solid";
|
|
5
|
+
import { createComponent as _$createComponent } from "@opentui/solid";
|
|
6
|
+
import { spread as _$spread } from "@opentui/solid";
|
|
7
|
+
import { mergeProps as _$mergeProps } from "@opentui/solid";
|
|
8
|
+
import { memo as _$memo } from "@opentui/solid";
|
|
9
|
+
import { createElement as _$createElement } from "@opentui/solid";
|
|
10
|
+
import { usePlugin } from "@opencode/plugin/tui";
|
|
11
|
+
import { rgbToHex } from "@opentui/core";
|
|
12
|
+
import { Resvg } from "@resvg/resvg-js";
|
|
13
|
+
import { createMemo, createSignal, onCleanup, Show } from "solid-js";
|
|
14
|
+
import { supportsImageRendering } from "./capabilities";
|
|
15
|
+
export function SvgIcon(props) {
|
|
16
|
+
const {
|
|
17
|
+
source: _,
|
|
18
|
+
color: __,
|
|
19
|
+
fallback,
|
|
20
|
+
...prop
|
|
21
|
+
} = props;
|
|
22
|
+
const context = usePlugin();
|
|
23
|
+
const [imageSupported, setImageSupported] = createSignal(supportsImageRendering(context.renderer.capabilities));
|
|
24
|
+
const updateImageSupport = capabilities => {
|
|
25
|
+
setImageSupported(supportsImageRendering(capabilities));
|
|
26
|
+
};
|
|
27
|
+
context.renderer.on("capabilities", updateImageSupport);
|
|
28
|
+
onCleanup(() => context.renderer.off("capabilities", updateImageSupport));
|
|
29
|
+
const iconColor = () => props.color ? typeof props.color === "string" ? props.color : rgbToHex(props.color) : "currentColor";
|
|
30
|
+
const pngBuffer = createMemo(() => {
|
|
31
|
+
const bgToken = context.theme.background.base;
|
|
32
|
+
const bg = rgbToHex(bgToken);
|
|
33
|
+
let svg = props.source.replace(/stroke="[^"]*"/g, `stroke="${iconColor()}"`).replace(/color="[^"]*"/g, `color="${iconColor()}"`);
|
|
34
|
+
const resvg = new Resvg(svg, {
|
|
35
|
+
fitTo: {
|
|
36
|
+
mode: "width",
|
|
37
|
+
value: 64
|
|
38
|
+
},
|
|
39
|
+
background: bg
|
|
40
|
+
});
|
|
41
|
+
return resvg.render().asPng();
|
|
42
|
+
});
|
|
43
|
+
return _$createComponent(Show, {
|
|
44
|
+
get when() {
|
|
45
|
+
return imageSupported();
|
|
46
|
+
},
|
|
47
|
+
get fallback() {
|
|
48
|
+
return (() => {
|
|
49
|
+
var _el$2 = _$createElement("text"),
|
|
50
|
+
_el$3 = _$createElement("span");
|
|
51
|
+
_$insertNode(_el$2, _el$3);
|
|
52
|
+
_$insert(_el$3, fallback);
|
|
53
|
+
_$effect(_$p => _$setProp(_el$3, "style", {
|
|
54
|
+
fg: iconColor()
|
|
55
|
+
}, _$p));
|
|
56
|
+
return _el$2;
|
|
57
|
+
})();
|
|
58
|
+
},
|
|
59
|
+
get children() {
|
|
60
|
+
var _el$ = _$createElement("image");
|
|
61
|
+
_$spread(_el$, _$mergeProps({
|
|
62
|
+
get source() {
|
|
63
|
+
return pngBuffer();
|
|
64
|
+
},
|
|
65
|
+
get width() {
|
|
66
|
+
return props.width ?? 2;
|
|
67
|
+
},
|
|
68
|
+
get height() {
|
|
69
|
+
return props.height ?? 1;
|
|
70
|
+
}
|
|
71
|
+
}, prop), false);
|
|
72
|
+
return _el$;
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
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 "./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
|
+
}
|
|
38
|
+
//# sourceMappingURL=convert.jsx.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"convert.jsx","sourceRoot":"","sources":["../../src/icons/convert.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAQ,QAAQ,EAA6B,MAAM,eAAe,CAAC;AAE1E,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAExD,MAAM,UAAU,OAAO,CACrB,KAIC;IAED,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,CAAC;IAC1D,MAAM,OAAO,GAAG,SAAS,EAAE,CAAC;IAC5B,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,YAAY,CACtD,sBAAsB,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CACtD,CAAC;IACF,MAAM,kBAAkB,GAAG,CAAC,YAAkC,EAAE,EAAE;QAChE,iBAAiB,CAAC,sBAAsB,CAAC,YAAY,CAAC,CAAC,CAAC;IAC1D,CAAC,CAAC;IAEF,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC;IACxD,SAAS,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,cAAc,EAAE,kBAAkB,CAAC,CAAC,CAAC;IAE1E,MAAM,SAAS,GAAG,GAAG,EAAE,CACrB,KAAK,CAAC,KAAK;QACT,CAAC,CAAC,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ;YAC/B,CAAC,CAAC,KAAK,CAAC,KAAK;YACb,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC;QACzB,CAAC,CAAC,cAAc,CAAC;IAErB,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;QAChC,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC;QAC9C,MAAM,EAAE,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;QAE7B,IAAI,GAAG,GAAG,KAAK,CAAC,MAAM;aACnB,OAAO,CAAC,iBAAiB,EAAE,WAAW,SAAS,EAAE,GAAG,CAAC;aACrD,OAAO,CAAC,gBAAgB,EAAE,UAAU,SAAS,EAAE,GAAG,CAAC,CAAC;QAEvD,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,GAAG,EAAE;YAC3B,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE;YACnC,UAAU,EAAE,EAAE;SACf,CAAC,CAAC;QACH,OAAO,KAAK,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC;IAChC,CAAC,CAAC,CAAC;IAEH,OAAO,CACL,CAAC,IAAI,CACH,IAAI,CAAC,CAAC,cAAc,EAAE,CAAC,CACvB,QAAQ,CAAC,CACP,CAAC,IAAI,CACH;UAAA,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,IAAI,CACpD;QAAA,EAAE,IAAI,CACR,CAAC,CAED;MAAA,CAAC,KAAK,CACJ,MAAM,CAAC,CAAC,SAAS,EAAE,CAAC,CACpB,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC,CACxB,MAAM,CAAC,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC,CAC1B,IAAI,IAAI,CAAC,EAEb;IAAA,EAAE,IAAI,CAAC,CACR,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
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";
|
|
2
|
+
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";
|
|
3
|
+
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";
|
|
4
|
+
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
|
+
export const removeSvgIcon = `
|
|
2
|
+
<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>
|
|
3
|
+
`;
|
|
4
|
+
export const arrowDownSvgIcon = `
|
|
5
|
+
<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">
|
|
6
|
+
<path d="m6 9 6 6 6-6"/>
|
|
7
|
+
</svg>
|
|
8
|
+
`;
|
|
9
|
+
export const arrowRightSvgIcon = `
|
|
10
|
+
<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">
|
|
11
|
+
<path d="m9 18 6-6-6-6"/>
|
|
12
|
+
</svg>
|
|
13
|
+
`;
|
|
14
|
+
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>`;
|
|
15
|
+
//# sourceMappingURL=icons.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"icons.js","sourceRoot":"","sources":["../../src/icons/icons.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,aAAa,GAAG;;CAE5B,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;CAI/B,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG;;;;CAIhC,CAAC;AAEF,MAAM,CAAC,MAAM,qBAAqB,GAAG,6TAA6T,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Plugin } from "@opencode/plugin";
|
|
2
|
+
import { type TodoRootItem } from "./schema/todo.schema";
|
|
3
|
+
export declare function formatReadOutput(todos: readonly TodoRootItem[]): string;
|
|
4
|
+
export declare function formatTransitionLines(before: readonly TodoRootItem[], after: readonly TodoRootItem[]): string[];
|
|
5
|
+
export declare function formatWriteOutput(todos: readonly TodoRootItem[], before?: readonly TodoRootItem[]): string;
|
|
6
|
+
export declare function assertWriteIsInitialization(existing: readonly TodoRootItem[], incoming: readonly TodoRootItem[]): void;
|
|
7
|
+
/** Update response: progress, next step, and transition lines without resending the list. */
|
|
8
|
+
export declare function formatUpdateOutput(todos: readonly TodoRootItem[], before?: readonly TodoRootItem[]): string;
|
|
9
|
+
export declare function registerTodoTools(ctx: Plugin.Context): Promise<void>;
|
|
10
|
+
export declare function registerTodoPromptHook(ctx: Plugin.Context): Promise<void>;
|
|
11
|
+
declare const _default: Plugin.Plugin;
|
|
12
|
+
export default _default;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { Plugin } from "@opencode/plugin";
|
|
2
|
+
import { TodoInputToolSchema, TodoOutputToolSchema, } from "./schema/todo.schema";
|
|
3
|
+
import { registerTodoSkills } from "./skills/skill";
|
|
4
|
+
import { readTodoData, readTodos, updateTodos } from "./store/store";
|
|
5
|
+
import { buildTodoHint, consumeTodoHint, findNextTodo, findStuckParent, flattenLeaves, isAnyTodoActive, } from "./todo/hint";
|
|
6
|
+
import { TodoTree } from "./todo/todo";
|
|
7
|
+
import { updateTodoById } from "./todo/update";
|
|
8
|
+
export function formatReadOutput(todos) {
|
|
9
|
+
if (todos.length === 0)
|
|
10
|
+
return "No todos recorded.";
|
|
11
|
+
const tree = new TodoTree(todos).render();
|
|
12
|
+
const check = new TodoTree(todos).validateAndNormalize();
|
|
13
|
+
if (check.valid)
|
|
14
|
+
return tree;
|
|
15
|
+
return `Warning: the stored list needs fixing — ${check.error}\n${tree}`;
|
|
16
|
+
}
|
|
17
|
+
export function formatTransitionLines(before, after) {
|
|
18
|
+
const previous = new Map(flattenLeaves(before).map((leaf) => [leaf.id, leaf.status]));
|
|
19
|
+
const leaves = flattenLeaves(after);
|
|
20
|
+
const total = leaves.length;
|
|
21
|
+
const completed = [];
|
|
22
|
+
const started = [];
|
|
23
|
+
const failed = [];
|
|
24
|
+
leaves.forEach((leaf, index) => {
|
|
25
|
+
const was = previous.get(leaf.id);
|
|
26
|
+
const label = `(${index + 1}/${total}): ${leaf.content}`;
|
|
27
|
+
if (leaf.status === "completed" &&
|
|
28
|
+
was !== undefined &&
|
|
29
|
+
was !== "completed") {
|
|
30
|
+
completed.push(`✓\uFE0E Completed ${label}`);
|
|
31
|
+
}
|
|
32
|
+
else if (leaf.status === "in_progress" && was !== "in_progress") {
|
|
33
|
+
started.push(`▶\uFE0E Starting ${label}`);
|
|
34
|
+
}
|
|
35
|
+
else if (leaf.status === "error" &&
|
|
36
|
+
was !== undefined &&
|
|
37
|
+
was !== "error") {
|
|
38
|
+
failed.push(`✗\uFE0E Error ${label}${leaf.note ? ` — ${leaf.note}` : ""}`);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
return [...completed, ...started, ...failed];
|
|
42
|
+
}
|
|
43
|
+
export function formatWriteOutput(todos, before = []) {
|
|
44
|
+
const stats = new TodoTree(todos).calculateStats();
|
|
45
|
+
const base = `Todos (${stats.completedSubTasks}/${stats.totalSubTasks}) updated.`;
|
|
46
|
+
const next = findNextTodo(todos);
|
|
47
|
+
const stuck = findStuckParent(todos);
|
|
48
|
+
const head = next
|
|
49
|
+
? `${base} Next: ${next.id} "${next.content}". Continue immediately.`
|
|
50
|
+
: stuck
|
|
51
|
+
? `${base} All children of ${stuck.id} "${stuck.content}" are done. Set ${stuck.id} to completed (or cancelled) to finish it.`
|
|
52
|
+
: isAnyTodoActive(todos)
|
|
53
|
+
? `${base} Open items remain. Call manage_todo_list [read] and resolve them.`
|
|
54
|
+
: `${base} All todos finished.`;
|
|
55
|
+
const lines = formatTransitionLines(before, todos);
|
|
56
|
+
if (lines.length === 0)
|
|
57
|
+
return head;
|
|
58
|
+
return `${head}\nPrint these lines to chat verbatim, then continue:\n${lines.join("\n")}`;
|
|
59
|
+
}
|
|
60
|
+
export function assertWriteIsInitialization(existing, incoming) {
|
|
61
|
+
if (existing.length > 0 && incoming.length > 0) {
|
|
62
|
+
const messages = [
|
|
63
|
+
'[manage_todo_list] Invalid operation: "write".',
|
|
64
|
+
"",
|
|
65
|
+
'The "write" operation is only allowed during initialization.',
|
|
66
|
+
'Use "update" to modify an existing todo list.',
|
|
67
|
+
'To replace the entire list, use "write" with "todos:[]".',
|
|
68
|
+
];
|
|
69
|
+
throw new Error(messages.join("\n"));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/** Update response: progress, next step, and transition lines without resending the list. */
|
|
73
|
+
export function formatUpdateOutput(todos, before = []) {
|
|
74
|
+
const stats = new TodoTree(todos).calculateStats();
|
|
75
|
+
const progress = `Todos (${stats.completedSubTasks}/${stats.totalSubTasks}).`;
|
|
76
|
+
return formatWriteOutput(todos, before).replace(/^Todos \(\d+\/\d+\) updated\./, progress.slice(0, -1));
|
|
77
|
+
}
|
|
78
|
+
export async function registerTodoTools(ctx) {
|
|
79
|
+
await ctx.tool.transform((tools) => {
|
|
80
|
+
tools.add({
|
|
81
|
+
name: "manage_todo_list",
|
|
82
|
+
description: "Manage the todo list for multi-step tasks. Use non-empty 'write' only to initialize; use 'write' with [] to clear; use 'update' for existing items. " +
|
|
83
|
+
"Rules enforced: one root at a time in order — root 2 cannot start while root 1 is still open; only a root in 'error' may be fixed early, and only inside that root. " +
|
|
84
|
+
"Only one task/subtask may be 'in_progress'; progress never moves backward and finished items are locked. " +
|
|
85
|
+
"Mark items completed right after they are verified. " +
|
|
86
|
+
"Keep working through open items without asking permission to continue. " +
|
|
87
|
+
"Call 'read' first if unsure of current state, as tasks can be cleared by user via UI.",
|
|
88
|
+
input: TodoInputToolSchema,
|
|
89
|
+
output: TodoOutputToolSchema,
|
|
90
|
+
options: { codemode: false },
|
|
91
|
+
execute: async (input, toolContext) => {
|
|
92
|
+
const parsed = TodoInputToolSchema.safeParse(input);
|
|
93
|
+
if (!parsed.success) {
|
|
94
|
+
throw new Error(`[manage_todo_list validation failed] ${parsed.error.issues
|
|
95
|
+
.map((i) => `${i.path.join(".") || "input"}: ${i.message}`)
|
|
96
|
+
.join(", ")}`);
|
|
97
|
+
}
|
|
98
|
+
if (parsed.data.operation === "read") {
|
|
99
|
+
const todos = await readTodos(toolContext.sessionID);
|
|
100
|
+
return { output: { todos }, content: formatReadOutput(todos) };
|
|
101
|
+
}
|
|
102
|
+
if (parsed.data.operation === "update") {
|
|
103
|
+
const updateInput = parsed.data;
|
|
104
|
+
let updated;
|
|
105
|
+
let before = [];
|
|
106
|
+
const todos = await updateTodos(toolContext.sessionID, (current) => {
|
|
107
|
+
before = current;
|
|
108
|
+
const result = updateTodoById(current, updateInput);
|
|
109
|
+
updated = result.updated;
|
|
110
|
+
return result.todos;
|
|
111
|
+
});
|
|
112
|
+
return {
|
|
113
|
+
output: { todos },
|
|
114
|
+
content: `Updated ${updated.scope} todo ${updated.id}. ${formatUpdateOutput(todos, before)}`,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
const rawTodos = parsed.data.todos;
|
|
118
|
+
assertWriteIsInitialization(readTodoData(toolContext.sessionID)?.todos ?? [], rawTodos);
|
|
119
|
+
if (rawTodos.length === 0) {
|
|
120
|
+
await updateTodos(toolContext.sessionID, () => []);
|
|
121
|
+
return { output: { todos: [] }, content: "Cleared all todos." };
|
|
122
|
+
}
|
|
123
|
+
let before = [];
|
|
124
|
+
const todos = await updateTodos(toolContext.sessionID, (current) => {
|
|
125
|
+
before = current;
|
|
126
|
+
return rawTodos;
|
|
127
|
+
});
|
|
128
|
+
return { output: { todos }, content: formatWriteOutput(todos, before) };
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
await registerTodoSkills(ctx);
|
|
133
|
+
await registerTodoPromptHook(ctx);
|
|
134
|
+
}
|
|
135
|
+
export async function registerTodoPromptHook(ctx) {
|
|
136
|
+
if (typeof ctx.session?.hook !== "function")
|
|
137
|
+
return;
|
|
138
|
+
const debug = process.env.TODO_HINT_DEBUG === "1";
|
|
139
|
+
try {
|
|
140
|
+
await ctx.session.hook("context", async (sessionContext) => {
|
|
141
|
+
try {
|
|
142
|
+
const system = sessionContext.system;
|
|
143
|
+
if (!Array.isArray(system)) {
|
|
144
|
+
if (debug)
|
|
145
|
+
console.error("[todo] system is not an array");
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
const hint = buildTodoHint(sessionContext.sessionID);
|
|
149
|
+
if (!hint)
|
|
150
|
+
return;
|
|
151
|
+
system.push({ type: "text", text: hint });
|
|
152
|
+
if (debug)
|
|
153
|
+
console.error("[todo] hint injected", sessionContext.sessionID);
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
// Fail-safe
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
// Fallback
|
|
163
|
+
}
|
|
164
|
+
try {
|
|
165
|
+
await ctx.session.hook("prompt", async (sessionPrompt) => {
|
|
166
|
+
try {
|
|
167
|
+
if (!sessionPrompt.prompt?.text?.trim())
|
|
168
|
+
return;
|
|
169
|
+
const hint = consumeTodoHint(sessionPrompt.sessionID);
|
|
170
|
+
if (hint) {
|
|
171
|
+
sessionPrompt.prompt.text = `${sessionPrompt.prompt.text}\n\n${hint}`;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
// Fail-safe
|
|
176
|
+
}
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
catch {
|
|
180
|
+
// Graceful degradation
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
export default Plugin.define({
|
|
184
|
+
id: "opencode.todolist.tool",
|
|
185
|
+
setup: registerTodoTools,
|
|
186
|
+
});
|
|
187
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
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[];
|
|
@@ -0,0 +1,15 @@
|
|
|
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
|
+
//# sourceMappingURL=status.schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.schema.js","sourceRoot":"","sources":["../../src/schema/status.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,CAAC,IAAI,CAAC;IACrC,SAAS;IACT,aAAa;IACb,WAAW;IACX,WAAW;IACX,OAAO;CACR,CAAC,CAAC;AAGH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC;AAGhE,MAAM,CAAC,MAAM,aAAa,GAA0B;IAClD,SAAS;IACT,aAAa;IACb,OAAO;CACR,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import z from "zod";
|
|
2
|
+
export declare const PlatformContextSchema: z.ZodObject<{
|
|
3
|
+
platform: z.ZodOptional<z.ZodEnum<{
|
|
4
|
+
aix: "aix";
|
|
5
|
+
android: "android";
|
|
6
|
+
cygwin: "cygwin";
|
|
7
|
+
darwin: "darwin";
|
|
8
|
+
freebsd: "freebsd";
|
|
9
|
+
haiku: "haiku";
|
|
10
|
+
linux: "linux";
|
|
11
|
+
netbsd: "netbsd";
|
|
12
|
+
openbsd: "openbsd";
|
|
13
|
+
sunos: "sunos";
|
|
14
|
+
win32: "win32";
|
|
15
|
+
}>>;
|
|
16
|
+
env: z.ZodOptional<z.ZodDefault<z.ZodObject<{}, z.core.$strip>>>;
|
|
17
|
+
home: z.ZodOptional<z.ZodString>;
|
|
18
|
+
}, z.core.$strip>;
|
|
19
|
+
export type PlatformContext = z.infer<typeof PlatformContextSchema>;
|