@gamflaz/opencode-todolist 1.0.10 → 1.0.12

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/README.md CHANGED
@@ -21,17 +21,20 @@ git clone https://github.com/MomoPi-Dark/opencode-todolist.git \
21
21
  ~/.config/opencode/plugins/todolist
22
22
  cd ~/.config/opencode/plugins/todolist
23
23
  bun install
24
- bun run build
25
24
  ```
26
25
 
26
+ `bun install` runs the `prepare` script, which compiles `dist/` from `src/`
27
+ (TypeScript declarations plus Solid-compiled JSX). No extra step is required.
28
+
27
29
  Or add it directly through the OpenCode CLI:
28
30
 
29
31
  ```bash
30
32
  opencode plugin add @gamflaz/opencode-todolist
31
33
  ```
32
34
 
33
- OpenCode loads local plugins from the plugins directory, but it does not install
34
- their dependencies, so `bun install` is required before use.
35
+ The npm package ships the prebuilt `dist/`, so no local build runs. OpenCode
36
+ loads local plugins from the plugins directory but does not install their
37
+ dependencies, so `bun install` is required before use.
35
38
 
36
39
  ## Tool: `manage_todo_list`
37
40
 
@@ -141,11 +144,23 @@ tracked work.
141
144
  ## Development
142
145
 
143
146
  ```bash
144
- bun install
147
+ bun install # runs prepare -> compiles dist/
145
148
  bun run check # typecheck + tests
