@hasna/todos 0.11.38 → 0.11.39
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 +1 -11
- package/dist/capabilities.d.ts +32 -0
- package/dist/capabilities.d.ts.map +1 -0
- package/dist/cli/commands/cloud-commands.d.ts.map +1 -1
- package/dist/cli/commands/remote-commands.d.ts +3 -0
- package/dist/cli/commands/remote-commands.d.ts.map +1 -0
- package/dist/cli/index.js +16830 -29235
- package/dist/cli/remote-index.d.ts +3 -0
- package/dist/cli/remote-index.d.ts.map +1 -0
- package/dist/contracts.d.ts +58 -0
- package/dist/contracts.d.ts.map +1 -0
- package/dist/contracts.js +823 -0
- package/dist/db/builtin-templates.d.ts.map +1 -1
- package/dist/index.d.ts +14 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4712 -13636
- package/dist/json-contracts.d.ts +56 -0
- package/dist/json-contracts.d.ts.map +1 -0
- package/dist/lib/cloud-migration.d.ts +53 -0
- package/dist/lib/cloud-migration.d.ts.map +1 -0
- package/dist/lib/config.d.ts +17 -0
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/logger.d.ts +6 -12
- package/dist/lib/logger.d.ts.map +1 -1
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +4435 -16629
- package/dist/mcp/token-utils.d.ts.map +1 -1
- package/dist/mcp/tools/code-tools.d.ts.map +1 -1
- package/dist/mcp/tools/task-meta-tools.d.ts.map +1 -1
- package/dist/mcp.d.ts +42 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +359 -0
- package/dist/registry.d.ts +33 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +1382 -0
- package/dist/remote-cli/remote-index.js +3054 -0
- package/dist/remote.d.ts +5 -0
- package/dist/remote.d.ts.map +1 -0
- package/dist/remote.js +770 -0
- package/dist/sdk/client.d.ts +1 -1
- package/dist/sdk/client.d.ts.map +1 -1
- package/dist/sdk/index.js +635 -0
- package/dist/server/index.js +4 -4
- package/dist/storage/index.d.ts +4 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/interfaces.d.ts +185 -0
- package/dist/storage/interfaces.d.ts.map +1 -0
- package/dist/storage/local-sqlite.d.ts +7 -0
- package/dist/storage/local-sqlite.d.ts.map +1 -0
- package/dist/storage.d.ts +4 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +4984 -0
- package/package.json +22 -4
package/dist/registry.js
ADDED
|
@@ -0,0 +1,1382 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
function __accessProp(key) {
|
|
7
|
+
return this[key];
|
|
8
|
+
}
|
|
9
|
+
var __toCommonJS = (from) => {
|
|
10
|
+
var entry = (__moduleCache ??= new WeakMap).get(from), desc;
|
|
11
|
+
if (entry)
|
|
12
|
+
return entry;
|
|
13
|
+
entry = __defProp({}, "__esModule", { value: true });
|
|
14
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
15
|
+
for (var key of __getOwnPropNames(from))
|
|
16
|
+
if (!__hasOwnProp.call(entry, key))
|
|
17
|
+
__defProp(entry, key, {
|
|
18
|
+
get: __accessProp.bind(from, key),
|
|
19
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
__moduleCache.set(from, entry);
|
|
23
|
+
return entry;
|
|
24
|
+
};
|
|
25
|
+
var __moduleCache;
|
|
26
|
+
var __returnValue = (v) => v;
|
|
27
|
+
function __exportSetter(name, newValue) {
|
|
28
|
+
this[name] = __returnValue.bind(null, newValue);
|
|
29
|
+
}
|
|
30
|
+
var __export = (target, all) => {
|
|
31
|
+
for (var name in all)
|
|
32
|
+
__defProp(target, name, {
|
|
33
|
+
get: all[name],
|
|
34
|
+
enumerable: true,
|
|
35
|
+
configurable: true,
|
|
36
|
+
set: __exportSetter.bind(all, name)
|
|
37
|
+
});
|
|
38
|
+
};
|
|
39
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
40
|
+
|
|
41
|
+
// src/types/index.ts
|
|
42
|
+
var TASK_STATUSES, TASK_PRIORITIES, PLAN_STATUSES, VersionConflictError, TaskNotFoundError, ProjectNotFoundError, PlanNotFoundError, LockError, AgentNotFoundError, TaskListNotFoundError, DependencyCycleError, CompletionGuardError, DISPATCH_STATUSES, DispatchNotFoundError;
|
|
43
|
+
var init_types = __esm(() => {
|
|
44
|
+
TASK_STATUSES = [
|
|
45
|
+
"pending",
|
|
46
|
+
"in_progress",
|
|
47
|
+
"completed",
|
|
48
|
+
"failed",
|
|
49
|
+
"cancelled"
|
|
50
|
+
];
|
|
51
|
+
TASK_PRIORITIES = [
|
|
52
|
+
"low",
|
|
53
|
+
"medium",
|
|
54
|
+
"high",
|
|
55
|
+
"critical"
|
|
56
|
+
];
|
|
57
|
+
PLAN_STATUSES = ["active", "completed", "archived"];
|
|
58
|
+
VersionConflictError = class VersionConflictError extends Error {
|
|
59
|
+
taskId;
|
|
60
|
+
expectedVersion;
|
|
61
|
+
actualVersion;
|
|
62
|
+
static code = "VERSION_CONFLICT";
|
|
63
|
+
static suggestion = "Fetch the task with get_task to get the current version before updating.";
|
|
64
|
+
constructor(taskId, expectedVersion, actualVersion) {
|
|
65
|
+
super(`Version conflict for task ${taskId}: expected ${expectedVersion}, got ${actualVersion}`);
|
|
66
|
+
this.taskId = taskId;
|
|
67
|
+
this.expectedVersion = expectedVersion;
|
|
68
|
+
this.actualVersion = actualVersion;
|
|
69
|
+
this.name = "VersionConflictError";
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
TaskNotFoundError = class TaskNotFoundError extends Error {
|
|
73
|
+
taskId;
|
|
74
|
+
static code = "TASK_NOT_FOUND";
|
|
75
|
+
static suggestion = "Verify the task ID. Use list_tasks or search_tasks to find the correct ID.";
|
|
76
|
+
constructor(taskId) {
|
|
77
|
+
super(`Task not found: ${taskId}`);
|
|
78
|
+
this.taskId = taskId;
|
|
79
|
+
this.name = "TaskNotFoundError";
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
ProjectNotFoundError = class ProjectNotFoundError extends Error {
|
|
83
|
+
projectId;
|
|
84
|
+
static code = "PROJECT_NOT_FOUND";
|
|
85
|
+
static suggestion = "Use list_projects to see available projects.";
|
|
86
|
+
constructor(projectId) {
|
|
87
|
+
super(`Project not found: ${projectId}`);
|
|
88
|
+
this.projectId = projectId;
|
|
89
|
+
this.name = "ProjectNotFoundError";
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
PlanNotFoundError = class PlanNotFoundError extends Error {
|
|
93
|
+
planId;
|
|
94
|
+
static code = "PLAN_NOT_FOUND";
|
|
95
|
+
static suggestion = "Use list_plans to see available plans.";
|
|
96
|
+
constructor(planId) {
|
|
97
|
+
super(`Plan not found: ${planId}`);
|
|
98
|
+
this.planId = planId;
|
|
99
|
+
this.name = "PlanNotFoundError";
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
LockError = class LockError extends Error {
|
|
103
|
+
taskId;
|
|
104
|
+
lockedBy;
|
|
105
|
+
static code = "LOCK_ERROR";
|
|
106
|
+
static suggestion = "Wait for the lock to expire (30 min) or contact the lock holder.";
|
|
107
|
+
constructor(taskId, lockedBy) {
|
|
108
|
+
super(`Task ${taskId} is locked by ${lockedBy}`);
|
|
109
|
+
this.taskId = taskId;
|
|
110
|
+
this.lockedBy = lockedBy;
|
|
111
|
+
this.name = "LockError";
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
AgentNotFoundError = class AgentNotFoundError extends Error {
|
|
115
|
+
agentId;
|
|
116
|
+
static code = "AGENT_NOT_FOUND";
|
|
117
|
+
static suggestion = "Use register_agent to create the agent first, or list_agents to find existing ones.";
|
|
118
|
+
constructor(agentId) {
|
|
119
|
+
super(`Agent not found: ${agentId}`);
|
|
120
|
+
this.agentId = agentId;
|
|
121
|
+
this.name = "AgentNotFoundError";
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
TaskListNotFoundError = class TaskListNotFoundError extends Error {
|
|
125
|
+
taskListId;
|
|
126
|
+
static code = "TASK_LIST_NOT_FOUND";
|
|
127
|
+
static suggestion = "Use list_task_lists to see available lists.";
|
|
128
|
+
constructor(taskListId) {
|
|
129
|
+
super(`Task list not found: ${taskListId}`);
|
|
130
|
+
this.taskListId = taskListId;
|
|
131
|
+
this.name = "TaskListNotFoundError";
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
DependencyCycleError = class DependencyCycleError extends Error {
|
|
135
|
+
taskId;
|
|
136
|
+
dependsOn;
|
|
137
|
+
static code = "DEPENDENCY_CYCLE";
|
|
138
|
+
static suggestion = "Check the dependency chain with get_task to avoid circular references.";
|
|
139
|
+
constructor(taskId, dependsOn) {
|
|
140
|
+
super(`Adding dependency ${taskId} -> ${dependsOn} would create a cycle`);
|
|
141
|
+
this.taskId = taskId;
|
|
142
|
+
this.dependsOn = dependsOn;
|
|
143
|
+
this.name = "DependencyCycleError";
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
CompletionGuardError = class CompletionGuardError extends Error {
|
|
147
|
+
reason;
|
|
148
|
+
retryAfterSeconds;
|
|
149
|
+
static code = "COMPLETION_BLOCKED";
|
|
150
|
+
static suggestion = "Wait for the cooldown period, then retry.";
|
|
151
|
+
constructor(reason, retryAfterSeconds) {
|
|
152
|
+
super(reason);
|
|
153
|
+
this.reason = reason;
|
|
154
|
+
this.retryAfterSeconds = retryAfterSeconds;
|
|
155
|
+
this.name = "CompletionGuardError";
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
DISPATCH_STATUSES = ["pending", "sent", "failed", "cancelled"];
|
|
159
|
+
DispatchNotFoundError = class DispatchNotFoundError extends Error {
|
|
160
|
+
dispatchId;
|
|
161
|
+
static code = "DISPATCH_NOT_FOUND";
|
|
162
|
+
static suggestion = "Check the dispatch ID with list_dispatches.";
|
|
163
|
+
constructor(dispatchId) {
|
|
164
|
+
super(`Dispatch not found: ${dispatchId}`);
|
|
165
|
+
this.dispatchId = dispatchId;
|
|
166
|
+
this.name = "DispatchNotFoundError";
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
// src/lib/package-version.ts
|
|
172
|
+
import { existsSync, readFileSync } from "fs";
|
|
173
|
+
import { dirname, join } from "path";
|
|
174
|
+
import { fileURLToPath } from "url";
|
|
175
|
+
function getPackageVersion(fromUrl = import.meta.url) {
|
|
176
|
+
try {
|
|
177
|
+
let dir = dirname(fileURLToPath(fromUrl));
|
|
178
|
+
for (let i = 0;i < 5; i++) {
|
|
179
|
+
const pkgPath = join(dir, "package.json");
|
|
180
|
+
if (existsSync(pkgPath)) {
|
|
181
|
+
return JSON.parse(readFileSync(pkgPath, "utf-8")).version || "0.0.0";
|
|
182
|
+
}
|
|
183
|
+
const parent = dirname(dir);
|
|
184
|
+
if (parent === dir)
|
|
185
|
+
break;
|
|
186
|
+
dir = parent;
|
|
187
|
+
}
|
|
188
|
+
} catch {
|
|
189
|
+
return "0.0.0";
|
|
190
|
+
}
|
|
191
|
+
return "0.0.0";
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// src/json-contracts.ts
|
|
195
|
+
function source(version) {
|
|
196
|
+
return {
|
|
197
|
+
packageName: "@hasna/todos",
|
|
198
|
+
repository: "hasna/todos",
|
|
199
|
+
version
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
function field(type, description, nullable = false) {
|
|
203
|
+
return { type, description, nullable };
|
|
204
|
+
}
|
|
205
|
+
function contract(input) {
|
|
206
|
+
return {
|
|
207
|
+
...input,
|
|
208
|
+
additionalProperties: true,
|
|
209
|
+
evolution: {
|
|
210
|
+
additionalFields: "allowed",
|
|
211
|
+
removingRequiredFields: "breaking",
|
|
212
|
+
changingRequiredFieldTypes: "breaking",
|
|
213
|
+
nullableToNonNullable: "breaking"
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
var idField = field("string", "Stable UUID or short identifier.");
|
|
218
|
+
var nullableIdField = field(["string", "null"], "Stable identifier when attached to another object.", true);
|
|
219
|
+
var isoDateField = field("string", "ISO-8601 timestamp string.");
|
|
220
|
+
var nullableIsoDateField = field(["string", "null"], "ISO-8601 timestamp string, or null when not set.", true);
|
|
221
|
+
var metadataField = field("object", "JSON object metadata. Unknown keys are extension data.");
|
|
222
|
+
var tagsField = field("array", "Array of string tags.");
|
|
223
|
+
var TODOS_JSON_CONTRACTS = [
|
|
224
|
+
contract({
|
|
225
|
+
id: "task",
|
|
226
|
+
name: "Task",
|
|
227
|
+
description: "Canonical task object returned by CLI JSON, SDK, API summaries, and MCP task tools.",
|
|
228
|
+
surfaces: ["cli", "api", "mcp", "sdk"],
|
|
229
|
+
stability: "stable",
|
|
230
|
+
required: {
|
|
231
|
+
id: idField,
|
|
232
|
+
short_id: nullableIdField,
|
|
233
|
+
title: field("string", "Human-readable task title."),
|
|
234
|
+
description: field(["string", "null"], "Optional task description.", true),
|
|
235
|
+
status: field("string", "Task lifecycle status."),
|
|
236
|
+
priority: field("string", "Task priority."),
|
|
237
|
+
project_id: nullableIdField,
|
|
238
|
+
plan_id: nullableIdField,
|
|
239
|
+
task_list_id: nullableIdField,
|
|
240
|
+
agent_id: nullableIdField,
|
|
241
|
+
assigned_to: field(["string", "null"], "Assigned agent name or id.", true),
|
|
242
|
+
tags: tagsField,
|
|
243
|
+
metadata: metadataField,
|
|
244
|
+
version: field("integer", "Optimistic locking version."),
|
|
245
|
+
created_at: isoDateField,
|
|
246
|
+
updated_at: isoDateField
|
|
247
|
+
},
|
|
248
|
+
optional: {
|
|
249
|
+
locked_by: field(["string", "null"], "Agent currently holding the task lock.", true),
|
|
250
|
+
locked_at: nullableIsoDateField,
|
|
251
|
+
started_at: nullableIsoDateField,
|
|
252
|
+
completed_at: nullableIsoDateField,
|
|
253
|
+
due_at: nullableIsoDateField
|
|
254
|
+
}
|
|
255
|
+
}),
|
|
256
|
+
contract({
|
|
257
|
+
id: "project",
|
|
258
|
+
name: "Project",
|
|
259
|
+
description: "Project object used to scope tasks to a local repository or workspace.",
|
|
260
|
+
surfaces: ["cli", "api", "mcp", "sdk"],
|
|
261
|
+
stability: "stable",
|
|
262
|
+
required: {
|
|
263
|
+
id: idField,
|
|
264
|
+
name: field("string", "Project display name."),
|
|
265
|
+
path: field("string", "Canonical project path."),
|
|
266
|
+
description: field(["string", "null"], "Optional project description.", true),
|
|
267
|
+
task_list_id: nullableIdField,
|
|
268
|
+
task_prefix: field(["string", "null"], "Optional task prefix.", true),
|
|
269
|
+
task_counter: field("integer", "Monotonic project task counter."),
|
|
270
|
+
created_at: isoDateField,
|
|
271
|
+
updated_at: isoDateField
|
|
272
|
+
},
|
|
273
|
+
optional: {
|
|
274
|
+
sources: field("array", "Optional project source records.")
|
|
275
|
+
}
|
|
276
|
+
}),
|
|
277
|
+
contract({
|
|
278
|
+
id: "agent",
|
|
279
|
+
name: "Agent",
|
|
280
|
+
description: "Registered agent identity and coordination metadata.",
|
|
281
|
+
surfaces: ["cli", "api", "mcp", "sdk"],
|
|
282
|
+
stability: "stable",
|
|
283
|
+
required: {
|
|
284
|
+
id: idField,
|
|
285
|
+
name: field("string", "Normalized agent name."),
|
|
286
|
+
description: field(["string", "null"], "Optional agent description.", true),
|
|
287
|
+
role: field(["string", "null"], "Agent role.", true),
|
|
288
|
+
permissions: field("array", "Permission labels."),
|
|
289
|
+
capabilities: field("array", "Capability labels."),
|
|
290
|
+
status: field("string", "Agent lifecycle status."),
|
|
291
|
+
created_at: isoDateField,
|
|
292
|
+
last_seen_at: isoDateField
|
|
293
|
+
},
|
|
294
|
+
optional: {
|
|
295
|
+
session_id: nullableIdField,
|
|
296
|
+
working_dir: field(["string", "null"], "Current working directory.", true),
|
|
297
|
+
active_project_id: nullableIdField
|
|
298
|
+
}
|
|
299
|
+
}),
|
|
300
|
+
contract({
|
|
301
|
+
id: "template",
|
|
302
|
+
name: "Task Template",
|
|
303
|
+
description: "Task template object used to create repeatable task plans.",
|
|
304
|
+
surfaces: ["cli", "api", "mcp", "sdk"],
|
|
305
|
+
stability: "stable",
|
|
306
|
+
required: {
|
|
307
|
+
id: idField,
|
|
308
|
+
name: field("string", "Template name."),
|
|
309
|
+
title_pattern: field("string", "Task title pattern."),
|
|
310
|
+
description: field(["string", "null"], "Optional template description.", true),
|
|
311
|
+
priority: field("string", "Default task priority."),
|
|
312
|
+
tags: tagsField,
|
|
313
|
+
variables: field("array", "Template variable definitions."),
|
|
314
|
+
version: field("integer", "Template version."),
|
|
315
|
+
project_id: nullableIdField,
|
|
316
|
+
plan_id: nullableIdField,
|
|
317
|
+
metadata: metadataField,
|
|
318
|
+
created_at: isoDateField
|
|
319
|
+
},
|
|
320
|
+
optional: {
|
|
321
|
+
tasks: field("array", "Expanded template task steps.")
|
|
322
|
+
}
|
|
323
|
+
}),
|
|
324
|
+
contract({
|
|
325
|
+
id: "task_list",
|
|
326
|
+
name: "Task List",
|
|
327
|
+
description: "Named task list, optionally scoped to a project.",
|
|
328
|
+
surfaces: ["cli", "api", "mcp", "sdk"],
|
|
329
|
+
stability: "stable",
|
|
330
|
+
required: {
|
|
331
|
+
id: idField,
|
|
332
|
+
project_id: nullableIdField,
|
|
333
|
+
slug: field("string", "Stable URL/CLI-safe list slug."),
|
|
334
|
+
name: field("string", "Task list display name."),
|
|
335
|
+
description: field(["string", "null"], "Optional list description.", true),
|
|
336
|
+
metadata: metadataField,
|
|
337
|
+
created_at: isoDateField,
|
|
338
|
+
updated_at: isoDateField
|
|
339
|
+
},
|
|
340
|
+
optional: {}
|
|
341
|
+
}),
|
|
342
|
+
contract({
|
|
343
|
+
id: "comment",
|
|
344
|
+
name: "Task Comment",
|
|
345
|
+
description: "Comment, progress update, or note attached to a task.",
|
|
346
|
+
surfaces: ["cli", "api", "mcp", "sdk"],
|
|
347
|
+
stability: "stable",
|
|
348
|
+
required: {
|
|
349
|
+
id: idField,
|
|
350
|
+
task_id: idField,
|
|
351
|
+
agent_id: nullableIdField,
|
|
352
|
+
session_id: nullableIdField,
|
|
353
|
+
content: field("string", "Comment body."),
|
|
354
|
+
type: field("string", "Comment type: comment, progress, or note."),
|
|
355
|
+
progress_pct: field(["integer", "number", "null"], "Progress percentage for progress entries.", true),
|
|
356
|
+
created_at: isoDateField
|
|
357
|
+
},
|
|
358
|
+
optional: {}
|
|
359
|
+
}),
|
|
360
|
+
contract({
|
|
361
|
+
id: "checkpoint",
|
|
362
|
+
name: "Task Run Checkpoint",
|
|
363
|
+
description: "Task runner checkpoint for a named execution step.",
|
|
364
|
+
surfaces: ["api", "mcp", "sdk"],
|
|
365
|
+
stability: "stable",
|
|
366
|
+
required: {
|
|
367
|
+
id: idField,
|
|
368
|
+
task_id: idField,
|
|
369
|
+
agent_id: nullableIdField,
|
|
370
|
+
step: field("string", "Runner step name."),
|
|
371
|
+
status: field("string", "Checkpoint execution status."),
|
|
372
|
+
data: metadataField,
|
|
373
|
+
error: field(["string", "null"], "Step error message when failed.", true),
|
|
374
|
+
attempt: field("integer", "Current attempt number."),
|
|
375
|
+
max_attempts: field("integer", "Maximum allowed attempts."),
|
|
376
|
+
started_at: nullableIsoDateField,
|
|
377
|
+
completed_at: nullableIsoDateField,
|
|
378
|
+
created_at: isoDateField,
|
|
379
|
+
updated_at: isoDateField
|
|
380
|
+
},
|
|
381
|
+
optional: {}
|
|
382
|
+
}),
|
|
383
|
+
contract({
|
|
384
|
+
id: "dispatch",
|
|
385
|
+
name: "Dispatch",
|
|
386
|
+
description: "Queued or completed tmux dispatch/run request.",
|
|
387
|
+
surfaces: ["cli", "mcp", "sdk"],
|
|
388
|
+
stability: "stable",
|
|
389
|
+
required: {
|
|
390
|
+
id: idField,
|
|
391
|
+
title: field(["string", "null"], "Optional dispatch title.", true),
|
|
392
|
+
target_window: field("string", "tmux target window."),
|
|
393
|
+
task_ids: field("array", "Task IDs included in the dispatch."),
|
|
394
|
+
task_list_id: nullableIdField,
|
|
395
|
+
message: field(["string", "null"], "Preformatted message, or null when generated from tasks.", true),
|
|
396
|
+
delay_ms: field(["integer", "null"], "Delay between send and Enter.", true),
|
|
397
|
+
scheduled_at: nullableIsoDateField,
|
|
398
|
+
status: field("string", "Dispatch status."),
|
|
399
|
+
error: field(["string", "null"], "Dispatch error when failed.", true),
|
|
400
|
+
created_at: isoDateField,
|
|
401
|
+
sent_at: nullableIsoDateField
|
|
402
|
+
},
|
|
403
|
+
optional: {}
|
|
404
|
+
}),
|
|
405
|
+
contract({
|
|
406
|
+
id: "audit_history",
|
|
407
|
+
name: "Audit History",
|
|
408
|
+
description: "Audit log entry for a task mutation.",
|
|
409
|
+
surfaces: ["cli", "api", "mcp", "sdk"],
|
|
410
|
+
stability: "stable",
|
|
411
|
+
required: {
|
|
412
|
+
id: idField,
|
|
413
|
+
task_id: idField,
|
|
414
|
+
action: field("string", "Mutation action name."),
|
|
415
|
+
field: field(["string", "null"], "Changed field name.", true),
|
|
416
|
+
old_value: field(["string", "null"], "Previous value serialized as a string.", true),
|
|
417
|
+
new_value: field(["string", "null"], "New value serialized as a string.", true),
|
|
418
|
+
agent_id: nullableIdField,
|
|
419
|
+
created_at: isoDateField
|
|
420
|
+
},
|
|
421
|
+
optional: {}
|
|
422
|
+
}),
|
|
423
|
+
contract({
|
|
424
|
+
id: "status_summary",
|
|
425
|
+
name: "Status Summary",
|
|
426
|
+
description: "Queue status counts and lightweight next/active work summary.",
|
|
427
|
+
surfaces: ["cli", "api", "mcp", "sdk"],
|
|
428
|
+
stability: "stable",
|
|
429
|
+
required: {
|
|
430
|
+
pending: field("integer", "Pending task count."),
|
|
431
|
+
in_progress: field("integer", "In-progress task count."),
|
|
432
|
+
completed: field("integer", "Completed task count."),
|
|
433
|
+
total: field("integer", "Total task count for the selected scope."),
|
|
434
|
+
active_work: field("array", "Lightweight active work items."),
|
|
435
|
+
next_task: field(["object", "null"], "Next available task, or null when none is available.", true),
|
|
436
|
+
stale_count: field("integer", "Count of stale in-progress tasks."),
|
|
437
|
+
overdue_recurring: field("integer", "Count of overdue recurring tasks.")
|
|
438
|
+
},
|
|
439
|
+
optional: {
|
|
440
|
+
blocked_tasks: field("array", "Optional blocked task explanation list.")
|
|
441
|
+
}
|
|
442
|
+
}),
|
|
443
|
+
contract({
|
|
444
|
+
id: "structured_error",
|
|
445
|
+
name: "Structured Error",
|
|
446
|
+
description: "Structured MCP/SDK-style error response with a stable machine code.",
|
|
447
|
+
surfaces: ["mcp", "sdk"],
|
|
448
|
+
stability: "stable",
|
|
449
|
+
required: {
|
|
450
|
+
code: field("string", "Stable machine-readable error code."),
|
|
451
|
+
message: field("string", "Human-readable error message.")
|
|
452
|
+
},
|
|
453
|
+
optional: {
|
|
454
|
+
suggestion: field("string", "Optional recovery suggestion."),
|
|
455
|
+
retryAfterSeconds: field("integer", "Optional retry delay for cooldown errors.")
|
|
456
|
+
}
|
|
457
|
+
}),
|
|
458
|
+
contract({
|
|
459
|
+
id: "api_error",
|
|
460
|
+
name: "API Error",
|
|
461
|
+
description: "HTTP API and CLI JSON error object for simple error responses.",
|
|
462
|
+
surfaces: ["cli", "api"],
|
|
463
|
+
stability: "stable",
|
|
464
|
+
required: {
|
|
465
|
+
error: field("string", "Human-readable error message.")
|
|
466
|
+
},
|
|
467
|
+
optional: {
|
|
468
|
+
code: field("string", "Optional machine-readable error code."),
|
|
469
|
+
conflict: field("boolean", "Optional conflict flag for registration errors."),
|
|
470
|
+
suggestions: field("array", "Optional recovery suggestions."),
|
|
471
|
+
retry_after: field("integer", "Optional retry delay for rate-limited responses.")
|
|
472
|
+
}
|
|
473
|
+
})
|
|
474
|
+
];
|
|
475
|
+
function expectedTypes(contract2) {
|
|
476
|
+
const types = Array.isArray(contract2.type) ? [...contract2.type] : [contract2.type];
|
|
477
|
+
if (contract2.nullable && !types.includes("null"))
|
|
478
|
+
return [...types, "null"];
|
|
479
|
+
return types;
|
|
480
|
+
}
|
|
481
|
+
function actualType(value) {
|
|
482
|
+
if (value === null)
|
|
483
|
+
return "null";
|
|
484
|
+
if (Array.isArray(value))
|
|
485
|
+
return "array";
|
|
486
|
+
if (typeof value === "number" && Number.isInteger(value))
|
|
487
|
+
return "integer";
|
|
488
|
+
if (typeof value === "number")
|
|
489
|
+
return "number";
|
|
490
|
+
if (typeof value === "boolean")
|
|
491
|
+
return "boolean";
|
|
492
|
+
if (typeof value === "string")
|
|
493
|
+
return "string";
|
|
494
|
+
if (typeof value === "object")
|
|
495
|
+
return "object";
|
|
496
|
+
return "string";
|
|
497
|
+
}
|
|
498
|
+
function matchesType(value, expected) {
|
|
499
|
+
const actual = actualType(value);
|
|
500
|
+
if (expected.includes(actual))
|
|
501
|
+
return true;
|
|
502
|
+
return actual === "integer" && expected.includes("number");
|
|
503
|
+
}
|
|
504
|
+
function getJsonContract(contractId) {
|
|
505
|
+
return TODOS_JSON_CONTRACTS.find((contractItem) => contractItem.id === contractId) ?? null;
|
|
506
|
+
}
|
|
507
|
+
function validateJsonContract(contractId, value) {
|
|
508
|
+
const contractItem = getJsonContract(contractId);
|
|
509
|
+
if (!contractItem) {
|
|
510
|
+
throw new Error(`Unknown JSON contract: ${contractId}`);
|
|
511
|
+
}
|
|
512
|
+
const record = value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
513
|
+
const missingRequired = [];
|
|
514
|
+
const typeMismatches = [];
|
|
515
|
+
for (const [fieldName, fieldContract] of Object.entries(contractItem.required)) {
|
|
516
|
+
if (!(fieldName in record)) {
|
|
517
|
+
missingRequired.push(fieldName);
|
|
518
|
+
continue;
|
|
519
|
+
}
|
|
520
|
+
const expected = expectedTypes(fieldContract);
|
|
521
|
+
const valueType = actualType(record[fieldName]);
|
|
522
|
+
if (!matchesType(record[fieldName], expected)) {
|
|
523
|
+
typeMismatches.push({ field: fieldName, expected, actual: valueType });
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
return {
|
|
527
|
+
ok: missingRequired.length === 0 && typeMismatches.length === 0,
|
|
528
|
+
contractId,
|
|
529
|
+
missingRequired,
|
|
530
|
+
typeMismatches
|
|
531
|
+
};
|
|
532
|
+
}
|
|
533
|
+
function createJsonContractsManifest(options = {}) {
|
|
534
|
+
const version = options.version ?? getPackageVersion(import.meta.url);
|
|
535
|
+
return {
|
|
536
|
+
schemaVersion: 1,
|
|
537
|
+
generatedAt: options.generatedAt ?? new Date().toISOString(),
|
|
538
|
+
package: source(version),
|
|
539
|
+
contracts: TODOS_JSON_CONTRACTS
|
|
540
|
+
};
|
|
541
|
+
}
|
|
542
|
+
var TODOS_JSON_CONTRACTS_MANIFEST = createJsonContractsManifest({
|
|
543
|
+
generatedAt: "1970-01-01T00:00:00.000Z"
|
|
544
|
+
});
|
|
545
|
+
|
|
546
|
+
// src/contracts.ts
|
|
547
|
+
init_types();
|
|
548
|
+
var objectSchema = {
|
|
549
|
+
type: "object",
|
|
550
|
+
additionalProperties: true
|
|
551
|
+
};
|
|
552
|
+
var taskSchema = {
|
|
553
|
+
type: "object",
|
|
554
|
+
properties: {
|
|
555
|
+
id: { type: "string" },
|
|
556
|
+
title: { type: "string" },
|
|
557
|
+
status: { type: "string", enum: TASK_STATUSES },
|
|
558
|
+
priority: { type: "string", enum: TASK_PRIORITIES }
|
|
559
|
+
},
|
|
560
|
+
required: ["id", "title", "status", "priority"],
|
|
561
|
+
additionalProperties: true
|
|
562
|
+
};
|
|
563
|
+
var taskArraySchema = {
|
|
564
|
+
type: "array",
|
|
565
|
+
items: taskSchema
|
|
566
|
+
};
|
|
567
|
+
var TODOS_API_ROUTES = [
|
|
568
|
+
{
|
|
569
|
+
id: "health.read",
|
|
570
|
+
method: "GET",
|
|
571
|
+
path: "/api/health",
|
|
572
|
+
description: "Read local server health and stale task counts.",
|
|
573
|
+
auth: "optional-api-key",
|
|
574
|
+
requestSchema: null,
|
|
575
|
+
responseSchema: objectSchema,
|
|
576
|
+
tags: ["server", "health"],
|
|
577
|
+
stability: "stable"
|
|
578
|
+
},
|
|
579
|
+
{
|
|
580
|
+
id: "tasks.list",
|
|
581
|
+
method: "GET",
|
|
582
|
+
path: "/api/tasks",
|
|
583
|
+
description: "List tasks with query filters for status, project, session, agent, limit, and offset.",
|
|
584
|
+
auth: "optional-api-key",
|
|
585
|
+
requestSchema: null,
|
|
586
|
+
responseSchema: taskArraySchema,
|
|
587
|
+
tags: ["tasks", "query"],
|
|
588
|
+
stability: "stable"
|
|
589
|
+
},
|
|
590
|
+
{
|
|
591
|
+
id: "tasks.create",
|
|
592
|
+
method: "POST",
|
|
593
|
+
path: "/api/tasks",
|
|
594
|
+
description: "Create a task with a title, optional description, priority, and project.",
|
|
595
|
+
auth: "optional-api-key",
|
|
596
|
+
requestSchema: {
|
|
597
|
+
type: "object",
|
|
598
|
+
properties: {
|
|
599
|
+
title: { type: "string" },
|
|
600
|
+
description: { type: "string" },
|
|
601
|
+
priority: { type: "string", enum: TASK_PRIORITIES },
|
|
602
|
+
project_id: { type: "string" }
|
|
603
|
+
},
|
|
604
|
+
required: ["title"],
|
|
605
|
+
additionalProperties: false
|
|
606
|
+
},
|
|
607
|
+
responseSchema: taskSchema,
|
|
608
|
+
tags: ["tasks", "mutation"],
|
|
609
|
+
stability: "stable"
|
|
610
|
+
},
|
|
611
|
+
{
|
|
612
|
+
id: "tasks.read",
|
|
613
|
+
method: "GET",
|
|
614
|
+
path: "/api/tasks/:id",
|
|
615
|
+
description: "Read a single task by full or partial id.",
|
|
616
|
+
auth: "optional-api-key",
|
|
617
|
+
requestSchema: null,
|
|
618
|
+
responseSchema: taskSchema,
|
|
619
|
+
tags: ["tasks", "query"],
|
|
620
|
+
stability: "stable"
|
|
621
|
+
},
|
|
622
|
+
{
|
|
623
|
+
id: "tasks.update",
|
|
624
|
+
method: "PATCH",
|
|
625
|
+
path: "/api/tasks/:id",
|
|
626
|
+
description: "Update a task with optimistic locking through the current version.",
|
|
627
|
+
auth: "optional-api-key",
|
|
628
|
+
requestSchema: objectSchema,
|
|
629
|
+
responseSchema: taskSchema,
|
|
630
|
+
tags: ["tasks", "mutation"],
|
|
631
|
+
stability: "stable"
|
|
632
|
+
},
|
|
633
|
+
{
|
|
634
|
+
id: "tasks.complete",
|
|
635
|
+
method: "POST",
|
|
636
|
+
path: "/api/tasks/:id/complete",
|
|
637
|
+
description: "Mark a task complete and return its updated summary.",
|
|
638
|
+
auth: "optional-api-key",
|
|
639
|
+
requestSchema: null,
|
|
640
|
+
responseSchema: taskSchema,
|
|
641
|
+
tags: ["tasks", "workflow"],
|
|
642
|
+
stability: "stable"
|
|
643
|
+
},
|
|
644
|
+
{
|
|
645
|
+
id: "tasks.claim",
|
|
646
|
+
method: "POST",
|
|
647
|
+
path: "/api/tasks/claim",
|
|
648
|
+
description: "Atomically claim the next available task for an agent.",
|
|
649
|
+
auth: "optional-api-key",
|
|
650
|
+
requestSchema: {
|
|
651
|
+
type: "object",
|
|
652
|
+
properties: {
|
|
653
|
+
agent_id: { type: "string" },
|
|
654
|
+
project_id: { type: "string" }
|
|
655
|
+
},
|
|
656
|
+
additionalProperties: false
|
|
657
|
+
},
|
|
658
|
+
responseSchema: objectSchema,
|
|
659
|
+
tags: ["tasks", "agents", "workflow"],
|
|
660
|
+
stability: "stable"
|
|
661
|
+
},
|
|
662
|
+
{
|
|
663
|
+
id: "agents.register",
|
|
664
|
+
method: "POST",
|
|
665
|
+
path: "/api/agents",
|
|
666
|
+
description: "Register an agent for local task coordination.",
|
|
667
|
+
auth: "optional-api-key",
|
|
668
|
+
requestSchema: {
|
|
669
|
+
type: "object",
|
|
670
|
+
properties: {
|
|
671
|
+
name: { type: "string" },
|
|
672
|
+
description: { type: "string" }
|
|
673
|
+
},
|
|
674
|
+
required: ["name"],
|
|
675
|
+
additionalProperties: true
|
|
676
|
+
},
|
|
677
|
+
responseSchema: objectSchema,
|
|
678
|
+
tags: ["agents"],
|
|
679
|
+
stability: "stable"
|
|
680
|
+
},
|
|
681
|
+
{
|
|
682
|
+
id: "plans.create",
|
|
683
|
+
method: "POST",
|
|
684
|
+
path: "/api/plans",
|
|
685
|
+
description: "Create a plan for grouping related task work.",
|
|
686
|
+
auth: "optional-api-key",
|
|
687
|
+
requestSchema: {
|
|
688
|
+
type: "object",
|
|
689
|
+
properties: {
|
|
690
|
+
name: { type: "string" },
|
|
691
|
+
description: { type: "string" },
|
|
692
|
+
project_id: { type: "string" },
|
|
693
|
+
task_list_id: { type: "string" },
|
|
694
|
+
agent_id: { type: "string" },
|
|
695
|
+
status: { type: "string", enum: PLAN_STATUSES }
|
|
696
|
+
},
|
|
697
|
+
required: ["name"],
|
|
698
|
+
additionalProperties: false
|
|
699
|
+
},
|
|
700
|
+
responseSchema: objectSchema,
|
|
701
|
+
tags: ["plans"],
|
|
702
|
+
stability: "stable"
|
|
703
|
+
},
|
|
704
|
+
{
|
|
705
|
+
id: "streams.tasks",
|
|
706
|
+
method: "GET",
|
|
707
|
+
path: "/api/tasks/stream",
|
|
708
|
+
description: "Subscribe to server-sent task events with optional agent, project, and event filters.",
|
|
709
|
+
auth: "optional-api-key",
|
|
710
|
+
requestSchema: null,
|
|
711
|
+
responseSchema: {
|
|
712
|
+
type: "object",
|
|
713
|
+
properties: {
|
|
714
|
+
type: { type: "string" },
|
|
715
|
+
timestamp: { type: "string" }
|
|
716
|
+
},
|
|
717
|
+
additionalProperties: true
|
|
718
|
+
},
|
|
719
|
+
tags: ["tasks", "events"],
|
|
720
|
+
stability: "experimental"
|
|
721
|
+
}
|
|
722
|
+
];
|
|
723
|
+
var TODOS_ERROR_CODES = [
|
|
724
|
+
{
|
|
725
|
+
code: VersionConflictError.code,
|
|
726
|
+
name: "VersionConflictError",
|
|
727
|
+
suggestion: VersionConflictError.suggestion,
|
|
728
|
+
httpStatus: 409
|
|
729
|
+
},
|
|
730
|
+
{
|
|
731
|
+
code: TaskNotFoundError.code,
|
|
732
|
+
name: "TaskNotFoundError",
|
|
733
|
+
suggestion: TaskNotFoundError.suggestion,
|
|
734
|
+
httpStatus: 404
|
|
735
|
+
},
|
|
736
|
+
{
|
|
737
|
+
code: ProjectNotFoundError.code,
|
|
738
|
+
name: "ProjectNotFoundError",
|
|
739
|
+
suggestion: ProjectNotFoundError.suggestion,
|
|
740
|
+
httpStatus: 404
|
|
741
|
+
},
|
|
742
|
+
{
|
|
743
|
+
code: PlanNotFoundError.code,
|
|
744
|
+
name: "PlanNotFoundError",
|
|
745
|
+
suggestion: PlanNotFoundError.suggestion,
|
|
746
|
+
httpStatus: 404
|
|
747
|
+
},
|
|
748
|
+
{
|
|
749
|
+
code: LockError.code,
|
|
750
|
+
name: "LockError",
|
|
751
|
+
suggestion: LockError.suggestion,
|
|
752
|
+
httpStatus: 409
|
|
753
|
+
},
|
|
754
|
+
{
|
|
755
|
+
code: AgentNotFoundError.code,
|
|
756
|
+
name: "AgentNotFoundError",
|
|
757
|
+
suggestion: AgentNotFoundError.suggestion,
|
|
758
|
+
httpStatus: 404
|
|
759
|
+
},
|
|
760
|
+
{
|
|
761
|
+
code: TaskListNotFoundError.code,
|
|
762
|
+
name: "TaskListNotFoundError",
|
|
763
|
+
suggestion: TaskListNotFoundError.suggestion,
|
|
764
|
+
httpStatus: 404
|
|
765
|
+
},
|
|
766
|
+
{
|
|
767
|
+
code: DependencyCycleError.code,
|
|
768
|
+
name: "DependencyCycleError",
|
|
769
|
+
suggestion: DependencyCycleError.suggestion,
|
|
770
|
+
httpStatus: 409
|
|
771
|
+
},
|
|
772
|
+
{
|
|
773
|
+
code: CompletionGuardError.code,
|
|
774
|
+
name: "CompletionGuardError",
|
|
775
|
+
suggestion: CompletionGuardError.suggestion,
|
|
776
|
+
httpStatus: 409
|
|
777
|
+
},
|
|
778
|
+
{
|
|
779
|
+
code: DispatchNotFoundError.code,
|
|
780
|
+
name: "DispatchNotFoundError",
|
|
781
|
+
suggestion: DispatchNotFoundError.suggestion,
|
|
782
|
+
httpStatus: 404
|
|
783
|
+
}
|
|
784
|
+
];
|
|
785
|
+
function source2(version) {
|
|
786
|
+
return {
|
|
787
|
+
packageName: "@hasna/todos",
|
|
788
|
+
repository: "hasna/todos",
|
|
789
|
+
version
|
|
790
|
+
};
|
|
791
|
+
}
|
|
792
|
+
function createContractsManifest(options = {}) {
|
|
793
|
+
const version = options.version ?? getPackageVersion(import.meta.url);
|
|
794
|
+
const generatedAt = options.generatedAt ?? new Date().toISOString();
|
|
795
|
+
return {
|
|
796
|
+
schemaVersion: 1,
|
|
797
|
+
generatedAt,
|
|
798
|
+
package: source2(version),
|
|
799
|
+
values: {
|
|
800
|
+
taskStatuses: TASK_STATUSES,
|
|
801
|
+
taskPriorities: TASK_PRIORITIES,
|
|
802
|
+
planStatuses: PLAN_STATUSES,
|
|
803
|
+
dispatchStatuses: DISPATCH_STATUSES
|
|
804
|
+
},
|
|
805
|
+
apiRoutes: TODOS_API_ROUTES,
|
|
806
|
+
errorCodes: TODOS_ERROR_CODES,
|
|
807
|
+
jsonOutputs: createJsonContractsManifest({ version, generatedAt })
|
|
808
|
+
};
|
|
809
|
+
}
|
|
810
|
+
var TODOS_CONTRACTS = createContractsManifest({
|
|
811
|
+
generatedAt: "1970-01-01T00:00:00.000Z"
|
|
812
|
+
});
|
|
813
|
+
|
|
814
|
+
// src/mcp/token-utils.ts
|
|
815
|
+
var CORE_MCP_TOOLS = new Set([
|
|
816
|
+
"add_comment",
|
|
817
|
+
"bootstrap",
|
|
818
|
+
"claim_next_task",
|
|
819
|
+
"complete_task",
|
|
820
|
+
"create_task",
|
|
821
|
+
"fail_task",
|
|
822
|
+
"get_context",
|
|
823
|
+
"get_health",
|
|
824
|
+
"get_next_task",
|
|
825
|
+
"get_status",
|
|
826
|
+
"get_task",
|
|
827
|
+
"get_tasks_changed_since",
|
|
828
|
+
"heartbeat",
|
|
829
|
+
"list_agents",
|
|
830
|
+
"list_tasks",
|
|
831
|
+
"register_agent",
|
|
832
|
+
"release_agent",
|
|
833
|
+
"start_task",
|
|
834
|
+
"suggest_agent_name"
|
|
835
|
+
]);
|
|
836
|
+
var MCP_TOOL_GROUPS = {
|
|
837
|
+
core: [...CORE_MCP_TOOLS],
|
|
838
|
+
tasks: [
|
|
839
|
+
"archive_completed",
|
|
840
|
+
"approve_task",
|
|
841
|
+
"bulk_create_tasks",
|
|
842
|
+
"bulk_delete_tasks",
|
|
843
|
+
"bulk_update_tasks",
|
|
844
|
+
"cancel_task",
|
|
845
|
+
"claim_task",
|
|
846
|
+
"clone_task",
|
|
847
|
+
"delete_task",
|
|
848
|
+
"extend_task",
|
|
849
|
+
"get_active_work",
|
|
850
|
+
"get_archived_tasks",
|
|
851
|
+
"get_blocked_tasks",
|
|
852
|
+
"get_blocking_tasks",
|
|
853
|
+
"get_my_tasks",
|
|
854
|
+
"get_review_queue",
|
|
855
|
+
"get_stale_tasks",
|
|
856
|
+
"list_my_tasks",
|
|
857
|
+
"move_task",
|
|
858
|
+
"patrol_tasks",
|
|
859
|
+
"prioritize_task",
|
|
860
|
+
"reassign_task",
|
|
861
|
+
"release_task",
|
|
862
|
+
"reschedule_task",
|
|
863
|
+
"search_tasks",
|
|
864
|
+
"standup",
|
|
865
|
+
"task_context",
|
|
866
|
+
"unarchive_task",
|
|
867
|
+
"update_task"
|
|
868
|
+
],
|
|
869
|
+
projects: [
|
|
870
|
+
"create_plan",
|
|
871
|
+
"create_project",
|
|
872
|
+
"create_task_list",
|
|
873
|
+
"delete_plan",
|
|
874
|
+
"delete_project",
|
|
875
|
+
"delete_task_list",
|
|
876
|
+
"get_focus",
|
|
877
|
+
"get_plan",
|
|
878
|
+
"get_project",
|
|
879
|
+
"get_task_list",
|
|
880
|
+
"list_plans",
|
|
881
|
+
"list_projects",
|
|
882
|
+
"list_task_lists",
|
|
883
|
+
"set_focus",
|
|
884
|
+
"unfocus",
|
|
885
|
+
"update_plan",
|
|
886
|
+
"update_project",
|
|
887
|
+
"update_task_list"
|
|
888
|
+
],
|
|
889
|
+
resources: [
|
|
890
|
+
"add_task_dependency",
|
|
891
|
+
"add_task_file",
|
|
892
|
+
"add_task_relationship",
|
|
893
|
+
"bulk_find_tasks_by_files",
|
|
894
|
+
"check_file_lock",
|
|
895
|
+
"create_comment",
|
|
896
|
+
"delete_comment",
|
|
897
|
+
"detect_file_relationships",
|
|
898
|
+
"find_path",
|
|
899
|
+
"find_task_by_commit",
|
|
900
|
+
"find_tasks_by_file",
|
|
901
|
+
"get_comments",
|
|
902
|
+
"get_critical_path",
|
|
903
|
+
"get_file_heat_map",
|
|
904
|
+
"get_impact_analysis",
|
|
905
|
+
"get_latest_handoff",
|
|
906
|
+
"get_related_entities",
|
|
907
|
+
"get_task_commits",
|
|
908
|
+
"get_task_dependencies",
|
|
909
|
+
"get_task_relationships",
|
|
910
|
+
"get_task_watchers",
|
|
911
|
+
"link_task_to_commit",
|
|
912
|
+
"list_active_files",
|
|
913
|
+
"list_comments",
|
|
914
|
+
"list_file_locks",
|
|
915
|
+
"list_task_files",
|
|
916
|
+
"lock_file",
|
|
917
|
+
"log_time",
|
|
918
|
+
"remove_task_dependency",
|
|
919
|
+
"remove_task_relationship",
|
|
920
|
+
"sync_kg",
|
|
921
|
+
"unlock_file",
|
|
922
|
+
"unwatch_task",
|
|
923
|
+
"update_comment",
|
|
924
|
+
"watch_task"
|
|
925
|
+
],
|
|
926
|
+
agents: [
|
|
927
|
+
"auto_assign_task",
|
|
928
|
+
"delete_agent",
|
|
929
|
+
"get_agent",
|
|
930
|
+
"get_agent_metrics",
|
|
931
|
+
"get_capable_agents",
|
|
932
|
+
"get_leaderboard",
|
|
933
|
+
"get_my_workload",
|
|
934
|
+
"get_org_chart",
|
|
935
|
+
"get_project_org_chart",
|
|
936
|
+
"get_time_report",
|
|
937
|
+
"list_project_agent_roles",
|
|
938
|
+
"rebalance_workload",
|
|
939
|
+
"rename_agent",
|
|
940
|
+
"set_project_agent_role",
|
|
941
|
+
"set_reports_to",
|
|
942
|
+
"unarchive_agent",
|
|
943
|
+
"update_agent"
|
|
944
|
+
],
|
|
945
|
+
metadata: [
|
|
946
|
+
"create_label",
|
|
947
|
+
"create_tag",
|
|
948
|
+
"delete_label",
|
|
949
|
+
"delete_tag",
|
|
950
|
+
"get_label",
|
|
951
|
+
"get_recent_activity",
|
|
952
|
+
"get_tag",
|
|
953
|
+
"get_task_graph",
|
|
954
|
+
"get_task_history",
|
|
955
|
+
"get_task_stats",
|
|
956
|
+
"list_labels",
|
|
957
|
+
"list_tags",
|
|
958
|
+
"search_tools",
|
|
959
|
+
"describe_tools",
|
|
960
|
+
"update_label",
|
|
961
|
+
"update_tag"
|
|
962
|
+
],
|
|
963
|
+
dispatch: [
|
|
964
|
+
"cancel_dispatch",
|
|
965
|
+
"dispatch_task_list",
|
|
966
|
+
"dispatch_tasks",
|
|
967
|
+
"dispatch_to_multiple",
|
|
968
|
+
"list_dispatches",
|
|
969
|
+
"run_due_dispatches"
|
|
970
|
+
],
|
|
971
|
+
templates: [
|
|
972
|
+
"create_task_from_template",
|
|
973
|
+
"create_template",
|
|
974
|
+
"delete_template",
|
|
975
|
+
"export_template",
|
|
976
|
+
"import_template",
|
|
977
|
+
"init_templates",
|
|
978
|
+
"list_templates",
|
|
979
|
+
"preview_template",
|
|
980
|
+
"template_history",
|
|
981
|
+
"update_template"
|
|
982
|
+
],
|
|
983
|
+
webhooks: ["create_webhook", "delete_webhook", "list_webhooks"],
|
|
984
|
+
machines: [
|
|
985
|
+
"machines_archive",
|
|
986
|
+
"machines_delete",
|
|
987
|
+
"machines_list",
|
|
988
|
+
"machines_register",
|
|
989
|
+
"machines_set_primary",
|
|
990
|
+
"machines_unarchive"
|
|
991
|
+
],
|
|
992
|
+
maintenance: ["extract_todos", "notify_upcoming_deadlines", "score_task"]
|
|
993
|
+
};
|
|
994
|
+
var MCP_PROFILE_GROUPS = {
|
|
995
|
+
minimal: ["core"],
|
|
996
|
+
core: ["core"],
|
|
997
|
+
standard: ["core", "tasks", "projects", "resources", "agents", "metadata"],
|
|
998
|
+
agent: ["core", "tasks", "projects", "resources"],
|
|
999
|
+
maintainer: ["core", "tasks", "projects", "resources", "agents", "metadata", "dispatch", "maintenance"]
|
|
1000
|
+
};
|
|
1001
|
+
function splitTokens(value) {
|
|
1002
|
+
return (value || "").split(",").map((item) => item.trim().toLowerCase()).filter(Boolean);
|
|
1003
|
+
}
|
|
1004
|
+
function addGroupTools(toolNames, groupName) {
|
|
1005
|
+
const tools = MCP_TOOL_GROUPS[groupName];
|
|
1006
|
+
if (!tools)
|
|
1007
|
+
return false;
|
|
1008
|
+
for (const tool of tools)
|
|
1009
|
+
toolNames.add(tool);
|
|
1010
|
+
return true;
|
|
1011
|
+
}
|
|
1012
|
+
function shouldRegisterToolForProfile(name, profileValue = process.env["TODOS_PROFILE"], groupValue = process.env["TODOS_TOOL_GROUPS"]) {
|
|
1013
|
+
const profileTokens = splitTokens(profileValue || "minimal");
|
|
1014
|
+
const groupTokens = splitTokens(groupValue);
|
|
1015
|
+
if (profileTokens.includes("full") || profileTokens.includes("all"))
|
|
1016
|
+
return true;
|
|
1017
|
+
const tools = new Set;
|
|
1018
|
+
let matchedProfile = false;
|
|
1019
|
+
for (const token of profileTokens) {
|
|
1020
|
+
const profileGroups = MCP_PROFILE_GROUPS[token];
|
|
1021
|
+
if (profileGroups) {
|
|
1022
|
+
matchedProfile = true;
|
|
1023
|
+
for (const group of profileGroups)
|
|
1024
|
+
addGroupTools(tools, group);
|
|
1025
|
+
continue;
|
|
1026
|
+
}
|
|
1027
|
+
if (addGroupTools(tools, token)) {
|
|
1028
|
+
matchedProfile = true;
|
|
1029
|
+
continue;
|
|
1030
|
+
}
|
|
1031
|
+
if (token.startsWith("tool:")) {
|
|
1032
|
+
matchedProfile = true;
|
|
1033
|
+
tools.add(token.slice("tool:".length));
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
if (!matchedProfile) {
|
|
1037
|
+
addGroupTools(tools, "core");
|
|
1038
|
+
}
|
|
1039
|
+
for (const token of groupTokens) {
|
|
1040
|
+
if (token === "full" || token === "all")
|
|
1041
|
+
return true;
|
|
1042
|
+
if (!addGroupTools(tools, token) && token.startsWith("tool:")) {
|
|
1043
|
+
tools.add(token.slice("tool:".length));
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
return tools.has(name);
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
// src/mcp.ts
|
|
1050
|
+
function source3(version) {
|
|
1051
|
+
return {
|
|
1052
|
+
packageName: "@hasna/todos",
|
|
1053
|
+
repository: "hasna/todos",
|
|
1054
|
+
version
|
|
1055
|
+
};
|
|
1056
|
+
}
|
|
1057
|
+
function uniqueSorted(values) {
|
|
1058
|
+
return [...new Set(values)].sort((left, right) => left.localeCompare(right));
|
|
1059
|
+
}
|
|
1060
|
+
function getAllMcpToolNames() {
|
|
1061
|
+
return uniqueSorted(Object.values(MCP_TOOL_GROUPS).flatMap((tools) => [...tools]));
|
|
1062
|
+
}
|
|
1063
|
+
function groupsForTool(toolName) {
|
|
1064
|
+
return Object.entries(MCP_TOOL_GROUPS).filter(([, tools]) => tools.includes(toolName)).map(([group]) => group).sort((left, right) => left.localeCompare(right));
|
|
1065
|
+
}
|
|
1066
|
+
function profilesForTool(toolName) {
|
|
1067
|
+
return Object.entries(MCP_PROFILE_GROUPS).filter(([, groups]) => groups.some((group) => MCP_TOOL_GROUPS[group]?.includes(toolName))).map(([profile]) => profile).sort((left, right) => left.localeCompare(right));
|
|
1068
|
+
}
|
|
1069
|
+
function getMcpToolNames(options = {}) {
|
|
1070
|
+
const profile = options.profile ?? "minimal";
|
|
1071
|
+
const groups = options.groups ?? "";
|
|
1072
|
+
return getAllMcpToolNames().filter((toolName) => shouldRegisterToolForProfile(toolName, profile, groups));
|
|
1073
|
+
}
|
|
1074
|
+
function createMcpManifest(options = {}) {
|
|
1075
|
+
const version = options.version ?? getPackageVersion(import.meta.url);
|
|
1076
|
+
return {
|
|
1077
|
+
schemaVersion: 1,
|
|
1078
|
+
generatedAt: options.generatedAt ?? new Date().toISOString(),
|
|
1079
|
+
package: source3(version),
|
|
1080
|
+
server: {
|
|
1081
|
+
name: "todos",
|
|
1082
|
+
binary: "todos-mcp",
|
|
1083
|
+
transport: "stdio",
|
|
1084
|
+
profileEnvironmentVariable: "TODOS_PROFILE",
|
|
1085
|
+
groupEnvironmentVariable: "TODOS_TOOL_GROUPS"
|
|
1086
|
+
},
|
|
1087
|
+
groups: MCP_TOOL_GROUPS,
|
|
1088
|
+
profiles: MCP_PROFILE_GROUPS,
|
|
1089
|
+
tools: getAllMcpToolNames().map((toolName) => ({
|
|
1090
|
+
name: toolName,
|
|
1091
|
+
groups: groupsForTool(toolName),
|
|
1092
|
+
profiles: profilesForTool(toolName),
|
|
1093
|
+
core: CORE_MCP_TOOLS.has(toolName),
|
|
1094
|
+
stability: CORE_MCP_TOOLS.has(toolName) ? "stable" : "experimental"
|
|
1095
|
+
}))
|
|
1096
|
+
};
|
|
1097
|
+
}
|
|
1098
|
+
var TODOS_MCP_MANIFEST = createMcpManifest({
|
|
1099
|
+
generatedAt: "1970-01-01T00:00:00.000Z"
|
|
1100
|
+
});
|
|
1101
|
+
|
|
1102
|
+
// src/capabilities.ts
|
|
1103
|
+
var packageName = "@hasna/todos";
|
|
1104
|
+
var repository = "hasna/todos";
|
|
1105
|
+
var objectSchema2 = {
|
|
1106
|
+
type: "object",
|
|
1107
|
+
additionalProperties: true
|
|
1108
|
+
};
|
|
1109
|
+
var taskSchema2 = {
|
|
1110
|
+
type: "object",
|
|
1111
|
+
properties: {
|
|
1112
|
+
id: { type: "string" },
|
|
1113
|
+
title: { type: "string" },
|
|
1114
|
+
status: { type: "string" },
|
|
1115
|
+
priority: { type: "string" }
|
|
1116
|
+
},
|
|
1117
|
+
required: ["id", "title", "status", "priority"],
|
|
1118
|
+
additionalProperties: true
|
|
1119
|
+
};
|
|
1120
|
+
function source4(version) {
|
|
1121
|
+
return { packageName, repository, version };
|
|
1122
|
+
}
|
|
1123
|
+
function capability(version, input) {
|
|
1124
|
+
return {
|
|
1125
|
+
...input,
|
|
1126
|
+
source: source4(version)
|
|
1127
|
+
};
|
|
1128
|
+
}
|
|
1129
|
+
function buildCapabilities(version) {
|
|
1130
|
+
return [
|
|
1131
|
+
capability(version, {
|
|
1132
|
+
id: "cli.add-task",
|
|
1133
|
+
kind: "cli",
|
|
1134
|
+
name: "todos add",
|
|
1135
|
+
description: "Create a local task from the command line.",
|
|
1136
|
+
tags: ["tasks", "cli", "local"],
|
|
1137
|
+
docsPath: "README.md#cli",
|
|
1138
|
+
stability: "stable",
|
|
1139
|
+
inputSchema: {
|
|
1140
|
+
type: "object",
|
|
1141
|
+
properties: {
|
|
1142
|
+
title: { type: "string" },
|
|
1143
|
+
description: { type: "string" },
|
|
1144
|
+
priority: { type: "string", enum: ["low", "medium", "high", "critical"] },
|
|
1145
|
+
tags: { type: "array", items: { type: "string" } }
|
|
1146
|
+
},
|
|
1147
|
+
required: ["title"],
|
|
1148
|
+
additionalProperties: false
|
|
1149
|
+
},
|
|
1150
|
+
outputSchema: taskSchema2
|
|
1151
|
+
}),
|
|
1152
|
+
capability(version, {
|
|
1153
|
+
id: "cli.list-tasks",
|
|
1154
|
+
kind: "cli",
|
|
1155
|
+
name: "todos list",
|
|
1156
|
+
description: "List local tasks with filters for status, priority, assignment, tags, and task lists.",
|
|
1157
|
+
tags: ["tasks", "cli", "query"],
|
|
1158
|
+
docsPath: "README.md#cli",
|
|
1159
|
+
stability: "stable",
|
|
1160
|
+
inputSchema: {
|
|
1161
|
+
type: "object",
|
|
1162
|
+
properties: {
|
|
1163
|
+
status: { type: "string" },
|
|
1164
|
+
priority: { type: "string" },
|
|
1165
|
+
tags: { type: "array", items: { type: "string" } },
|
|
1166
|
+
limit: { type: "number" }
|
|
1167
|
+
},
|
|
1168
|
+
additionalProperties: false
|
|
1169
|
+
},
|
|
1170
|
+
outputSchema: {
|
|
1171
|
+
type: "array",
|
|
1172
|
+
items: taskSchema2
|
|
1173
|
+
}
|
|
1174
|
+
}),
|
|
1175
|
+
capability(version, {
|
|
1176
|
+
id: "cli.show-task",
|
|
1177
|
+
kind: "cli",
|
|
1178
|
+
name: "todos show",
|
|
1179
|
+
description: "Show full local task details by id or partial id.",
|
|
1180
|
+
tags: ["tasks", "cli", "query"],
|
|
1181
|
+
docsPath: "README.md#cli",
|
|
1182
|
+
stability: "stable",
|
|
1183
|
+
inputSchema: {
|
|
1184
|
+
type: "object",
|
|
1185
|
+
properties: {
|
|
1186
|
+
id: { type: "string" }
|
|
1187
|
+
},
|
|
1188
|
+
required: ["id"],
|
|
1189
|
+
additionalProperties: false
|
|
1190
|
+
},
|
|
1191
|
+
outputSchema: taskSchema2
|
|
1192
|
+
}),
|
|
1193
|
+
capability(version, {
|
|
1194
|
+
id: "sdk.client",
|
|
1195
|
+
kind: "sdk",
|
|
1196
|
+
name: "createClient",
|
|
1197
|
+
description: "Create a REST SDK client for cross-process and cross-machine task operations.",
|
|
1198
|
+
tags: ["sdk", "api", "client"],
|
|
1199
|
+
docsPath: "sdk/README.md",
|
|
1200
|
+
stability: "stable",
|
|
1201
|
+
inputSchema: {
|
|
1202
|
+
type: "object",
|
|
1203
|
+
properties: {
|
|
1204
|
+
baseUrl: { type: "string" },
|
|
1205
|
+
apiKey: { type: "string" }
|
|
1206
|
+
},
|
|
1207
|
+
required: ["baseUrl"],
|
|
1208
|
+
additionalProperties: true
|
|
1209
|
+
},
|
|
1210
|
+
outputSchema: objectSchema2
|
|
1211
|
+
}),
|
|
1212
|
+
capability(version, {
|
|
1213
|
+
id: "mcp.create-task",
|
|
1214
|
+
kind: "mcp",
|
|
1215
|
+
name: "create_task",
|
|
1216
|
+
description: "Create a task through the MCP server.",
|
|
1217
|
+
tags: ["mcp", "tasks", "create"],
|
|
1218
|
+
docsPath: "README.md#mcp",
|
|
1219
|
+
stability: "stable",
|
|
1220
|
+
inputSchema: {
|
|
1221
|
+
type: "object",
|
|
1222
|
+
properties: {
|
|
1223
|
+
title: { type: "string" },
|
|
1224
|
+
description: { type: "string" },
|
|
1225
|
+
priority: { type: "string", enum: ["low", "medium", "high", "critical"] },
|
|
1226
|
+
project_id: { type: "string" },
|
|
1227
|
+
tags: { type: "array", items: { type: "string" } }
|
|
1228
|
+
},
|
|
1229
|
+
required: ["title"],
|
|
1230
|
+
additionalProperties: false
|
|
1231
|
+
},
|
|
1232
|
+
outputSchema: taskSchema2
|
|
1233
|
+
}),
|
|
1234
|
+
capability(version, {
|
|
1235
|
+
id: "mcp.claim-next-task",
|
|
1236
|
+
kind: "mcp",
|
|
1237
|
+
name: "claim_next_task",
|
|
1238
|
+
description: "Atomically claim and start the best available pending task for an agent.",
|
|
1239
|
+
tags: ["mcp", "tasks", "agents", "workflow"],
|
|
1240
|
+
docsPath: "README.md#mcp",
|
|
1241
|
+
stability: "stable",
|
|
1242
|
+
inputSchema: {
|
|
1243
|
+
type: "object",
|
|
1244
|
+
properties: {
|
|
1245
|
+
agent_id: { type: "string" },
|
|
1246
|
+
project_id: { type: "string" },
|
|
1247
|
+
task_list_id: { type: "string" },
|
|
1248
|
+
plan_id: { type: "string" },
|
|
1249
|
+
tags: { type: "array", items: { type: "string" } }
|
|
1250
|
+
},
|
|
1251
|
+
required: ["agent_id"],
|
|
1252
|
+
additionalProperties: false
|
|
1253
|
+
},
|
|
1254
|
+
outputSchema: taskSchema2
|
|
1255
|
+
}),
|
|
1256
|
+
capability(version, {
|
|
1257
|
+
id: "mcp.get-status",
|
|
1258
|
+
kind: "mcp",
|
|
1259
|
+
name: "get_status",
|
|
1260
|
+
description: "Read queue status or task-specific status through the MCP server.",
|
|
1261
|
+
tags: ["mcp", "tasks", "status"],
|
|
1262
|
+
docsPath: "README.md#mcp",
|
|
1263
|
+
stability: "stable",
|
|
1264
|
+
inputSchema: {
|
|
1265
|
+
type: "object",
|
|
1266
|
+
properties: {
|
|
1267
|
+
task_id: { type: "string" },
|
|
1268
|
+
project_id: { type: "string" },
|
|
1269
|
+
task_list_id: { type: "string" },
|
|
1270
|
+
agent_id: { type: "string" }
|
|
1271
|
+
},
|
|
1272
|
+
additionalProperties: false
|
|
1273
|
+
},
|
|
1274
|
+
outputSchema: objectSchema2
|
|
1275
|
+
}),
|
|
1276
|
+
capability(version, {
|
|
1277
|
+
id: "server.local-api",
|
|
1278
|
+
kind: "server",
|
|
1279
|
+
name: "todos-serve",
|
|
1280
|
+
description: "Start the local HTTP server for task APIs and dashboard support.",
|
|
1281
|
+
tags: ["server", "api", "local"],
|
|
1282
|
+
docsPath: "README.md#server",
|
|
1283
|
+
stability: "experimental",
|
|
1284
|
+
inputSchema: {
|
|
1285
|
+
type: "object",
|
|
1286
|
+
properties: {
|
|
1287
|
+
port: { type: "number" },
|
|
1288
|
+
host: { type: "string" }
|
|
1289
|
+
},
|
|
1290
|
+
additionalProperties: true
|
|
1291
|
+
},
|
|
1292
|
+
outputSchema: objectSchema2
|
|
1293
|
+
})
|
|
1294
|
+
];
|
|
1295
|
+
}
|
|
1296
|
+
function createCapabilityManifest(options = {}) {
|
|
1297
|
+
const version = options.version ?? getPackageVersion(import.meta.url);
|
|
1298
|
+
return {
|
|
1299
|
+
schemaVersion: 1,
|
|
1300
|
+
generatedAt: options.generatedAt ?? new Date().toISOString(),
|
|
1301
|
+
package: source4(version),
|
|
1302
|
+
capabilities: buildCapabilities(version)
|
|
1303
|
+
};
|
|
1304
|
+
}
|
|
1305
|
+
var TODOS_CAPABILITIES = createCapabilityManifest({
|
|
1306
|
+
generatedAt: "1970-01-01T00:00:00.000Z"
|
|
1307
|
+
}).capabilities;
|
|
1308
|
+
|
|
1309
|
+
// src/registry.ts
|
|
1310
|
+
var TODOS_PACKAGE_EXPORTS = [
|
|
1311
|
+
{
|
|
1312
|
+
subpath: ".",
|
|
1313
|
+
import: "./dist/index.js",
|
|
1314
|
+
types: "./dist/index.d.ts",
|
|
1315
|
+
description: "Root SDK and local database exports kept for backward compatibility.",
|
|
1316
|
+
stability: "stable"
|
|
1317
|
+
},
|
|
1318
|
+
{
|
|
1319
|
+
subpath: "./sdk",
|
|
1320
|
+
import: "./dist/sdk/index.js",
|
|
1321
|
+
types: "./dist/sdk/index.d.ts",
|
|
1322
|
+
description: "REST SDK client and SDK response/error types.",
|
|
1323
|
+
stability: "stable"
|
|
1324
|
+
},
|
|
1325
|
+
{
|
|
1326
|
+
subpath: "./mcp",
|
|
1327
|
+
import: "./dist/mcp.js",
|
|
1328
|
+
types: "./dist/mcp.d.ts",
|
|
1329
|
+
description: "Side-effect-free MCP manifest, profile, and tool group contracts.",
|
|
1330
|
+
stability: "stable"
|
|
1331
|
+
},
|
|
1332
|
+
{
|
|
1333
|
+
subpath: "./registry",
|
|
1334
|
+
import: "./dist/registry.js",
|
|
1335
|
+
types: "./dist/registry.d.ts",
|
|
1336
|
+
description: "Package registry manifest combining exports, capabilities, contracts, and MCP metadata.",
|
|
1337
|
+
stability: "stable"
|
|
1338
|
+
},
|
|
1339
|
+
{
|
|
1340
|
+
subpath: "./contracts",
|
|
1341
|
+
import: "./dist/contracts.js",
|
|
1342
|
+
types: "./dist/contracts.d.ts",
|
|
1343
|
+
description: "Stable API, enum, and error contracts for integrations.",
|
|
1344
|
+
stability: "stable"
|
|
1345
|
+
},
|
|
1346
|
+
{
|
|
1347
|
+
subpath: "./storage",
|
|
1348
|
+
import: "./dist/storage.js",
|
|
1349
|
+
types: "./dist/storage.d.ts",
|
|
1350
|
+
description: "Storage and service adapter contracts for local SQLite implementations.",
|
|
1351
|
+
stability: "stable"
|
|
1352
|
+
}
|
|
1353
|
+
];
|
|
1354
|
+
function source5(version) {
|
|
1355
|
+
return {
|
|
1356
|
+
packageName: "@hasna/todos",
|
|
1357
|
+
repository: "hasna/todos",
|
|
1358
|
+
version
|
|
1359
|
+
};
|
|
1360
|
+
}
|
|
1361
|
+
function createTodosRegistry(options = {}) {
|
|
1362
|
+
const version = options.version ?? getPackageVersion(import.meta.url);
|
|
1363
|
+
const generatedAt = options.generatedAt ?? new Date().toISOString();
|
|
1364
|
+
return {
|
|
1365
|
+
schemaVersion: 1,
|
|
1366
|
+
generatedAt,
|
|
1367
|
+
package: source5(version),
|
|
1368
|
+
exports: TODOS_PACKAGE_EXPORTS,
|
|
1369
|
+
jsonContractDocsPath: "docs/json-contracts.md",
|
|
1370
|
+
capabilities: createCapabilityManifest({ version, generatedAt }),
|
|
1371
|
+
contracts: createContractsManifest({ version, generatedAt }),
|
|
1372
|
+
mcp: createMcpManifest({ version, generatedAt })
|
|
1373
|
+
};
|
|
1374
|
+
}
|
|
1375
|
+
var TODOS_REGISTRY = createTodosRegistry({
|
|
1376
|
+
generatedAt: "1970-01-01T00:00:00.000Z"
|
|
1377
|
+
});
|
|
1378
|
+
export {
|
|
1379
|
+
createTodosRegistry,
|
|
1380
|
+
TODOS_REGISTRY,
|
|
1381
|
+
TODOS_PACKAGE_EXPORTS
|
|
1382
|
+
};
|