@dexto/tools-todo 0.1.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 ADDED
@@ -0,0 +1,44 @@
1
+ Elastic License 2.0 (ELv2)
2
+
3
+ **Acceptance**
4
+ By using the software, you agree to all of the terms and conditions below.
5
+
6
+ **Copyright License**
7
+ The licensor grants you a non-exclusive, royalty-free, worldwide, non-sublicensable, non-transferable license to use, copy, distribute, make available, and prepare derivative works of the software, in each case subject to the limitations and conditions below
8
+
9
+ **Limitations**
10
+ You may not provide the software to third parties as a hosted or managed service, where the service provides users with access to any substantial set of the features or functionality of the software.
11
+
12
+ You may not move, change, disable, or circumvent the license key functionality in the software, and you may not remove or obscure any functionality in the software that is protected by the license key.
13
+
14
+ You may not alter, remove, or obscure any licensing, copyright, or other notices of the licensor in the software. Any use of the licensor’s trademarks is subject to applicable law.
15
+
16
+ **Patents**
17
+ The licensor grants you a license, under any patent claims the licensor can license, or becomes able to license, to make, have made, use, sell, offer for sale, import and have imported the software, in each case subject to the limitations and conditions in this license. This license does not cover any patent claims that you cause to be infringed by modifications or additions to the software. If you or your company make any written claim that the software infringes or contributes to infringement of any patent, your patent license for the software granted under these terms ends immediately. If your company makes such a claim, your patent license ends immediately for work on behalf of your company.
18
+
19
+ **Notices**
20
+ You must ensure that anyone who gets a copy of any part of the software from you also gets a copy of these terms.
21
+
22
+ If you modify the software, you must include in any modified copies of the software prominent notices stating that you have modified the software.
23
+
24
+ **No Other Rights**
25
+ These terms do not imply any licenses other than those expressly granted in these terms.
26
+
27
+ **Termination**
28
+ If you use the software in violation of these terms, such use is not licensed, and your licenses will automatically terminate. If the licensor provides you with a notice of your violation, and you cease all violation of this license no later than 30 days after you receive that notice, your licenses will be reinstated retroactively. However, if you violate these terms after such reinstatement, any additional violation of these terms will cause your licenses to terminate automatically and permanently.
29
+
30
+ **No Liability**
31
+ As far as the law allows, the software comes as is, without any warranty or condition, and the licensor will not be liable to you for any damages arising out of these terms or the use or nature of the software, under any kind of legal claim.
32
+
33
+ **Definitions**
34
+ The _licensor_ is the entity offering these terms, and the _software_ is the software the licensor makes available under these terms, including any portion of it.
35
+
36
+ _you_ refers to the individual or entity agreeing to these terms.
37
+
38
+ _your company_ is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. _control_ means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect.
39
+
40
+ _your licenses_ are all the licenses granted to you for the software under these terms.
41
+
42
+ _use_ means anything you do with the software requiring one of your licenses.
43
+
44
+ _trademark_ means trademarks, service marks, and similar rights.
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var error_codes_exports = {};
20
+ __export(error_codes_exports, {
21
+ TodoErrorCode: () => TodoErrorCode
22
+ });
23
+ module.exports = __toCommonJS(error_codes_exports);
24
+ var TodoErrorCode = /* @__PURE__ */ ((TodoErrorCode2) => {
25
+ TodoErrorCode2["SERVICE_NOT_INITIALIZED"] = "TODO_SERVICE_NOT_INITIALIZED";
26
+ TodoErrorCode2["TODO_LIMIT_EXCEEDED"] = "TODO_LIMIT_EXCEEDED";
27
+ TodoErrorCode2["INVALID_TODO_STATUS"] = "TODO_INVALID_TODO_STATUS";
28
+ TodoErrorCode2["DATABASE_ERROR"] = "TODO_DATABASE_ERROR";
29
+ return TodoErrorCode2;
30
+ })(TodoErrorCode || {});
31
+ // Annotate the CommonJS export names for ESM import in node:
32
+ 0 && (module.exports = {
33
+ TodoErrorCode
34
+ });
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Todo Service Error Codes
3
+ */
4
+ declare enum TodoErrorCode {
5
+ SERVICE_NOT_INITIALIZED = "TODO_SERVICE_NOT_INITIALIZED",
6
+ TODO_LIMIT_EXCEEDED = "TODO_LIMIT_EXCEEDED",
7
+ INVALID_TODO_STATUS = "TODO_INVALID_TODO_STATUS",
8
+ DATABASE_ERROR = "TODO_DATABASE_ERROR"
9
+ }
10
+
11
+ export { TodoErrorCode };
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Todo Service Error Codes
3
+ */
4
+ declare enum TodoErrorCode {
5
+ SERVICE_NOT_INITIALIZED = "TODO_SERVICE_NOT_INITIALIZED",
6
+ TODO_LIMIT_EXCEEDED = "TODO_LIMIT_EXCEEDED",
7
+ INVALID_TODO_STATUS = "TODO_INVALID_TODO_STATUS",
8
+ DATABASE_ERROR = "TODO_DATABASE_ERROR"
9
+ }
10
+
11
+ export { TodoErrorCode };
@@ -0,0 +1,10 @@
1
+ var TodoErrorCode = /* @__PURE__ */ ((TodoErrorCode2) => {
2
+ TodoErrorCode2["SERVICE_NOT_INITIALIZED"] = "TODO_SERVICE_NOT_INITIALIZED";
3
+ TodoErrorCode2["TODO_LIMIT_EXCEEDED"] = "TODO_LIMIT_EXCEEDED";
4
+ TodoErrorCode2["INVALID_TODO_STATUS"] = "TODO_INVALID_TODO_STATUS";
5
+ TodoErrorCode2["DATABASE_ERROR"] = "TODO_DATABASE_ERROR";
6
+ return TodoErrorCode2;
7
+ })(TodoErrorCode || {});
8
+ export {
9
+ TodoErrorCode
10
+ };
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var errors_exports = {};
20
+ __export(errors_exports, {
21
+ TodoError: () => TodoError
22
+ });
23
+ module.exports = __toCommonJS(errors_exports);
24
+ var import_core = require("@dexto/core");
25
+ var import_error_codes = require("./error-codes.js");
26
+ const TODO_ERROR_SCOPE = "todo";
27
+ class TodoError {
28
+ constructor() {
29
+ }
30
+ /**
31
+ * Service not initialized error
32
+ */
33
+ static notInitialized() {
34
+ return new import_core.DextoRuntimeError(
35
+ import_error_codes.TodoErrorCode.SERVICE_NOT_INITIALIZED,
36
+ TODO_ERROR_SCOPE,
37
+ import_core.ErrorType.SYSTEM,
38
+ "TodoService has not been initialized",
39
+ {},
40
+ "Initialize the TodoService before using it"
41
+ );
42
+ }
43
+ /**
44
+ * Todo limit exceeded error
45
+ */
46
+ static todoLimitExceeded(current, max) {
47
+ return new import_core.DextoRuntimeError(
48
+ import_error_codes.TodoErrorCode.TODO_LIMIT_EXCEEDED,
49
+ TODO_ERROR_SCOPE,
50
+ import_core.ErrorType.USER,
51
+ `Todo limit exceeded: ${current} todos. Maximum allowed: ${max}`,
52
+ { current, max },
53
+ "Complete or delete existing todos before adding new ones"
54
+ );
55
+ }
56
+ /**
57
+ * Invalid todo status error
58
+ */
59
+ static invalidStatus(status) {
60
+ return new import_core.DextoRuntimeError(
61
+ import_error_codes.TodoErrorCode.INVALID_TODO_STATUS,
62
+ TODO_ERROR_SCOPE,
63
+ import_core.ErrorType.USER,
64
+ `Invalid todo status: ${status}. Must be 'pending', 'in_progress', or 'completed'`,
65
+ { status }
66
+ );
67
+ }
68
+ /**
69
+ * Database error
70
+ */
71
+ static databaseError(operation, cause) {
72
+ return new import_core.DextoRuntimeError(
73
+ import_error_codes.TodoErrorCode.DATABASE_ERROR,
74
+ TODO_ERROR_SCOPE,
75
+ import_core.ErrorType.SYSTEM,
76
+ `Database error during ${operation}: ${cause}`,
77
+ { operation, cause }
78
+ );
79
+ }
80
+ }
81
+ // Annotate the CommonJS export names for ESM import in node:
82
+ 0 && (module.exports = {
83
+ TodoError
84
+ });
@@ -0,0 +1,32 @@
1
+ import { DextoRuntimeError } from '@dexto/core';
2
+
3
+ /**
4
+ * Todo Service Errors
5
+ *
6
+ * Error factory for todo list management operations
7
+ */
8
+
9
+ /**
10
+ * Factory class for creating Todo-related errors
11
+ */
12
+ declare class TodoError {
13
+ private constructor();
14
+ /**
15
+ * Service not initialized error
16
+ */
17
+ static notInitialized(): DextoRuntimeError;
18
+ /**
19
+ * Todo limit exceeded error
20
+ */
21
+ static todoLimitExceeded(current: number, max: number): DextoRuntimeError;
22
+ /**
23
+ * Invalid todo status error
24
+ */
25
+ static invalidStatus(status: string): DextoRuntimeError;
26
+ /**
27
+ * Database error
28
+ */
29
+ static databaseError(operation: string, cause: string): DextoRuntimeError;
30
+ }
31
+
32
+ export { TodoError };
@@ -0,0 +1,32 @@
1
+ import { DextoRuntimeError } from '@dexto/core';
2
+
3
+ /**
4
+ * Todo Service Errors
5
+ *
6
+ * Error factory for todo list management operations
7
+ */
8
+
9
+ /**
10
+ * Factory class for creating Todo-related errors
11
+ */
12
+ declare class TodoError {
13
+ private constructor();
14
+ /**
15
+ * Service not initialized error
16
+ */
17
+ static notInitialized(): DextoRuntimeError;
18
+ /**
19
+ * Todo limit exceeded error
20
+ */
21
+ static todoLimitExceeded(current: number, max: number): DextoRuntimeError;
22
+ /**
23
+ * Invalid todo status error
24
+ */
25
+ static invalidStatus(status: string): DextoRuntimeError;
26
+ /**
27
+ * Database error
28
+ */
29
+ static databaseError(operation: string, cause: string): DextoRuntimeError;
30
+ }
31
+
32
+ export { TodoError };
package/dist/errors.js ADDED
@@ -0,0 +1,60 @@
1
+ import { DextoRuntimeError, ErrorType } from "@dexto/core";
2
+ import { TodoErrorCode } from "./error-codes.js";
3
+ const TODO_ERROR_SCOPE = "todo";
4
+ class TodoError {
5
+ constructor() {
6
+ }
7
+ /**
8
+ * Service not initialized error
9
+ */
10
+ static notInitialized() {
11
+ return new DextoRuntimeError(
12
+ TodoErrorCode.SERVICE_NOT_INITIALIZED,
13
+ TODO_ERROR_SCOPE,
14
+ ErrorType.SYSTEM,
15
+ "TodoService has not been initialized",
16
+ {},
17
+ "Initialize the TodoService before using it"
18
+ );
19
+ }
20
+ /**
21
+ * Todo limit exceeded error
22
+ */
23
+ static todoLimitExceeded(current, max) {
24
+ return new DextoRuntimeError(
25
+ TodoErrorCode.TODO_LIMIT_EXCEEDED,
26
+ TODO_ERROR_SCOPE,
27
+ ErrorType.USER,
28
+ `Todo limit exceeded: ${current} todos. Maximum allowed: ${max}`,
29
+ { current, max },
30
+ "Complete or delete existing todos before adding new ones"
31
+ );
32
+ }
33
+ /**
34
+ * Invalid todo status error
35
+ */
36
+ static invalidStatus(status) {
37
+ return new DextoRuntimeError(
38
+ TodoErrorCode.INVALID_TODO_STATUS,
39
+ TODO_ERROR_SCOPE,
40
+ ErrorType.USER,
41
+ `Invalid todo status: ${status}. Must be 'pending', 'in_progress', or 'completed'`,
42
+ { status }
43
+ );
44
+ }
45
+ /**
46
+ * Database error
47
+ */
48
+ static databaseError(operation, cause) {
49
+ return new DextoRuntimeError(
50
+ TodoErrorCode.DATABASE_ERROR,
51
+ TODO_ERROR_SCOPE,
52
+ ErrorType.SYSTEM,
53
+ `Database error during ${operation}: ${cause}`,
54
+ { operation, cause }
55
+ );
56
+ }
57
+ }
58
+ export {
59
+ TodoError
60
+ };
package/dist/index.cjs ADDED
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var index_exports = {};
20
+ __export(index_exports, {
21
+ TODO_STATUS_VALUES: () => import_types.TODO_STATUS_VALUES,
22
+ TodoError: () => import_errors.TodoError,
23
+ TodoErrorCode: () => import_error_codes.TodoErrorCode,
24
+ TodoService: () => import_todo_service.TodoService,
25
+ createTodoWriteTool: () => import_todo_write_tool.createTodoWriteTool,
26
+ todoToolsProvider: () => import_tool_provider.todoToolsProvider
27
+ });
28
+ module.exports = __toCommonJS(index_exports);
29
+ var import_tool_provider = require("./tool-provider.js");
30
+ var import_todo_service = require("./todo-service.js");
31
+ var import_errors = require("./errors.js");
32
+ var import_error_codes = require("./error-codes.js");
33
+ var import_types = require("./types.js");
34
+ var import_todo_write_tool = require("./todo-write-tool.js");
35
+ // Annotate the CommonJS export names for ESM import in node:
36
+ 0 && (module.exports = {
37
+ TODO_STATUS_VALUES,
38
+ TodoError,
39
+ TodoErrorCode,
40
+ TodoService,
41
+ createTodoWriteTool,
42
+ todoToolsProvider
43
+ });
@@ -0,0 +1,8 @@
1
+ export { todoToolsProvider } from './tool-provider.cjs';
2
+ export { TodoService } from './todo-service.cjs';
3
+ export { TodoError } from './errors.cjs';
4
+ export { TodoErrorCode } from './error-codes.cjs';
5
+ export { TODO_STATUS_VALUES, Todo, TodoConfig, TodoInput, TodoStatus, TodoUpdateResult } from './types.cjs';
6
+ export { createTodoWriteTool } from './todo-write-tool.cjs';
7
+ import 'zod';
8
+ import '@dexto/core';
@@ -0,0 +1,8 @@
1
+ export { todoToolsProvider } from './tool-provider.js';
2
+ export { TodoService } from './todo-service.js';
3
+ export { TodoError } from './errors.js';
4
+ export { TodoErrorCode } from './error-codes.js';
5
+ export { TODO_STATUS_VALUES, Todo, TodoConfig, TodoInput, TodoStatus, TodoUpdateResult } from './types.js';
6
+ export { createTodoWriteTool } from './todo-write-tool.js';
7
+ import 'zod';
8
+ import '@dexto/core';
package/dist/index.js ADDED
@@ -0,0 +1,14 @@
1
+ import { todoToolsProvider } from "./tool-provider.js";
2
+ import { TodoService } from "./todo-service.js";
3
+ import { TodoError } from "./errors.js";
4
+ import { TodoErrorCode } from "./error-codes.js";
5
+ import { TODO_STATUS_VALUES } from "./types.js";
6
+ import { createTodoWriteTool } from "./todo-write-tool.js";
7
+ export {
8
+ TODO_STATUS_VALUES,
9
+ TodoError,
10
+ TodoErrorCode,
11
+ TodoService,
12
+ createTodoWriteTool,
13
+ todoToolsProvider
14
+ };
@@ -0,0 +1,187 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var todo_service_exports = {};
20
+ __export(todo_service_exports, {
21
+ TodoService: () => TodoService
22
+ });
23
+ module.exports = __toCommonJS(todo_service_exports);
24
+ var import_nanoid = require("nanoid");
25
+ var import_core = require("@dexto/core");
26
+ var import_errors = require("./errors.js");
27
+ var import_types = require("./types.js");
28
+ const DEFAULT_MAX_TODOS = 100;
29
+ const TODOS_KEY_PREFIX = "todos:";
30
+ class TodoService {
31
+ database;
32
+ eventBus;
33
+ logger;
34
+ config;
35
+ initialized = false;
36
+ constructor(database, eventBus, logger, config = {}) {
37
+ this.database = database;
38
+ this.eventBus = eventBus;
39
+ this.logger = logger;
40
+ this.config = {
41
+ maxTodosPerSession: config.maxTodosPerSession ?? DEFAULT_MAX_TODOS,
42
+ enableEvents: config.enableEvents ?? true
43
+ };
44
+ }
45
+ /**
46
+ * Initialize the service
47
+ */
48
+ async initialize() {
49
+ if (this.initialized) {
50
+ this.logger.debug("TodoService already initialized");
51
+ return;
52
+ }
53
+ this.initialized = true;
54
+ this.logger.info("TodoService initialized successfully");
55
+ }
56
+ /**
57
+ * Update todos for a session (replaces entire list)
58
+ */
59
+ async updateTodos(sessionId, todoInputs) {
60
+ if (!this.initialized) {
61
+ throw import_errors.TodoError.notInitialized();
62
+ }
63
+ if (todoInputs.length > this.config.maxTodosPerSession) {
64
+ throw import_errors.TodoError.todoLimitExceeded(todoInputs.length, this.config.maxTodosPerSession);
65
+ }
66
+ try {
67
+ const existing = await this.getTodos(sessionId);
68
+ const existingMap = new Map(existing.map((t) => [this.getTodoKey(t), t]));
69
+ const now = /* @__PURE__ */ new Date();
70
+ const newTodos = [];
71
+ const stats = { created: 0, updated: 0, deleted: 0 };
72
+ for (let i = 0; i < todoInputs.length; i++) {
73
+ const input = todoInputs[i];
74
+ this.validateTodoStatus(input.status);
75
+ const todoKey = this.getTodoKeyFromInput(input);
76
+ const existingTodo = existingMap.get(todoKey);
77
+ if (existingTodo) {
78
+ const updated = {
79
+ ...existingTodo,
80
+ status: input.status,
81
+ updatedAt: now,
82
+ position: i
83
+ };
84
+ newTodos.push(updated);
85
+ stats.updated++;
86
+ existingMap.delete(todoKey);
87
+ } else {
88
+ const created = {
89
+ id: (0, import_nanoid.nanoid)(),
90
+ sessionId,
91
+ content: input.content,
92
+ activeForm: input.activeForm,
93
+ status: input.status,
94
+ position: i,
95
+ createdAt: now,
96
+ updatedAt: now
97
+ };
98
+ newTodos.push(created);
99
+ stats.created++;
100
+ }
101
+ }
102
+ stats.deleted = existingMap.size;
103
+ const key = this.getTodosDatabaseKey(sessionId);
104
+ await this.database.set(key, newTodos);
105
+ if (this.config.enableEvents) {
106
+ this.eventBus.emit("service:event", {
107
+ service: "todo",
108
+ event: "updated",
109
+ sessionId,
110
+ data: {
111
+ todos: newTodos,
112
+ stats
113
+ }
114
+ });
115
+ }
116
+ this.logger.debug(
117
+ `Updated todos for session ${sessionId}: ${stats.created} created, ${stats.updated} updated, ${stats.deleted} deleted`
118
+ );
119
+ return {
120
+ todos: newTodos,
121
+ sessionId,
122
+ ...stats
123
+ };
124
+ } catch (error) {
125
+ if (error instanceof import_core.DextoRuntimeError) {
126
+ throw error;
127
+ }
128
+ throw import_errors.TodoError.databaseError(
129
+ "updateTodos",
130
+ error instanceof Error ? error.message : String(error)
131
+ );
132
+ }
133
+ }
134
+ /**
135
+ * Get todos for a session
136
+ */
137
+ async getTodos(sessionId) {
138
+ if (!this.initialized) {
139
+ throw import_errors.TodoError.notInitialized();
140
+ }
141
+ try {
142
+ const key = this.getTodosDatabaseKey(sessionId);
143
+ const todos = await this.database.get(key);
144
+ return todos || [];
145
+ } catch (error) {
146
+ if (error instanceof import_core.DextoRuntimeError) {
147
+ throw error;
148
+ }
149
+ throw import_errors.TodoError.databaseError(
150
+ "getTodos",
151
+ error instanceof Error ? error.message : String(error)
152
+ );
153
+ }
154
+ }
155
+ /**
156
+ * Generate database key for session todos
157
+ */
158
+ getTodosDatabaseKey(sessionId) {
159
+ return `${TODOS_KEY_PREFIX}${sessionId}`;
160
+ }
161
+ /**
162
+ * Generate consistent key for todo matching (content + activeForm)
163
+ * Uses JSON encoding to prevent collisions when fields contain delimiters
164
+ */
165
+ getTodoKey(todo) {
166
+ return JSON.stringify([todo.content, todo.activeForm]);
167
+ }
168
+ /**
169
+ * Generate key from TodoInput
170
+ * Uses JSON encoding to prevent collisions when fields contain delimiters
171
+ */
172
+ getTodoKeyFromInput(input) {
173
+ return JSON.stringify([input.content, input.activeForm]);
174
+ }
175
+ /**
176
+ * Validate todo status
177
+ */
178
+ validateTodoStatus(status) {
179
+ if (!import_types.TODO_STATUS_VALUES.includes(status)) {
180
+ throw import_errors.TodoError.invalidStatus(status);
181
+ }
182
+ }
183
+ }
184
+ // Annotate the CommonJS export names for ESM import in node:
185
+ 0 && (module.exports = {
186
+ TodoService
187
+ });
@@ -0,0 +1,53 @@
1
+ import { Database, AgentEventBus, IDextoLogger } from '@dexto/core';
2
+ import { TodoConfig, TodoInput, TodoUpdateResult, Todo } from './types.cjs';
3
+
4
+ /**
5
+ * Todo Service
6
+ *
7
+ * Manages todo lists for tracking agent workflow and task progress.
8
+ * Emits events through the AgentEventBus using the service:event pattern.
9
+ */
10
+
11
+ /**
12
+ * TodoService - Manages todo lists for agent workflow tracking
13
+ */
14
+ declare class TodoService {
15
+ private database;
16
+ private eventBus;
17
+ private logger;
18
+ private config;
19
+ private initialized;
20
+ constructor(database: Database, eventBus: AgentEventBus, logger: IDextoLogger, config?: TodoConfig);
21
+ /**
22
+ * Initialize the service
23
+ */
24
+ initialize(): Promise<void>;
25
+ /**
26
+ * Update todos for a session (replaces entire list)
27
+ */
28
+ updateTodos(sessionId: string, todoInputs: TodoInput[]): Promise<TodoUpdateResult>;
29
+ /**
30
+ * Get todos for a session
31
+ */
32
+ getTodos(sessionId: string): Promise<Todo[]>;
33
+ /**
34
+ * Generate database key for session todos
35
+ */
36
+ private getTodosDatabaseKey;
37
+ /**
38
+ * Generate consistent key for todo matching (content + activeForm)
39
+ * Uses JSON encoding to prevent collisions when fields contain delimiters
40
+ */
41
+ private getTodoKey;
42
+ /**
43
+ * Generate key from TodoInput
44
+ * Uses JSON encoding to prevent collisions when fields contain delimiters
45
+ */
46
+ private getTodoKeyFromInput;
47
+ /**
48
+ * Validate todo status
49
+ */
50
+ private validateTodoStatus;
51
+ }
52
+
53
+ export { TodoService };