146
- bun run build # compile the plugin entrypoints
149
+ bun run compile # rebuild dist/ (tsc + Solid JSX transform)
147
150
  ```
148
151
 
152
+ `bun run compile` must be used instead of `bun run build`: the raw `tsc` pass
153
+ alone leaves intermediate `.jsx` files in `dist/`, which Bun then prefers over
154
+ the compiled `.js` and reports as `No renderer found` / `ENOENT ... dist/tui.jsx`.
155
+
149
156
  ## Publishing notes
150
157
 
151
- Do not commit environment files, local dependencies, or generated build output.
158
+ `dist/`, `index.js`, and `tui.js` are generated build output and are not
159
+ committed. They reach users through the npm tarball: npm runs `prepare`
160
+ (`bun run compile`) before packing, and `files` ships the built `dist/`
161
+ directory. The `opencode plugin add` installer skips lifecycle scripts
162
+ (`ignoreScripts: true`), so the tarball — not a post-install build — must
163
+ contain `dist/`.
164
+
165
+ Before publishing, run `bun run check && bun run compile` and confirm
166
+ `dist/` contains no `.jsx` files.
@@ -10,15 +10,16 @@ import { createElement as _$createElement } from "@opentui/solid";
10
10
  import { usePlugin } from "@opencode/plugin/tui";
11
11
  import { rgbToHex } from "@opentui/core";
12
12
  import { Resvg } from "@resvg/resvg-js";
13
- import { createMemo, createSignal, onCleanup, Show } from "solid-js";
14
- import { supportsImageRendering } from "./image-capabilities";
13
+ import { createMemo, createSignal, onCleanup, Show, splitProps } from "solid-js";
14
+ import { supportsImageRendering } from "./image-capabilities.js";
15
15
  export function SvgIcon(props) {
16
- const {
17
- source: _,
18
- color: __,
19
- fallback,
20
- ...prop
21
- } = props;
16
+ // Solid props are getters. Destructuring them reads each value exactly once
17
+ // at creation time, which freezes the prop instead of tracking it. That made
18
+ // the collapsed `▶` / expanded `▼` fallback glyph stick on terminals without
19
+ // image support, where the text fallback is the branch that renders.
20
+ // splitProps keeps every accessor live while still separating the props this
21
+ // component consumes from the ones forwarded to the rendered element.
22
+ const [local, rest] = splitProps(props, ["source", "color", "fallback"]);
22
23
  const context = usePlugin();
23
24
  const [imageSupported, setImageSupported] = createSignal(supportsImageRendering(context.renderer.capabilities));
24
25
  const updateImageSupport = capabilities => {
@@ -26,11 +27,11 @@ export function SvgIcon(props) {
26
27
  };
27
28
  context.renderer.on("capabilities", updateImageSupport);
28
29
  onCleanup(() => context.renderer.off("capabilities", updateImageSupport));
29
- const iconColor = () => props.color ? typeof props.color === "string" ? props.color : rgbToHex(props.color) : "currentColor";
30
+ const iconColor = () => local.color ? typeof local.color === "string" ? local.color : rgbToHex(local.color) : "currentColor";
30
31
  const pngBuffer = createMemo(() => {
31
32
  const bgToken = context.theme.background.base;
32
33
  const bg = rgbToHex(bgToken);
33
- let svg = props.source.replace(/stroke="[^"]*"/g, `stroke="${iconColor()}"`).replace(/color="[^"]*"/g, `color="${iconColor()}"`);
34
+ let svg = local.source.replace(/stroke="[^"]*"/g, `stroke="${iconColor()}"`).replace(/color="[^"]*"/g, `color="${iconColor()}"`);
34
35
  const resvg = new Resvg(svg, {
35
36
  fitTo: {
36
37
  mode: "width",
@@ -49,7 +50,7 @@ export function SvgIcon(props) {
49
50
  var _el$2 = _$createElement("text"),
50
51
  _el$3 = _$createElement("span");
51
52
  _$insertNode(_el$2, _el$3);
52
- _$insert(_el$3, fallback);
53
+ _$insert(_el$3, () => local.fallback);
53
54
  _$effect(_$p => _$setProp(_el$3, "style", {
54
55
  fg: iconColor()
55
56
  }, _$p));
@@ -68,7 +69,7 @@ export function SvgIcon(props) {
68
69
  get height() {
69
70
  return props.height ?? 1;
70
71
  }
71
- }, prop), false);
72
+ }, rest), false);
72
73
  return _el$;
73
74
  }
74
75
  });
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import { Plugin } from "@opencode/plugin";
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";
2
+ import { TodoInputToolSchema, TodoOutputToolSchema, } from "./schemas/todo.js";
3
+ import { registerTodoSkills } from "./skills/loader.js";
4
+ import { readTodoData, readTodos, updateTodos } from "./storage/todo-store.js";
5
+ import { buildTodoHint, consumeTodoHint, findNextTodo, findStuckParent, flattenLeaves, isAnyTodoActive, } from "./todos/hint.js";
6
+ import { TodoTree } from "./todos/todo-tree.js";
7
+ import { updateTodoById } from "./todos/update.js";
8
8
  export function formatReadOutput(todos) {
9
9
  if (todos.length === 0)
10
10
  return "No todos recorded.";
@@ -181,6 +181,6 @@ export async function registerTodoPromptHook(ctx) {
181
181
  }
182
182
  }
183
183
  export default Plugin.define({
184
- id: "opencode.todolist.tool1",
184
+ id: "opencode.todolist.tool",
185
185
  setup: registerTodoTools,
186
186
  });
@@ -1,5 +1,5 @@
1
1
  import z from "zod";
2
- import { PrioritySchema, TodoStatusSchema } from "./status";
2
+ import { PrioritySchema, TodoStatusSchema } from "./status.js";
3
3
  // Child id format: <root_id>.<n> as a number -> 1.1, 2.3, etc.
4
4
  // Only a single decimal digit (1-9) is allowed, see the note below.
5
5
  const ChildIdSchema = z
@@ -4,9 +4,9 @@ import { chmod, mkdir, readFile, rename, rm, writeFile, } from "node:fs/promises
4
4
  import { homedir, tmpdir } from "node:os";
5
5
  import { join, posix, win32 } from "node:path";
6
6
  import * as lockfile from "proper-lockfile";
7
- import { TodoRootItemSchema } from "../schemas/todo";
8
- import { TodoTree } from "../todos/todo-tree";
9
- import { InvalidTodoDataError } from "./errors";
7
+ import { TodoRootItemSchema } from "../schemas/todo.js";
8
+ import { TodoTree } from "../todos/todo-tree.js";
9
+ import { InvalidTodoDataError } from "./errors.js";
10
10
  /**
11
11
  * Per-session todo persistence.
12
12
  *
@@ -1,4 +1,4 @@
1
- import { TodoTree } from "./todo-tree";
1
+ import { TodoTree } from "./todo-tree.js";
2
2
  export function getStatusIcon(status) {
3
3
  switch (status) {
4
4
  case "completed":
@@ -1,6 +1,6 @@
1
1
  import { readFileSync, renameSync, writeFileSync } from "node:fs";
2
- import { getHintMarkerPath, readTodoData, TodoStore } from "../storage/todo-store";
3
- import { TodoTree } from "./todo-tree";
2
+ import { getHintMarkerPath, readTodoData, TodoStore } from "../storage/todo-store.js";
3
+ import { TodoTree } from "./todo-tree.js";
4
4
  export const DEFAULT_STALE_MS = 30 * 60 * 1000; // 30 minutes (prompt fallback)
5
5
  export const CONTEXT_STALE_MS = 6 * 60 * 60 * 1000; // 6 hours
6
6
  const UPCOMING_LIMIT = 3;
@@ -1,4 +1,4 @@
1
- import { TodoTree } from "../todos/todo-tree";
1
+ import { TodoTree } from "../todos/todo-tree.js";
2
2
  /** Rendered prefix of an error detail row. */
3
3
  export const ERROR_PREFIX = "↳ error: ";
4
4
  /**
@@ -1,6 +1,6 @@
1
1
  import { Plugin } from "@opencode/plugin/tui";
2
- import { ColorInput, ScrollBoxRenderable } from "@opentui/core";
3
- import { TodoStatus } from "../schemas/status";
2
+ import { type ColorInput, ScrollBoxRenderable } from "@opentui/core";
3
+ import { type TodoStatus } from "../schemas/status";
4
4
  /** How many open items the Continue prompt lists before collapsing the rest. */
5
5
  export declare const CONTINUE_PROMPT_MAX_ITEMS = 3;
6
6
  /** Per-field caps so one long note cannot flood the prompt. */
@@ -1,23 +1,25 @@
1
+ import { effect as _$effect } from "@opentui/solid";
1
2
  import { memo as _$memo } from "@opentui/solid";
2
3
  import { createTextNode as _$createTextNode } from "@opentui/solid";
3
- import { effect as _$effect } from "@opentui/solid";
4
4
  import { insertNode as _$insertNode } from "@opentui/solid";
5
5
  import { insert as _$insert } from "@opentui/solid";
6
6
  import { createComponent as _$createComponent } from "@opentui/solid";
7
7
  import { setProp as _$setProp } from "@opentui/solid";
8
8
  import { use as _$use } from "@opentui/solid";
9
+ import { spread as _$spread } from "@opentui/solid";
10
+ import { mergeProps as _$mergeProps } from "@opentui/solid";
9
11
  import { createElement as _$createElement } from "@opentui/solid";
10
12
  import { mkdirSync, watch } from "node:fs";
11
13
  import { createEffect, createMemo, createSignal, For, onCleanup, Show } from "solid-js";
12
- import { supportsImageRendering } from "../icons/image-capabilities";
13
- import { SvgIcon } from "../icons/svg-icon";
14
- import { arrowDownSvgIcon, arrowRightSvgIcon, continuePromptSvgIcon, removeSvgIcon } from "../icons/svg-icons";
15
- import { StatusLabel } from "../schemas/status";
16
- import { getTodosDirectory, hashSessionID, readTodosSync, writeTodos } from "../storage/todo-store";
17
- import { getTodoDisplaySummary, hasOpenTodos } from "../todos/display";
18
- import { TodoTree } from "../todos/todo-tree";
19
- import { shorten } from "./text";
20
- import { ERROR_PREFIX, ErrorRowWidth, RowWidth } from "./layout";
14
+ import { supportsImageRendering } from "../icons/image-capabilities.js";
15
+ import { SvgIcon } from "../icons/svg-icon.js";
16
+ import { arrowDownSvgIcon, arrowRightSvgIcon, continuePromptSvgIcon, removeSvgIcon } from "../icons/svg-icons.js";
17
+ import { StatusLabel } from "../schemas/status.js";
18
+ import { getTodosDirectory, hashSessionID, readTodosSync, writeTodos } from "../storage/todo-store.js";
19
+ import { getTodoDisplaySummary, hasOpenTodos } from "../todos/display.js";
20
+ import { TodoTree } from "../todos/todo-tree.js";
21
+ import { ERROR_PREFIX, ErrorRowWidth, RowWidth } from "./layout.js";
22
+ import { shorten } from "./text.js";
21
23
 
22
24
  /** How many open items the Continue prompt lists before collapsing the rest. */
23
25
  export const CONTINUE_PROMPT_MAX_ITEMS = 3;
@@ -167,21 +169,29 @@ export function TodoList(props) {
167
169
  if (el) followActiveRow(el);
168
170
  });
169
171
  const scrollbarOptions = () => props.scrollbarColor ? {
170
- trackOptions: {
171
- backgroundColor: props.scrollbarColor,
172
- foregroundColor: props.scrollbarColor
172
+ verticalScrollbarOptions: {
173
+ trackOptions: {
174
+ backgroundColor: props.scrollbarColor,
175
+ foregroundColor: props.scrollbarColor
176
+ }
173
177
  }
174
- } : undefined;
178
+ } : {};
175
179
  const isExpanded = id => (props.expandedIds ?? []).includes(id);
176
180
  return (() => {
177
181
  var _el$ = _$createElement("scrollbox"),
178
182
  _el$2 = _$createElement("box");
179
183
  _$insertNode(_el$, _el$2);
180
184
  _$use(attach, _el$);
181
- _$setProp(_el$, "width", "100%");
182
- _$setProp(_el$, "horizontalScrollbarOptions", {
183
- visible: false
184
- });
185
+ _$setProp(_el$, "width", "auto");
186
+ _$spread(_el$, _$mergeProps({
187
+ get height() {
188
+ return Math.min(entries().length, TODO_PANEL_MAX_ROWS);
189
+ }
190
+ }, scrollbarOptions, {
191
+ "horizontalScrollbarOptions": {
192
+ visible: false
193
+ }
194
+ }), true);
185
195
  _$setProp(_el$2, "flexDirection", "column");
186
196
  _$setProp(_el$2, "flexShrink", 0);
187
197
  _$insert(_el$2, _$createComponent(For, {
@@ -239,23 +249,23 @@ export function TodoList(props) {
239
249
  }
240
250
  }), null);
241
251
  _$effect(_p$ => {
242
- var _v$3 = rowId(entry.row.id),
243
- _v$4 = RowWidth(entry.row),
244
- _v$5 = {
252
+ var _v$ = rowId(entry.row.id),
253
+ _v$2 = RowWidth(entry.row),
254
+ _v$3 = {
245
255
  fg: entry.row.iconColor
246
256
  },
247
- _v$6 = {
257
+ _v$4 = {
248
258
  fg: entry.row.textColor
249
259
  },
250
- _v$7 = {
260
+ _v$5 = {
251
261
  fg: entry.row.textColor,
252
262
  strikethrough: entry.row.status === "completed"
253
263
  };
254
- _v$3 !== _p$.e && (_p$.e = _$setProp(_el$3, "id", _v$3, _p$.e));
255
- _v$4 !== _p$.t && (_p$.t = _$setProp(_el$3, "width", _v$4, _p$.t));
256
- _v$5 !== _p$.a && (_p$.a = _$setProp(_el$7, "style", _v$5, _p$.a));
257
- _v$6 !== _p$.o && (_p$.o = _$setProp(_el$9, "style", _v$6, _p$.o));
258
- _v$7 !== _p$.i && (_p$.i = _$setProp(_el$0, "style", _v$7, _p$.i));
264
+ _v$ !== _p$.e && (_p$.e = _$setProp(_el$3, "id", _v$, _p$.e));
265
+ _v$2 !== _p$.t && (_p$.t = _$setProp(_el$3, "width", _v$2, _p$.t));
266
+ _v$3 !== _p$.a && (_p$.a = _$setProp(_el$7, "style", _v$3, _p$.a));
267
+ _v$4 !== _p$.o && (_p$.o = _$setProp(_el$9, "style", _v$4, _p$.o));
268
+ _v$5 !== _p$.i && (_p$.i = _$setProp(_el$0, "style", _v$5, _p$.i));
259
269
  return _p$;
260
270
  }, {
261
271
  e: undefined,
@@ -287,21 +297,21 @@ export function TodoList(props) {
287
297
  _$insert(_el$13, ERROR_PREFIX, null);
288
298
  _$insert(_el$14, () => entry.row.content);
289
299
  _$effect(_p$ => {
290
- var _v$8 = `${rowId(entry.row.id)}-note`,
291
- _v$9 = ErrorRowWidth({
300
+ var _v$6 = `${rowId(entry.row.id)}-note`,
301
+ _v$7 = ErrorRowWidth({
292
302
  error: entry.row.content,
293
303
  depth: entry.row.depth
294
304
  }),
295
- _v$0 = {
305
+ _v$8 = {
296
306
  fg: props.scrollbarColor
297
307
  },
298
- _v$1 = {
308
+ _v$9 = {
299
309
  fg: entry.row.textColor
300
310
  };
301
- _v$8 !== _p$.e && (_p$.e = _$setProp(_el$11, "id", _v$8, _p$.e));
302
- _v$9 !== _p$.t && (_p$.t = _$setProp(_el$11, "width", _v$9, _p$.t));
303
- _v$0 !== _p$.a && (_p$.a = _$setProp(_el$13, "style", _v$0, _p$.a));
304
- _v$1 !== _p$.o && (_p$.o = _$setProp(_el$14, "style", _v$1, _p$.o));
311
+ _v$6 !== _p$.e && (_p$.e = _$setProp(_el$11, "id", _v$6, _p$.e));
312
+ _v$7 !== _p$.t && (_p$.t = _$setProp(_el$11, "width", _v$7, _p$.t));
313
+ _v$8 !== _p$.a && (_p$.a = _$setProp(_el$13, "style", _v$8, _p$.a));
314
+ _v$9 !== _p$.o && (_p$.o = _$setProp(_el$14, "style", _v$9, _p$.o));
305
315
  return _p$;
306
316
  }, {
307
317
  e: undefined,
@@ -312,16 +322,6 @@ export function TodoList(props) {
312
322
  return _el$11;
313
323
  })()
314
324
  }));
315
- _$effect(_p$ => {
316
- var _v$ = Math.min(entries().length, TODO_PANEL_MAX_ROWS),
317
- _v$2 = scrollbarOptions();
318
- _v$ !== _p$.e && (_p$.e = _$setProp(_el$, "height", _v$, _p$.e));
319
- _v$2 !== _p$.t && (_p$.t = _$setProp(_el$, "verticalScrollbarOptions", _v$2, _p$.t));
320
- return _p$;
321
- }, {
322
- e: undefined,
323
- t: undefined
324
- });
325
325
  return _el$;
326
326
  })();
327
327
  }
@@ -382,9 +382,9 @@ function watchSessionTodos(sessionID, onChange) {
382
382
  });
383
383
  }
384
384
  export function TodoProgress(props) {
385
- const {
386
- context
387
- } = props;
385
+ // `context` is a stable reference for the lifetime of the plugin, so reading
386
+ // it once is safe. Reactive props below are read through accessors instead.
387
+ const context = props.context;
388
388
  const sessionID = () => props.sessionID ?? "";
389
389
  const theme = () => context.theme;
390
390
  const [refresh, setRefresh] = createSignal(0);
@@ -562,7 +562,7 @@ export function TodoProgress(props) {
562
562
  _$setProp(_el$17, "flexGrow", 1);
563
563
  _$setProp(_el$17, "onMouseDown", e => {
564
564
  if (e.button === 0) {
565
- e.stopPropagation?.();
565
+ e.stopPropagation();
566
566
  setIsCollapsed(v => !v);
567
567
  }
568
568
  });
@@ -654,12 +654,12 @@ export function TodoProgress(props) {
654
654
  _$insertNode(_el$25, _$createTextNode(`Continue`));
655
655
  _$setProp(_el$25, "wrapMode", "none");
656
656
  _$effect(_p$ => {
657
- var _v$10 = continueHover.onMouseOver,
658
- _v$11 = continueHover.onMouseOut,
659
- _v$12 = hoverColor(continueHover.hovered(), theme().text.action.primary.base);
660
- _v$10 !== _p$.e && (_p$.e = _$setProp(_el$24, "onMouseOver", _v$10, _p$.e));
661
- _v$11 !== _p$.t && (_p$.t = _$setProp(_el$24, "onMouseOut", _v$11, _p$.t));
662
- _v$12 !== _p$.a && (_p$.a = _$setProp(_el$25, "fg", _v$12, _p$.a));
657
+ var _v$0 = continueHover.onMouseOver,
658
+ _v$1 = continueHover.onMouseOut,
659
+ _v$10 = hoverColor(continueHover.hovered(), theme().text.action.primary.base);
660
+ _v$0 !== _p$.e && (_p$.e = _$setProp(_el$24, "onMouseOver", _v$0, _p$.e));
661
+ _v$1 !== _p$.t && (_p$.t = _$setProp(_el$24, "onMouseOut", _v$1, _p$.t));
662
+ _v$10 !== _p$.a && (_p$.a = _$setProp(_el$25, "fg", _v$10, _p$.a));
663
663
  return _p$;
664
664
  }, {
665
665
  e: undefined,
@@ -708,24 +708,24 @@ export function TodoProgress(props) {
708
708
  }
709
709
  }), null);
710
710
  _$effect(_p$ => {
711
- var _v$13 = theme().border.base,
712
- _v$14 = imageSupported() ? 0 : 1,
713
- _v$15 = {
711
+ var _v$11 = theme().border.base,
712
+ _v$12 = imageSupported() ? 0 : 1,
713
+ _v$13 = {
714
714
  fg: theme().text.base
715
715
  },
716
- _v$16 = {
716
+ _v$14 = {
717
717
  fg: theme().text.muted
718
718
  },
719
- _v$17 = !imageSupported() ? 1.5 : 0,
720
- _v$18 = clearHover.onMouseOver,
721
- _v$19 = clearHover.onMouseOut;
722
- _v$13 !== _p$.e && (_p$.e = _$setProp(_el$15, "borderColor", _v$13, _p$.e));
723
- _v$14 !== _p$.t && (_p$.t = _$setProp(_el$18, "marginLeft", _v$14, _p$.t));
724
- _v$15 !== _p$.a && (_p$.a = _$setProp(_el$21, "style", _v$15, _p$.a));
725
- _v$16 !== _p$.o && (_p$.o = _$setProp(_el$23, "style", _v$16, _p$.o));
726
- _v$17 !== _p$.i && (_p$.i = _$setProp(_el$27, "marginRight", _v$17, _p$.i));
727
- _v$18 !== _p$.n && (_p$.n = _$setProp(_el$27, "onMouseOver", _v$18, _p$.n));
728
- _v$19 !== _p$.s && (_p$.s = _$setProp(_el$27, "onMouseOut", _v$19, _p$.s));
719
+ _v$15 = !imageSupported() ? 1.5 : 0,
720
+ _v$16 = clearHover.onMouseOver,
721
+ _v$17 = clearHover.onMouseOut;
722
+ _v$11 !== _p$.e && (_p$.e = _$setProp(_el$15, "borderColor", _v$11, _p$.e));
723
+ _v$12 !== _p$.t && (_p$.t = _$setProp(_el$18, "marginLeft", _v$12, _p$.t));
724
+ _v$13 !== _p$.a && (_p$.a = _$setProp(_el$21, "style", _v$13, _p$.a));
725
+ _v$14 !== _p$.o && (_p$.o = _$setProp(_el$23, "style", _v$14, _p$.o));
726
+ _v$15 !== _p$.i && (_p$.i = _$setProp(_el$27, "marginRight", _v$15, _p$.i));
727
+ _v$16 !== _p$.n && (_p$.n = _$setProp(_el$27, "onMouseOver", _v$16, _p$.n));
728
+ _v$17 !== _p$.s && (_p$.s = _$setProp(_el$27, "onMouseOut", _v$17, _p$.s));
729
729
  return _p$;
730
730
  }, {
731
731
  e: undefined,
package/dist/tui.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { createComponent as _$createComponent } from "@opentui/solid";
2
2
  import { Plugin } from "@opencode/plugin/tui";
3
3
  import { RendererContext } from "@opentui/solid";
4
- import { TodoProgress } from "./tui/todo-panel";
4
+ import { TodoProgress } from "./tui/todo-panel.js";
5
5
  export default Plugin.define({
6
- id: "opencode.todolist.tui1",
6
+ id: "opencode.todolist.tui",
7
7
  setup(context) {
8
8
  const releaseSlot = context.ui.slot({
9
9
  append: "session.composer.top",
package/index.js CHANGED
@@ -1 +1 @@
1
- export { default } from "./dist/index";
1
+ export { default } from "./dist/index.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gamflaz/opencode-todolist",
3
- "version": "1.0.10",
3
+ "version": "1.0.12",
4
4
  "description": "Hierarchical todo list plugin for OpenCode with a real-time TUI widget.",
5
5
  "type": "module",
6
6
  "files": [
@@ -45,7 +45,8 @@
45
45
  "compile": "bun run build && node scripts/build-jsx.mjs",
46
46
  "build:jsx": "node scripts/build-jsx.mjs",
47
47
  "dev": "tsc-watch -p tsconfig.build.json --onSuccess \"node scripts/build-jsx.mjs\"",
48
- "test": "bun test/todo.test.ts",
48
+ "test": "bun test/icon.test.ts && bun test/skill.test.ts && bun test/skill.folder.test.ts",
49
+ "test:todo": "bun test/todo.test.ts",
49
50
  "typecheck": "tsc --noEmit",
50
51
  "check": "bun run typecheck && bun run test",
51
52
  "update": "git pull && bun run check && bun run compile"
package/tui.js CHANGED
@@ -1 +1 @@
1
- export { default } from "./dist/tui";
1
+ export { default } from "./dist/tui.js";