@gui-chat-plugin/todo 0.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/README.md ADDED
@@ -0,0 +1,94 @@
1
+ # @gui-chat-plugin/todo
2
+
3
+ Todo list plugin for GUI Chat applications. Manage tasks with a persistent todo list that syncs via localStorage.
4
+
5
+ ## Features
6
+
7
+ - Add, update, and delete todo items
8
+ - Mark tasks as completed/uncompleted
9
+ - Clear all completed items at once
10
+ - Persistent storage via localStorage
11
+ - Inline text editing capability
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ yarn add @gui-chat-plugin/todo
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ ### Vue Integration
22
+
23
+ ```typescript
24
+ // In src/tools/index.ts
25
+ import TodoPlugin from "@gui-chat-plugin/todo/vue";
26
+
27
+ const pluginList = [
28
+ // ... other plugins
29
+ TodoPlugin,
30
+ ];
31
+
32
+ // In src/main.ts
33
+ import "@gui-chat-plugin/todo/style.css";
34
+ ```
35
+
36
+ ### Core-only Usage
37
+
38
+ ```typescript
39
+ import { executeTodo, TOOL_DEFINITION } from "@gui-chat-plugin/todo";
40
+
41
+ // Show the todo list
42
+ const result = await executeTodo(context, {
43
+ action: "show",
44
+ });
45
+
46
+ // Add a new item
47
+ const result = await executeTodo(context, {
48
+ action: "add",
49
+ text: "Buy groceries",
50
+ });
51
+ ```
52
+
53
+ ## API
54
+
55
+ ### TodoArgs
56
+
57
+ ```typescript
58
+ interface TodoArgs {
59
+ action: "show" | "add" | "toggle" | "delete" | "clear_completed" | "update";
60
+ text?: string; // For add/update actions
61
+ itemId?: string; // For toggle/delete/update actions
62
+ }
63
+ ```
64
+
65
+ ### TodoItem
66
+
67
+ ```typescript
68
+ interface TodoItem {
69
+ id: string;
70
+ text: string;
71
+ completed: boolean;
72
+ createdAt: number;
73
+ }
74
+ ```
75
+
76
+ ## Development
77
+
78
+ ```bash
79
+ # Install dependencies
80
+ yarn install
81
+
82
+ # Run demo
83
+ yarn dev
84
+
85
+ # Build
86
+ yarn build
87
+
88
+ # Lint
89
+ yarn lint
90
+ ```
91
+
92
+ ## License
93
+
94
+ MIT
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Todo Tool Definition
3
+ */
4
+ import type { ToolDefinition } from "gui-chat-protocol";
5
+ export declare const TOOL_NAME = "manageTodoList";
6
+ export declare const TOOL_DEFINITION: ToolDefinition;
7
+ export declare const SYSTEM_PROMPT = "When users mention tasks they need to do, things to remember, or ask about their todo list, use the manageTodoList function to help them track these items.";
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Todo Plugin - Core (Framework-agnostic)
3
+ */
4
+ export type { TodoToolData, TodoArgs, TodoItem } from "./types";
5
+ export { TOOL_NAME, TOOL_DEFINITION, SYSTEM_PROMPT, executeTodo, pluginCore, } from "./plugin";
6
+ export { samples } from "./samples";
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Todo Plugin Core
3
+ */
4
+ import type { ToolPluginCore, ToolContext, ToolResult } from "gui-chat-protocol";
5
+ import type { TodoToolData, TodoArgs } from "./types";
6
+ export { TOOL_NAME, TOOL_DEFINITION, SYSTEM_PROMPT } from "./definition";
7
+ export declare const executeTodo: (_context: ToolContext, args: TodoArgs) => Promise<ToolResult<TodoToolData, unknown>>;
8
+ export declare const pluginCore: ToolPluginCore<TodoToolData, unknown, TodoArgs>;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Todo Plugin Samples
3
+ */
4
+ import type { ToolSample } from "gui-chat-protocol";
5
+ export declare const samples: ToolSample[];
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Todo Plugin Types
3
+ */
4
+ export interface TodoItem {
5
+ id: string;
6
+ text: string;
7
+ completed: boolean;
8
+ createdAt: number;
9
+ }
10
+ export interface TodoToolData {
11
+ items: TodoItem[];
12
+ }
13
+ export interface TodoArgs {
14
+ action: "show" | "add" | "delete" | "clear_completed" | "update" | "check" | "uncheck";
15
+ text?: string;
16
+ newText?: string;
17
+ }
package/dist/core.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const c="manageTodoList",m={type:"function",name:c,description:"Manage a todo list - show current items, add new items, or delete items. Use this to help users track tasks and remember things.",parameters:{type:"object",properties:{action:{type:"string",enum:["show","add","delete","clear_completed","update","check","uncheck"],description:"Action to perform: 'show' displays the list, 'add' creates a new item, 'delete' removes an item, 'clear_completed' removes all checked items, 'update' modifies an existing item, 'check' marks an item as completed, 'uncheck' marks an item as not completed"},text:{type:"string",description:"For 'add': the todo item text. For 'delete'/'update'/'check'/'uncheck': the text of the item to find (must match exactly). Not required for 'show' or 'clear_completed'"},newText:{type:"string",description:"For 'update' action only: the new text to replace the existing item text"}},required:["action"]}},u=`When users mention tasks they need to do, things to remember, or ask about their todo list, use the ${c} function to help them track these items.`,h="mulmo_todo_list";function g(){try{const n=localStorage.getItem(h);if(n)return JSON.parse(n)}catch(n){console.error("Error loading todos:",n)}return[]}function r(n){try{localStorage.setItem(h,JSON.stringify(n))}catch(d){console.error("Error saving todos:",d)}}const p=async(n,d)=>{const{action:l,text:o,newText:i}=d;try{const t=g();switch(l){case"show":return{message:`Todo list displayed with ${t.length} item${t.length!==1?"s":""}`,data:{items:t},jsonData:{totalItems:t.length,completed:t.filter(e=>e.completed).length,pending:t.filter(e=>!e.completed).length,items:t.map(e=>({text:e.text,completed:e.completed}))},instructions:"The todo list has been displayed. Acknowledge the current state of the list to the user.",updating:!0};case"add":{if(!o||typeof o!="string"||o.trim()==="")return{message:"Cannot add todo: text is required",data:{items:t},instructions:"Tell the user that a todo item text is required to add an item.",updating:!0};const e={id:`todo_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,text:o.trim(),completed:!1,createdAt:Date.now()};return t.push(e),r(t),{message:`Added todo: "${e.text}"`,data:{items:t},jsonData:{added:e.text,totalItems:t.length},instructions:`Confirm to the user that "${e.text}" has been added to their todo list.`,updating:!0}}case"delete":{if(!o||typeof o!="string")return{message:"Cannot delete todo: text is required",data:{items:t},instructions:"Tell the user which todo item they want to delete. List the current items if needed.",updating:!0};const e=t.findIndex(s=>s.text.toLowerCase()===o.toLowerCase());if(e===-1)return{message:`Todo item not found: "${o}"`,data:{items:t},jsonData:{availableItems:t.map(s=>s.text)},instructions:`Tell the user that "${o}" was not found in the todo list. Show them the current items if helpful.`,updating:!0};const a=t[e];return t.splice(e,1),r(t),{message:`Deleted todo: "${a.text}"`,data:{items:t},jsonData:{deleted:a.text,totalItems:t.length},instructions:`Confirm to the user that "${a.text}" has been removed from their todo list.`,updating:!0}}case"clear_completed":{const e=t.filter(s=>s.completed),a=t.filter(s=>!s.completed);return e.length===0?{message:"No completed items to clear",data:{items:t},jsonData:{totalItems:t.length},instructions:"Tell the user that there are no completed items to clear.",updating:!0}:(r(a),{message:`Cleared ${e.length} completed item${e.length!==1?"s":""}`,data:{items:a},jsonData:{clearedCount:e.length,totalItems:a.length},instructions:`Confirm to the user that ${e.length} completed item${e.length!==1?"s have":" has"} been removed from their todo list.`,updating:!0})}case"update":{if(!o||typeof o!="string")return{message:"Cannot update todo: text is required to identify the item",data:{items:t},instructions:"Tell the user which todo item they want to update.",updating:!0};if(!i||typeof i!="string"||i.trim()==="")return{message:"Cannot update todo: newText is required",data:{items:t},instructions:"Tell the user what the new text should be for the todo item.",updating:!0};const e=t.find(s=>s.text.toLowerCase()===o.toLowerCase());if(!e)return{message:`Todo item not found: "${o}"`,data:{items:t},jsonData:{availableItems:t.map(s=>s.text)},instructions:`Tell the user that "${o}" was not found in the todo list. Show them the current items if helpful.`,updating:!0};const a=e.text;return e.text=i.trim(),r(t),{message:`Updated todo from "${a}" to "${e.text}"`,data:{items:t},jsonData:{oldText:a,newText:e.text,totalItems:t.length},instructions:`Confirm to the user that the todo item has been updated from "${a}" to "${e.text}".`,updating:!0}}case"check":{if(!o||typeof o!="string")return{message:"Cannot check todo: text is required to identify the item",data:{items:t},instructions:"Tell the user which todo item they want to mark as completed.",updating:!0};const e=t.find(a=>a.text.toLowerCase()===o.toLowerCase());return e?e.completed?{message:`Todo item "${e.text}" is already completed`,data:{items:t},instructions:`Tell the user that "${e.text}" is already marked as completed.`,updating:!0}:(e.completed=!0,r(t),{message:`Checked todo: "${e.text}"`,data:{items:t},jsonData:{checkedItem:e.text,totalItems:t.length,completedItems:t.filter(a=>a.completed).length},instructions:`Confirm to the user that "${e.text}" has been marked as completed.`,updating:!0}):{message:`Todo item not found: "${o}"`,data:{items:t},jsonData:{availableItems:t.map(a=>a.text)},instructions:`Tell the user that "${o}" was not found in the todo list. Show them the current items if helpful.`,updating:!0}}case"uncheck":{if(!o||typeof o!="string")return{message:"Cannot uncheck todo: text is required to identify the item",data:{items:t},instructions:"Tell the user which todo item they want to mark as not completed.",updating:!0};const e=t.find(a=>a.text.toLowerCase()===o.toLowerCase());return e?e.completed?(e.completed=!1,r(t),{message:`Unchecked todo: "${e.text}"`,data:{items:t},jsonData:{uncheckedItem:e.text,totalItems:t.length,completedItems:t.filter(a=>a.completed).length},instructions:`Confirm to the user that "${e.text}" has been marked as not completed.`,updating:!0}):{message:`Todo item "${e.text}" is already not completed`,data:{items:t},instructions:`Tell the user that "${e.text}" is already marked as not completed.`,updating:!0}:{message:`Todo item not found: "${o}"`,data:{items:t},jsonData:{availableItems:t.map(a=>a.text)},instructions:`Tell the user that "${o}" was not found in the todo list. Show them the current items if helpful.`,updating:!0}}default:return{message:`Unknown action: ${l}`,data:{items:t},instructions:"Tell the user that the action was not recognized. Valid actions are: show, add, delete, clear_completed, update, check, uncheck.",updating:!0}}}catch(t){return console.error("ERR: exception in manageTodoList",t),{message:`Todo list error: ${t instanceof Error?t.message:"Unknown error"}`,data:{items:[]},instructions:"Acknowledge that there was an error managing the todo list."}}},f={toolDefinition:m,execute:p,generatingMessage:"Managing todo list...",isEnabled:()=>!0,systemPrompt:u},x=[{name:"Show List",args:{action:"show"}},{name:"Add Item",args:{action:"add",text:"Buy groceries"}},{name:"Check Item",args:{action:"check",text:"Buy groceries"}}];exports.SYSTEM_PROMPT=u;exports.TOOL_DEFINITION=m;exports.TOOL_NAME=c;exports.executeTodo=p;exports.pluginCore=f;exports.samples=x;
package/dist/core.js ADDED
@@ -0,0 +1,313 @@
1
+ const m = "manageTodoList", u = {
2
+ type: "function",
3
+ name: m,
4
+ description: "Manage a todo list - show current items, add new items, or delete items. Use this to help users track tasks and remember things.",
5
+ parameters: {
6
+ type: "object",
7
+ properties: {
8
+ action: {
9
+ type: "string",
10
+ enum: [
11
+ "show",
12
+ "add",
13
+ "delete",
14
+ "clear_completed",
15
+ "update",
16
+ "check",
17
+ "uncheck"
18
+ ],
19
+ description: "Action to perform: 'show' displays the list, 'add' creates a new item, 'delete' removes an item, 'clear_completed' removes all checked items, 'update' modifies an existing item, 'check' marks an item as completed, 'uncheck' marks an item as not completed"
20
+ },
21
+ text: {
22
+ type: "string",
23
+ description: "For 'add': the todo item text. For 'delete'/'update'/'check'/'uncheck': the text of the item to find (must match exactly). Not required for 'show' or 'clear_completed'"
24
+ },
25
+ newText: {
26
+ type: "string",
27
+ description: "For 'update' action only: the new text to replace the existing item text"
28
+ }
29
+ },
30
+ required: ["action"]
31
+ }
32
+ }, h = `When users mention tasks they need to do, things to remember, or ask about their todo list, use the ${m} function to help them track these items.`, l = "mulmo_todo_list";
33
+ function p() {
34
+ try {
35
+ const n = localStorage.getItem(l);
36
+ if (n)
37
+ return JSON.parse(n);
38
+ } catch (n) {
39
+ console.error("Error loading todos:", n);
40
+ }
41
+ return [];
42
+ }
43
+ function r(n) {
44
+ try {
45
+ localStorage.setItem(l, JSON.stringify(n));
46
+ } catch (d) {
47
+ console.error("Error saving todos:", d);
48
+ }
49
+ }
50
+ const g = async (n, d) => {
51
+ const { action: c, text: o, newText: i } = d;
52
+ try {
53
+ const t = p();
54
+ switch (c) {
55
+ case "show":
56
+ return {
57
+ message: `Todo list displayed with ${t.length} item${t.length !== 1 ? "s" : ""}`,
58
+ data: { items: t },
59
+ jsonData: {
60
+ totalItems: t.length,
61
+ completed: t.filter((e) => e.completed).length,
62
+ pending: t.filter((e) => !e.completed).length,
63
+ items: t.map((e) => ({
64
+ text: e.text,
65
+ completed: e.completed
66
+ }))
67
+ },
68
+ instructions: "The todo list has been displayed. Acknowledge the current state of the list to the user.",
69
+ updating: !0
70
+ };
71
+ case "add": {
72
+ if (!o || typeof o != "string" || o.trim() === "")
73
+ return {
74
+ message: "Cannot add todo: text is required",
75
+ data: { items: t },
76
+ instructions: "Tell the user that a todo item text is required to add an item.",
77
+ updating: !0
78
+ };
79
+ const e = {
80
+ id: `todo_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
81
+ text: o.trim(),
82
+ completed: !1,
83
+ createdAt: Date.now()
84
+ };
85
+ return t.push(e), r(t), {
86
+ message: `Added todo: "${e.text}"`,
87
+ data: { items: t },
88
+ jsonData: {
89
+ added: e.text,
90
+ totalItems: t.length
91
+ },
92
+ instructions: `Confirm to the user that "${e.text}" has been added to their todo list.`,
93
+ updating: !0
94
+ };
95
+ }
96
+ case "delete": {
97
+ if (!o || typeof o != "string")
98
+ return {
99
+ message: "Cannot delete todo: text is required",
100
+ data: { items: t },
101
+ instructions: "Tell the user which todo item they want to delete. List the current items if needed.",
102
+ updating: !0
103
+ };
104
+ const e = t.findIndex(
105
+ (s) => s.text.toLowerCase() === o.toLowerCase()
106
+ );
107
+ if (e === -1)
108
+ return {
109
+ message: `Todo item not found: "${o}"`,
110
+ data: { items: t },
111
+ jsonData: {
112
+ availableItems: t.map((s) => s.text)
113
+ },
114
+ instructions: `Tell the user that "${o}" was not found in the todo list. Show them the current items if helpful.`,
115
+ updating: !0
116
+ };
117
+ const a = t[e];
118
+ return t.splice(e, 1), r(t), {
119
+ message: `Deleted todo: "${a.text}"`,
120
+ data: { items: t },
121
+ jsonData: {
122
+ deleted: a.text,
123
+ totalItems: t.length
124
+ },
125
+ instructions: `Confirm to the user that "${a.text}" has been removed from their todo list.`,
126
+ updating: !0
127
+ };
128
+ }
129
+ case "clear_completed": {
130
+ const e = t.filter((s) => s.completed), a = t.filter((s) => !s.completed);
131
+ return e.length === 0 ? {
132
+ message: "No completed items to clear",
133
+ data: { items: t },
134
+ jsonData: {
135
+ totalItems: t.length
136
+ },
137
+ instructions: "Tell the user that there are no completed items to clear.",
138
+ updating: !0
139
+ } : (r(a), {
140
+ message: `Cleared ${e.length} completed item${e.length !== 1 ? "s" : ""}`,
141
+ data: { items: a },
142
+ jsonData: {
143
+ clearedCount: e.length,
144
+ totalItems: a.length
145
+ },
146
+ instructions: `Confirm to the user that ${e.length} completed item${e.length !== 1 ? "s have" : " has"} been removed from their todo list.`,
147
+ updating: !0
148
+ });
149
+ }
150
+ case "update": {
151
+ if (!o || typeof o != "string")
152
+ return {
153
+ message: "Cannot update todo: text is required to identify the item",
154
+ data: { items: t },
155
+ instructions: "Tell the user which todo item they want to update.",
156
+ updating: !0
157
+ };
158
+ if (!i || typeof i != "string" || i.trim() === "")
159
+ return {
160
+ message: "Cannot update todo: newText is required",
161
+ data: { items: t },
162
+ instructions: "Tell the user what the new text should be for the todo item.",
163
+ updating: !0
164
+ };
165
+ const e = t.find(
166
+ (s) => s.text.toLowerCase() === o.toLowerCase()
167
+ );
168
+ if (!e)
169
+ return {
170
+ message: `Todo item not found: "${o}"`,
171
+ data: { items: t },
172
+ jsonData: {
173
+ availableItems: t.map((s) => s.text)
174
+ },
175
+ instructions: `Tell the user that "${o}" was not found in the todo list. Show them the current items if helpful.`,
176
+ updating: !0
177
+ };
178
+ const a = e.text;
179
+ return e.text = i.trim(), r(t), {
180
+ message: `Updated todo from "${a}" to "${e.text}"`,
181
+ data: { items: t },
182
+ jsonData: {
183
+ oldText: a,
184
+ newText: e.text,
185
+ totalItems: t.length
186
+ },
187
+ instructions: `Confirm to the user that the todo item has been updated from "${a}" to "${e.text}".`,
188
+ updating: !0
189
+ };
190
+ }
191
+ case "check": {
192
+ if (!o || typeof o != "string")
193
+ return {
194
+ message: "Cannot check todo: text is required to identify the item",
195
+ data: { items: t },
196
+ instructions: "Tell the user which todo item they want to mark as completed.",
197
+ updating: !0
198
+ };
199
+ const e = t.find(
200
+ (a) => a.text.toLowerCase() === o.toLowerCase()
201
+ );
202
+ return e ? e.completed ? {
203
+ message: `Todo item "${e.text}" is already completed`,
204
+ data: { items: t },
205
+ instructions: `Tell the user that "${e.text}" is already marked as completed.`,
206
+ updating: !0
207
+ } : (e.completed = !0, r(t), {
208
+ message: `Checked todo: "${e.text}"`,
209
+ data: { items: t },
210
+ jsonData: {
211
+ checkedItem: e.text,
212
+ totalItems: t.length,
213
+ completedItems: t.filter((a) => a.completed).length
214
+ },
215
+ instructions: `Confirm to the user that "${e.text}" has been marked as completed.`,
216
+ updating: !0
217
+ }) : {
218
+ message: `Todo item not found: "${o}"`,
219
+ data: { items: t },
220
+ jsonData: {
221
+ availableItems: t.map((a) => a.text)
222
+ },
223
+ instructions: `Tell the user that "${o}" was not found in the todo list. Show them the current items if helpful.`,
224
+ updating: !0
225
+ };
226
+ }
227
+ case "uncheck": {
228
+ if (!o || typeof o != "string")
229
+ return {
230
+ message: "Cannot uncheck todo: text is required to identify the item",
231
+ data: { items: t },
232
+ instructions: "Tell the user which todo item they want to mark as not completed.",
233
+ updating: !0
234
+ };
235
+ const e = t.find(
236
+ (a) => a.text.toLowerCase() === o.toLowerCase()
237
+ );
238
+ return e ? e.completed ? (e.completed = !1, r(t), {
239
+ message: `Unchecked todo: "${e.text}"`,
240
+ data: { items: t },
241
+ jsonData: {
242
+ uncheckedItem: e.text,
243
+ totalItems: t.length,
244
+ completedItems: t.filter((a) => a.completed).length
245
+ },
246
+ instructions: `Confirm to the user that "${e.text}" has been marked as not completed.`,
247
+ updating: !0
248
+ }) : {
249
+ message: `Todo item "${e.text}" is already not completed`,
250
+ data: { items: t },
251
+ instructions: `Tell the user that "${e.text}" is already marked as not completed.`,
252
+ updating: !0
253
+ } : {
254
+ message: `Todo item not found: "${o}"`,
255
+ data: { items: t },
256
+ jsonData: {
257
+ availableItems: t.map((a) => a.text)
258
+ },
259
+ instructions: `Tell the user that "${o}" was not found in the todo list. Show them the current items if helpful.`,
260
+ updating: !0
261
+ };
262
+ }
263
+ default:
264
+ return {
265
+ message: `Unknown action: ${c}`,
266
+ data: { items: t },
267
+ instructions: "Tell the user that the action was not recognized. Valid actions are: show, add, delete, clear_completed, update, check, uncheck.",
268
+ updating: !0
269
+ };
270
+ }
271
+ } catch (t) {
272
+ return console.error("ERR: exception in manageTodoList", t), {
273
+ message: `Todo list error: ${t instanceof Error ? t.message : "Unknown error"}`,
274
+ data: { items: [] },
275
+ instructions: "Acknowledge that there was an error managing the todo list."
276
+ };
277
+ }
278
+ }, f = {
279
+ toolDefinition: u,
280
+ execute: g,
281
+ generatingMessage: "Managing todo list...",
282
+ isEnabled: () => !0,
283
+ systemPrompt: h
284
+ }, x = [
285
+ {
286
+ name: "Show List",
287
+ args: {
288
+ action: "show"
289
+ }
290
+ },
291
+ {
292
+ name: "Add Item",
293
+ args: {
294
+ action: "add",
295
+ text: "Buy groceries"
296
+ }
297
+ },
298
+ {
299
+ name: "Check Item",
300
+ args: {
301
+ action: "check",
302
+ text: "Buy groceries"
303
+ }
304
+ }
305
+ ];
306
+ export {
307
+ h as SYSTEM_PROMPT,
308
+ u as TOOL_DEFINITION,
309
+ m as TOOL_NAME,
310
+ g as executeTodo,
311
+ f as pluginCore,
312
+ x as samples
313
+ };
package/dist/index.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./core.cjs");exports.SYSTEM_PROMPT=e.SYSTEM_PROMPT;exports.TOOL_DEFINITION=e.TOOL_DEFINITION;exports.TOOL_NAME=e.TOOL_NAME;exports.executeTodo=e.executeTodo;exports.pluginCore=e.pluginCore;exports.samples=e.samples;
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Todo Plugin
3
+ */
4
+ export * from "./core";
package/dist/index.js ADDED
@@ -0,0 +1,9 @@
1
+ import { SYSTEM_PROMPT as T, TOOL_DEFINITION as o, TOOL_NAME as p, executeTodo as r, pluginCore as E, samples as I } from "./core.js";
2
+ export {
3
+ T as SYSTEM_PROMPT,
4
+ o as TOOL_DEFINITION,
5
+ p as TOOL_NAME,
6
+ r as executeTodo,
7
+ E as pluginCore,
8
+ I as samples
9
+ };
package/dist/style.css ADDED
@@ -0,0 +1 @@
1
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-space-y-reverse:0;--tw-border-style:solid;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-red-700:oklch(50.5% .213 27.518);--color-green-500:oklch(72.3% .219 149.579);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-indigo-100:oklch(93% .034 272.788);--color-indigo-200:oklch(87% .065 274.039);--color-indigo-700:oklch(45.7% .24 277.023);--color-gray-50:oklch(98.5% .002 247.839);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-500:oklch(55.1% .027 264.364);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-800:oklch(27.8% .033 256.848);--color-white:#fff;--spacing:.25rem;--container-2xl:42rem;--container-3xl:48rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75/1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2/1.5);--font-weight-medium:500;--font-weight-bold:700;--radius-md:.375rem;--radius-lg:.5rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.mx-auto{margin-inline:auto}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-6{margin-top:calc(var(--spacing)*6)}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.mb-5{margin-bottom:calc(var(--spacing)*5)}.mb-6{margin-bottom:calc(var(--spacing)*6)}.mb-8{margin-bottom:calc(var(--spacing)*8)}.contents{display:contents}.flex{display:flex}.h-4{height:calc(var(--spacing)*4)}.h-5{height:calc(var(--spacing)*5)}.h-96{height:calc(var(--spacing)*96)}.h-full{height:100%}.max-h-20{max-height:calc(var(--spacing)*20)}.w-4{width:calc(var(--spacing)*4)}.w-5{width:calc(var(--spacing)*5)}.w-full{width:100%}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-\[200px\]{max-width:200px}.min-w-0{min-width:calc(var(--spacing)*0)}.flex-1{flex:1}.cursor-pointer{cursor:pointer}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.gap-1{gap:calc(var(--spacing)*1)}.gap-2{gap:calc(var(--spacing)*2)}.gap-3{gap:calc(var(--spacing)*3)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-gray-200{border-color:var(--color-gray-200)}.border-gray-300{border-color:var(--color-gray-300)}.border-indigo-200{border-color:var(--color-indigo-200)}.bg-gray-50{background-color:var(--color-gray-50)}.bg-gray-100{background-color:var(--color-gray-100)}.bg-indigo-100{background-color:var(--color-indigo-100)}.bg-white{background-color:var(--color-white)}.p-1{padding:calc(var(--spacing)*1)}.p-2{padding:calc(var(--spacing)*2)}.p-4{padding:calc(var(--spacing)*4)}.p-5{padding:calc(var(--spacing)*5)}.p-6{padding:calc(var(--spacing)*6)}.p-8{padding:calc(var(--spacing)*8)}.px-4{padding-inline:calc(var(--spacing)*4)}.py-2{padding-block:calc(var(--spacing)*2)}.py-12{padding-block:calc(var(--spacing)*12)}.pt-4{padding-top:calc(var(--spacing)*4)}.text-center{text-align:center}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.break-words{overflow-wrap:break-word}.text-blue-600{color:var(--color-blue-600)}.text-gray-400{color:var(--color-gray-400)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-gray-700{color:var(--color-gray-700)}.text-gray-800{color:var(--color-gray-800)}.text-green-500{color:var(--color-green-500)}.text-indigo-700{color:var(--color-indigo-700)}.text-red-500{color:var(--color-red-500)}.text-white{color:var(--color-white)}.italic{font-style:italic}.line-through{text-decoration-line:line-through}.opacity-0{opacity:0}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}@media(hover:hover){.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}.hover\:bg-gray-200:hover{background-color:var(--color-gray-200)}.hover\:bg-indigo-200:hover{background-color:var(--color-indigo-200)}.hover\:text-red-600:hover{color:var(--color-red-600)}.hover\:text-red-700:hover{color:var(--color-red-700)}}.focus\:ring-blue-500:focus{--tw-ring-color:var(--color-blue-500)}.focus\:ring-offset-0:focus{--tw-ring-offset-width:0px;--tw-ring-offset-shadow:var(--tw-ring-inset,)0 0 0 var(--tw-ring-offset-width)var(--tw-ring-offset-color)}@media(prefers-color-scheme:dark){.dark\:bg-gray-800{background-color:var(--color-gray-800)}.dark\:text-blue-400{color:var(--color-blue-400)}.dark\:text-gray-300{color:var(--color-gray-300)}.dark\:text-gray-400{color:var(--color-gray-400)}}}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}
@@ -0,0 +1,8 @@
1
+ import type { ToolResult } from "gui-chat-protocol";
2
+ import type { TodoToolData } from "../core/types";
3
+ type __VLS_Props = {
4
+ result: ToolResult<TodoToolData>;
5
+ };
6
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
7
+ declare const _default: typeof __VLS_export;
8
+ export default _default;
@@ -0,0 +1,8 @@
1
+ import type { ToolResult } from "gui-chat-protocol";
2
+ import type { TodoToolData } from "../core/types";
3
+ type __VLS_Props = {
4
+ selectedResult: ToolResult<TodoToolData>;
5
+ };
6
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
7
+ declare const _default: typeof __VLS_export;
8
+ export default _default;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Todo Plugin - Vue Implementation
3
+ */
4
+ import "../style.css";
5
+ import type { ToolPlugin } from "gui-chat-protocol/vue";
6
+ import type { TodoToolData, TodoArgs } from "../core/types";
7
+ import View from "./View.vue";
8
+ import Preview from "./Preview.vue";
9
+ export declare const plugin: ToolPlugin<TodoToolData, unknown, TodoArgs>;
10
+ export type { TodoToolData, TodoArgs, TodoItem } from "../core/types";
11
+ export { TOOL_NAME, TOOL_DEFINITION, SYSTEM_PROMPT, executeTodo, pluginCore, } from "../core/plugin";
12
+ export { samples } from "../core/samples";
13
+ export { View, Preview };
14
+ declare const _default: {
15
+ plugin: ToolPlugin<TodoToolData, unknown, TodoArgs, import("gui-chat-protocol/vue").InputHandler, Record<string, unknown>>;
16
+ };
17
+ export default _default;
package/dist/vue.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const a=require("./core.cjs"),e=require("vue"),E={class:"w-full h-full overflow-y-auto bg-white"},w={class:"max-w-2xl mx-auto p-6"},N={class:"mb-6"},B={class:"text-sm text-gray-600"},V={key:0,class:"text-center py-12"},C={key:1,class:"space-y-2"},b=["checked","onChange"],S={class:"flex-1 min-w-0"},T={class:"text-xs text-gray-500 mt-1"},$=["onClick"],M={key:2,class:"mt-6 pt-4 border-t border-gray-200"},D="mulmo_todo_list",x=e.defineComponent({__name:"View",props:{selectedResult:{}},setup(p){const i=p,t=e.ref([...i.selectedResult.data?.items||[]]);e.watch(()=>i.selectedResult.data?.items,l=>{l&&(t.value=[...l])},{deep:!0});const g=e.computed(()=>t.value.length),d=e.computed(()=>t.value.filter(l=>l.completed).length);function n(l){try{localStorage.setItem(D,JSON.stringify(l))}catch(o){console.error("Error saving todos:",o)}}function u(l){const o=t.value.find(s=>s.id===l);o&&(o.completed=!o.completed,n(t.value))}function r(l){t.value=t.value.filter(o=>o.id!==l),n(t.value)}function y(){t.value=t.value.filter(l=>!l.completed),n(t.value)}function k(l){const o=new Date(l),c=new Date().getTime()-o.getTime(),m=Math.floor(c/6e4),v=Math.floor(c/36e5),h=Math.floor(c/864e5);return m<1?"just now":m<60?`${m} min${m!==1?"s":""} ago`:v<24?`${v} hour${v!==1?"s":""} ago`:h<7?`${h} day${h!==1?"s":""} ago`:o.toLocaleDateString()}return(l,o)=>(e.openBlock(),e.createElementBlock("div",E,[e.createElementVNode("div",w,[e.createElementVNode("div",N,[o[0]||(o[0]=e.createElementVNode("h2",{class:"text-2xl font-bold text-gray-800 mb-2"},"Todo List",-1)),e.createElementVNode("div",B,[e.createElementVNode("span",null,e.toDisplayString(d.value)+" of "+e.toDisplayString(g.value)+" completed",1)])]),t.value.length===0?(e.openBlock(),e.createElementBlock("div",V,[...o[1]||(o[1]=[e.createElementVNode("div",{class:"text-gray-400 text-lg"},"No todo items yet",-1),e.createElementVNode("div",{class:"text-gray-500 text-sm mt-2"}," Ask the assistant to add some tasks! ",-1)])])):(e.openBlock(),e.createElementBlock("div",C,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(t.value,s=>(e.openBlock(),e.createElementBlock("div",{key:s.id,class:"group flex items-start gap-3 p-4 bg-gray-100 rounded-lg hover:bg-gray-200 transition-colors"},[e.createElementVNode("input",{type:"checkbox",checked:s.completed,onChange:c=>u(s.id),class:"mt-1 h-5 w-5 rounded border-gray-300 text-blue-600 focus:ring-blue-500 focus:ring-offset-0 cursor-pointer"},null,40,b),e.createElementVNode("div",S,[e.createElementVNode("p",{class:e.normalizeClass(["break-words",s.completed?"line-through text-gray-500":"text-gray-800"])},e.toDisplayString(s.text),3),e.createElementVNode("p",T,e.toDisplayString(k(s.createdAt)),1)]),e.createElementVNode("button",{onClick:c=>r(s.id),class:"opacity-0 group-hover:opacity-100 text-red-500 hover:text-red-700 transition-opacity p-1",title:"Delete item"},[...o[2]||(o[2]=[e.createElementVNode("svg",{xmlns:"http://www.w3.org/2000/svg",class:"h-5 w-5",viewBox:"0 0 20 20",fill:"currentColor"},[e.createElementVNode("path",{"fill-rule":"evenodd",d:"M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z","clip-rule":"evenodd"})],-1)])],8,$)]))),128))])),d.value>0?(e.openBlock(),e.createElementBlock("div",M,[e.createElementVNode("button",{onClick:y,class:"text-sm text-gray-600 hover:text-red-600 transition-colors"}," Clear completed items ")])):e.createCommentVNode("",!0)])]))}}),O={class:"p-2 bg-gray-50 dark:bg-gray-800 rounded"},z={class:"text-xs text-gray-600 dark:text-gray-400"},L={key:0},I={key:1},H={class:"mb-1"},P={class:"space-y-1 max-h-20 overflow-y-auto"},A={key:0,class:"text-green-500"},R={key:1,class:"text-gray-400"},F={key:0,class:"text-gray-500 italic"},f=e.defineComponent({__name:"Preview",props:{result:{}},setup(p){const i=p,t=e.computed(()=>i.result.data?.items||[]),g=e.computed(()=>t.value.length),d=e.computed(()=>t.value.filter(n=>n.completed).length);return(n,u)=>(e.openBlock(),e.createElementBlock("div",O,[u[0]||(u[0]=e.createStaticVNode('<div class="flex items-center gap-2 mb-2"><svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 text-blue-600 dark:text-blue-400" viewBox="0 0 20 20" fill="currentColor"><path d="M9 2a1 1 0 000 2h2a1 1 0 100-2H9z"></path><path fill-rule="evenodd" d="M4 5a2 2 0 012-2 3 3 0 003 3h2a3 3 0 003-3 2 2 0 012 2v11a2 2 0 01-2 2H6a2 2 0 01-2-2V5zm3 4a1 1 0 000 2h.01a1 1 0 100-2H7zm3 0a1 1 0 000 2h3a1 1 0 100-2h-3zm-3 4a1 1 0 100 2h.01a1 1 0 100-2H7zm3 0a1 1 0 100 2h3a1 1 0 100-2h-3z" clip-rule="evenodd"></path></svg><span class="text-sm font-medium text-gray-700 dark:text-gray-300"> Todo List </span></div>',1)),e.createElementVNode("div",z,[t.value.length===0?(e.openBlock(),e.createElementBlock("div",L,"No items")):(e.openBlock(),e.createElementBlock("div",I,[e.createElementVNode("div",H,e.toDisplayString(d.value)+"/"+e.toDisplayString(g.value)+" completed",1),e.createElementVNode("div",P,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(t.value.slice(0,3),r=>(e.openBlock(),e.createElementBlock("div",{key:r.id,class:"flex items-start gap-1 text-xs"},[r.completed?(e.openBlock(),e.createElementBlock("span",A,"✓")):(e.openBlock(),e.createElementBlock("span",R,"○")),e.createElementVNode("span",{class:e.normalizeClass(["flex-1 truncate",r.completed?"line-through text-gray-500":"text-white"])},e.toDisplayString(r.text),3)]))),128)),t.value.length>3?(e.openBlock(),e.createElementBlock("div",F," +"+e.toDisplayString(t.value.length-3)+" more... ",1)):e.createCommentVNode("",!0)])]))])]))}}),_={...a.pluginCore,viewComponent:x,previewComponent:f,samples:a.samples},Y={plugin:_};exports.SYSTEM_PROMPT=a.SYSTEM_PROMPT;exports.TOOL_DEFINITION=a.TOOL_DEFINITION;exports.TOOL_NAME=a.TOOL_NAME;exports.executeTodo=a.executeTodo;exports.pluginCore=a.pluginCore;exports.samples=a.samples;exports.Preview=f;exports.View=x;exports.default=Y;exports.plugin=_;
package/dist/vue.js ADDED
@@ -0,0 +1,170 @@
1
+ import { samples as T, pluginCore as z } from "./core.js";
2
+ import { SYSTEM_PROMPT as rt, TOOL_DEFINITION as it, TOOL_NAME as ct, executeTodo as dt } from "./core.js";
3
+ import { defineComponent as y, ref as N, watch as V, computed as u, createElementBlock as a, openBlock as l, createElementVNode as e, createCommentVNode as w, toDisplayString as r, Fragment as k, renderList as b, normalizeClass as C, createStaticVNode as D } from "vue";
4
+ const E = { class: "w-full h-full overflow-y-auto bg-white" }, O = { class: "max-w-2xl mx-auto p-6" }, S = { class: "mb-6" }, H = { class: "text-sm text-gray-600" }, L = {
5
+ key: 0,
6
+ class: "text-center py-12"
7
+ }, A = {
8
+ key: 1,
9
+ class: "space-y-2"
10
+ }, I = ["checked", "onChange"], R = { class: "flex-1 min-w-0" }, B = { class: "text-xs text-gray-500 mt-1" }, P = ["onClick"], F = {
11
+ key: 2,
12
+ class: "mt-6 pt-4 border-t border-gray-200"
13
+ }, Y = "mulmo_todo_list", j = /* @__PURE__ */ y({
14
+ __name: "View",
15
+ props: {
16
+ selectedResult: {}
17
+ },
18
+ setup(h) {
19
+ const p = h, t = N([...p.selectedResult.data?.items || []]);
20
+ V(
21
+ () => p.selectedResult.data?.items,
22
+ (s) => {
23
+ s && (t.value = [...s]);
24
+ },
25
+ { deep: !0 }
26
+ );
27
+ const x = u(() => t.value.length), m = u(
28
+ () => t.value.filter((s) => s.completed).length
29
+ );
30
+ function i(s) {
31
+ try {
32
+ localStorage.setItem(Y, JSON.stringify(s));
33
+ } catch (o) {
34
+ console.error("Error saving todos:", o);
35
+ }
36
+ }
37
+ function v(s) {
38
+ const o = t.value.find((n) => n.id === s);
39
+ o && (o.completed = !o.completed, i(t.value));
40
+ }
41
+ function c(s) {
42
+ t.value = t.value.filter((o) => o.id !== s), i(t.value);
43
+ }
44
+ function $() {
45
+ t.value = t.value.filter((s) => !s.completed), i(t.value);
46
+ }
47
+ function M(s) {
48
+ const o = new Date(s), d = (/* @__PURE__ */ new Date()).getTime() - o.getTime(), g = Math.floor(d / 6e4), f = Math.floor(d / 36e5), _ = Math.floor(d / 864e5);
49
+ return g < 1 ? "just now" : g < 60 ? `${g} min${g !== 1 ? "s" : ""} ago` : f < 24 ? `${f} hour${f !== 1 ? "s" : ""} ago` : _ < 7 ? `${_} day${_ !== 1 ? "s" : ""} ago` : o.toLocaleDateString();
50
+ }
51
+ return (s, o) => (l(), a("div", E, [
52
+ e("div", O, [
53
+ e("div", S, [
54
+ o[0] || (o[0] = e("h2", { class: "text-2xl font-bold text-gray-800 mb-2" }, "Todo List", -1)),
55
+ e("div", H, [
56
+ e("span", null, r(m.value) + " of " + r(x.value) + " completed", 1)
57
+ ])
58
+ ]),
59
+ t.value.length === 0 ? (l(), a("div", L, [...o[1] || (o[1] = [
60
+ e("div", { class: "text-gray-400 text-lg" }, "No todo items yet", -1),
61
+ e("div", { class: "text-gray-500 text-sm mt-2" }, " Ask the assistant to add some tasks! ", -1)
62
+ ])])) : (l(), a("div", A, [
63
+ (l(!0), a(k, null, b(t.value, (n) => (l(), a("div", {
64
+ key: n.id,
65
+ class: "group flex items-start gap-3 p-4 bg-gray-100 rounded-lg hover:bg-gray-200 transition-colors"
66
+ }, [
67
+ e("input", {
68
+ type: "checkbox",
69
+ checked: n.completed,
70
+ onChange: (d) => v(n.id),
71
+ class: "mt-1 h-5 w-5 rounded border-gray-300 text-blue-600 focus:ring-blue-500 focus:ring-offset-0 cursor-pointer"
72
+ }, null, 40, I),
73
+ e("div", R, [
74
+ e("p", {
75
+ class: C([
76
+ "break-words",
77
+ n.completed ? "line-through text-gray-500" : "text-gray-800"
78
+ ])
79
+ }, r(n.text), 3),
80
+ e("p", B, r(M(n.createdAt)), 1)
81
+ ]),
82
+ e("button", {
83
+ onClick: (d) => c(n.id),
84
+ class: "opacity-0 group-hover:opacity-100 text-red-500 hover:text-red-700 transition-opacity p-1",
85
+ title: "Delete item"
86
+ }, [...o[2] || (o[2] = [
87
+ e("svg", {
88
+ xmlns: "http://www.w3.org/2000/svg",
89
+ class: "h-5 w-5",
90
+ viewBox: "0 0 20 20",
91
+ fill: "currentColor"
92
+ }, [
93
+ e("path", {
94
+ "fill-rule": "evenodd",
95
+ d: "M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z",
96
+ "clip-rule": "evenodd"
97
+ })
98
+ ], -1)
99
+ ])], 8, P)
100
+ ]))), 128))
101
+ ])),
102
+ m.value > 0 ? (l(), a("div", F, [
103
+ e("button", {
104
+ onClick: $,
105
+ class: "text-sm text-gray-600 hover:text-red-600 transition-colors"
106
+ }, " Clear completed items ")
107
+ ])) : w("", !0)
108
+ ])
109
+ ]));
110
+ }
111
+ }), G = { class: "p-2 bg-gray-50 dark:bg-gray-800 rounded" }, J = { class: "text-xs text-gray-600 dark:text-gray-400" }, K = { key: 0 }, q = { key: 1 }, Q = { class: "mb-1" }, U = { class: "space-y-1 max-h-20 overflow-y-auto" }, W = {
112
+ key: 0,
113
+ class: "text-green-500"
114
+ }, X = {
115
+ key: 1,
116
+ class: "text-gray-400"
117
+ }, Z = {
118
+ key: 0,
119
+ class: "text-gray-500 italic"
120
+ }, tt = /* @__PURE__ */ y({
121
+ __name: "Preview",
122
+ props: {
123
+ result: {}
124
+ },
125
+ setup(h) {
126
+ const p = h, t = u(() => p.result.data?.items || []), x = u(() => t.value.length), m = u(
127
+ () => t.value.filter((i) => i.completed).length
128
+ );
129
+ return (i, v) => (l(), a("div", G, [
130
+ v[0] || (v[0] = D('<div class="flex items-center gap-2 mb-2"><svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 text-blue-600 dark:text-blue-400" viewBox="0 0 20 20" fill="currentColor"><path d="M9 2a1 1 0 000 2h2a1 1 0 100-2H9z"></path><path fill-rule="evenodd" d="M4 5a2 2 0 012-2 3 3 0 003 3h2a3 3 0 003-3 2 2 0 012 2v11a2 2 0 01-2 2H6a2 2 0 01-2-2V5zm3 4a1 1 0 000 2h.01a1 1 0 100-2H7zm3 0a1 1 0 000 2h3a1 1 0 100-2h-3zm-3 4a1 1 0 100 2h.01a1 1 0 100-2H7zm3 0a1 1 0 100 2h3a1 1 0 100-2h-3z" clip-rule="evenodd"></path></svg><span class="text-sm font-medium text-gray-700 dark:text-gray-300"> Todo List </span></div>', 1)),
131
+ e("div", J, [
132
+ t.value.length === 0 ? (l(), a("div", K, "No items")) : (l(), a("div", q, [
133
+ e("div", Q, r(m.value) + "/" + r(x.value) + " completed", 1),
134
+ e("div", U, [
135
+ (l(!0), a(k, null, b(t.value.slice(0, 3), (c) => (l(), a("div", {
136
+ key: c.id,
137
+ class: "flex items-start gap-1 text-xs"
138
+ }, [
139
+ c.completed ? (l(), a("span", W, "✓")) : (l(), a("span", X, "○")),
140
+ e("span", {
141
+ class: C([
142
+ "flex-1 truncate",
143
+ c.completed ? "line-through text-gray-500" : "text-white"
144
+ ])
145
+ }, r(c.text), 3)
146
+ ]))), 128)),
147
+ t.value.length > 3 ? (l(), a("div", Z, " +" + r(t.value.length - 3) + " more... ", 1)) : w("", !0)
148
+ ])
149
+ ]))
150
+ ])
151
+ ]));
152
+ }
153
+ }), et = {
154
+ ...z,
155
+ viewComponent: j,
156
+ previewComponent: tt,
157
+ samples: T
158
+ }, at = { plugin: et };
159
+ export {
160
+ tt as Preview,
161
+ rt as SYSTEM_PROMPT,
162
+ it as TOOL_DEFINITION,
163
+ ct as TOOL_NAME,
164
+ j as View,
165
+ at as default,
166
+ dt as executeTodo,
167
+ et as plugin,
168
+ z as pluginCore,
169
+ T as samples
170
+ };
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@gui-chat-plugin/todo",
3
+ "version": "0.1.0",
4
+ "description": "Todo list plugin for GUIChat",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ },
15
+ "./core": {
16
+ "types": "./dist/core/index.d.ts",
17
+ "import": "./dist/core.js",
18
+ "require": "./dist/core.cjs"
19
+ },
20
+ "./vue": {
21
+ "types": "./dist/vue/index.d.ts",
22
+ "import": "./dist/vue.js",
23
+ "require": "./dist/vue.cjs"
24
+ },
25
+ "./style.css": "./dist/style.css"
26
+ },
27
+ "files": ["dist"],
28
+ "scripts": {
29
+ "dev": "vite",
30
+ "build": "vite build && vue-tsc -p tsconfig.build.json --emitDeclarationOnly",
31
+ "typecheck": "vue-tsc --noEmit",
32
+ "lint": "eslint src demo"
33
+ },
34
+ "peerDependencies": {
35
+ "vue": "^3.5.0"
36
+ },
37
+ "dependencies": {
38
+ "gui-chat-protocol": "^0.0.1"
39
+ },
40
+ "devDependencies": {
41
+ "@tailwindcss/vite": "^4.1.18",
42
+ "@typescript-eslint/eslint-plugin": "^8.53.0",
43
+ "@typescript-eslint/parser": "^8.53.0",
44
+ "@vitejs/plugin-vue": "^6.0.3",
45
+ "eslint": "^9.39.2",
46
+ "eslint-plugin-vue": "^10.6.2",
47
+ "globals": "^17.0.0",
48
+ "tailwindcss": "^4.1.18",
49
+ "typescript": "~5.9.3",
50
+ "vite": "^7.3.1",
51
+ "vue": "^3.5.26",
52
+ "vue-eslint-parser": "^10.2.0",
53
+ "vue-tsc": "^3.2.2"
54
+ },
55
+ "keywords": ["guichat", "plugin", "todo"],
56
+ "license": "MIT"
57
+ }