@jamesaphoenix/tx 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.
@@ -0,0 +1,453 @@
1
+ /**
2
+ * MCP Server Infrastructure
3
+ *
4
+ * Provides:
5
+ * - initRuntime: Initialize Effect runtime ONCE at startup
6
+ * - runEffect: Run Effect using the pre-built runtime
7
+ * - mcpResponse/mcpError: Format MCP responses
8
+ * - createMcpServer/startMcpServer: Server lifecycle
9
+ */
10
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
11
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
12
+ import { Effect, ManagedRuntime } from "effect";
13
+ import { z } from "zod";
14
+ import { TaskService } from "../services/task-service.js";
15
+ import { ReadyService } from "../services/ready-service.js";
16
+ import { DependencyService } from "../services/dep-service.js";
17
+ import { makeAppLayer } from "../layer.js";
18
+ import { TASK_STATUSES } from "../schema.js";
19
+ // -----------------------------------------------------------------------------
20
+ // Runtime
21
+ // -----------------------------------------------------------------------------
22
+ let managedRuntime = null;
23
+ /**
24
+ * Initialize the Effect runtime ONCE at server startup.
25
+ * Creates the full service layer with database connection.
26
+ */
27
+ export const initRuntime = async (dbPath = ".tx/tasks.db") => {
28
+ if (managedRuntime) {
29
+ return; // Already initialized
30
+ }
31
+ const appLayer = makeAppLayer(dbPath);
32
+ managedRuntime = ManagedRuntime.make(appLayer);
33
+ };
34
+ /**
35
+ * Run an Effect using the pre-built runtime.
36
+ * Must call initRuntime() first.
37
+ */
38
+ export const runEffect = (effect) => {
39
+ if (!managedRuntime) {
40
+ throw new Error("Runtime not initialized. Call initRuntime() first.");
41
+ }
42
+ return managedRuntime.runPromise(effect);
43
+ };
44
+ /**
45
+ * Get the current runtime for advanced use cases.
46
+ * Returns null if not initialized.
47
+ */
48
+ export const getRuntime = () => {
49
+ return managedRuntime;
50
+ };
51
+ /**
52
+ * Dispose of the runtime and release resources.
53
+ * Call when shutting down the server.
54
+ */
55
+ export const disposeRuntime = async () => {
56
+ if (managedRuntime) {
57
+ await managedRuntime.dispose();
58
+ managedRuntime = null;
59
+ }
60
+ };
61
+ // -----------------------------------------------------------------------------
62
+ // Response Formatters
63
+ // -----------------------------------------------------------------------------
64
+ /**
65
+ * Format a successful MCP response with text summary and JSON data.
66
+ */
67
+ export const mcpResponse = (text, data) => ({
68
+ content: [
69
+ { type: "text", text },
70
+ { type: "text", text: JSON.stringify(data) }
71
+ ]
72
+ });
73
+ /**
74
+ * Format an error MCP response.
75
+ */
76
+ export const mcpError = (error) => ({
77
+ content: [{
78
+ type: "text",
79
+ text: `Error: ${error instanceof Error ? error.message : String(error)}`
80
+ }],
81
+ isError: true
82
+ });
83
+ // -----------------------------------------------------------------------------
84
+ // Serialization Helpers
85
+ // -----------------------------------------------------------------------------
86
+ /**
87
+ * Serialize a TaskWithDeps for JSON output.
88
+ * Converts Date objects to ISO strings for proper serialization.
89
+ */
90
+ const serializeTask = (task) => ({
91
+ id: task.id,
92
+ title: task.title,
93
+ description: task.description,
94
+ status: task.status,
95
+ parentId: task.parentId,
96
+ score: task.score,
97
+ createdAt: task.createdAt.toISOString(),
98
+ updatedAt: task.updatedAt.toISOString(),
99
+ completedAt: task.completedAt?.toISOString() ?? null,
100
+ metadata: task.metadata,
101
+ blockedBy: task.blockedBy,
102
+ blocks: task.blocks,
103
+ children: task.children,
104
+ isReady: task.isReady
105
+ });
106
+ // -----------------------------------------------------------------------------
107
+ // Server Creation
108
+ // -----------------------------------------------------------------------------
109
+ /**
110
+ * Create the MCP server with tool registrations.
111
+ */
112
+ export const createMcpServer = () => {
113
+ const server = new McpServer({
114
+ name: "tx",
115
+ version: "0.1.0"
116
+ });
117
+ // ---------------------------------------------------------------------------
118
+ // tx_ready - List tasks that are ready to work on
119
+ // ---------------------------------------------------------------------------
120
+ server.tool("tx_ready", "List tasks ready to be worked on (no incomplete blockers)", { limit: z.number().int().positive().optional().describe("Maximum number of tasks to return (default: 100)") }, async ({ limit }) => {
121
+ try {
122
+ const tasks = await runEffect(Effect.gen(function* () {
123
+ const ready = yield* ReadyService;
124
+ return yield* ready.getReady(limit ?? 100);
125
+ }));
126
+ const serialized = tasks.map(serializeTask);
127
+ return {
128
+ content: [
129
+ { type: "text", text: `Found ${tasks.length} ready task(s)` },
130
+ { type: "text", text: JSON.stringify(serialized) }
131
+ ]
132
+ };
133
+ }
134
+ catch (error) {
135
+ return {
136
+ content: [{ type: "text", text: `Error: ${error instanceof Error ? error.message : String(error)}` }]
137
+ };
138
+ }
139
+ });
140
+ // ---------------------------------------------------------------------------
141
+ // tx_show - Show a single task with full dependency info
142
+ // ---------------------------------------------------------------------------
143
+ server.tool("tx_show", "Show detailed information about a task including dependencies", { id: z.string().describe("Task ID to show") }, async ({ id }) => {
144
+ try {
145
+ const task = await runEffect(Effect.gen(function* () {
146
+ const taskService = yield* TaskService;
147
+ return yield* taskService.getWithDeps(id);
148
+ }));
149
+ const serialized = serializeTask(task);
150
+ return {
151
+ content: [
152
+ { type: "text", text: `Task: ${task.title}` },
153
+ { type: "text", text: JSON.stringify(serialized) }
154
+ ]
155
+ };
156
+ }
157
+ catch (error) {
158
+ return {
159
+ content: [{ type: "text", text: `Error: ${error instanceof Error ? error.message : String(error)}` }]
160
+ };
161
+ }
162
+ });
163
+ // ---------------------------------------------------------------------------
164
+ // tx_list - List tasks with optional filters
165
+ // ---------------------------------------------------------------------------
166
+ server.tool("tx_list", "List tasks with optional filters for status, parent, and limit", {
167
+ status: z.string().optional().describe(`Filter by status: ${TASK_STATUSES.join(", ")}`),
168
+ parentId: z.string().optional().describe("Filter by parent task ID"),
169
+ limit: z.number().int().positive().optional().describe("Maximum number of tasks to return")
170
+ }, async ({ status, parentId, limit }) => {
171
+ try {
172
+ const tasks = await runEffect(Effect.gen(function* () {
173
+ const taskService = yield* TaskService;
174
+ return yield* taskService.listWithDeps({
175
+ status: status,
176
+ parentId: parentId ?? undefined,
177
+ limit: limit ?? undefined
178
+ });
179
+ }));
180
+ const serialized = tasks.map(serializeTask);
181
+ return {
182
+ content: [
183
+ { type: "text", text: `Found ${tasks.length} task(s)` },
184
+ { type: "text", text: JSON.stringify(serialized) }
185
+ ]
186
+ };
187
+ }
188
+ catch (error) {
189
+ return {
190
+ content: [{ type: "text", text: `Error: ${error instanceof Error ? error.message : String(error)}` }]
191
+ };
192
+ }
193
+ });
194
+ // ---------------------------------------------------------------------------
195
+ // tx_children - List children of a task
196
+ // ---------------------------------------------------------------------------
197
+ server.tool("tx_children", "List direct children of a task", { id: z.string().describe("Parent task ID") }, async ({ id }) => {
198
+ try {
199
+ const tasks = await runEffect(Effect.gen(function* () {
200
+ const taskService = yield* TaskService;
201
+ // Use listWithDeps with parentId filter to get TaskWithDeps[]
202
+ return yield* taskService.listWithDeps({ parentId: id });
203
+ }));
204
+ const serialized = tasks.map(serializeTask);
205
+ return {
206
+ content: [
207
+ { type: "text", text: `Found ${tasks.length} child task(s)` },
208
+ { type: "text", text: JSON.stringify(serialized) }
209
+ ]
210
+ };
211
+ }
212
+ catch (error) {
213
+ return {
214
+ content: [{ type: "text", text: `Error: ${error instanceof Error ? error.message : String(error)}` }]
215
+ };
216
+ }
217
+ });
218
+ // ---------------------------------------------------------------------------
219
+ // tx_add - Create a new task
220
+ // ---------------------------------------------------------------------------
221
+ server.tool("tx_add", "Create a new task", {
222
+ title: z.string().describe("Task title (required)"),
223
+ description: z.string().optional().describe("Task description"),
224
+ parentId: z.string().optional().describe("Parent task ID for subtasks"),
225
+ score: z.number().int().optional().describe("Priority score (higher = more important)")
226
+ }, async ({ title, description, parentId, score }) => {
227
+ try {
228
+ const task = await runEffect(Effect.gen(function* () {
229
+ const taskService = yield* TaskService;
230
+ const created = yield* taskService.create({
231
+ title,
232
+ description: description ?? undefined,
233
+ parentId: parentId ?? undefined,
234
+ score: score ?? undefined
235
+ });
236
+ // Return with deps (new task will have no deps, but we follow the pattern)
237
+ return yield* taskService.getWithDeps(created.id);
238
+ }));
239
+ const serialized = serializeTask(task);
240
+ return {
241
+ content: [
242
+ { type: "text", text: `Created task: ${task.id}` },
243
+ { type: "text", text: JSON.stringify(serialized) }
244
+ ]
245
+ };
246
+ }
247
+ catch (error) {
248
+ return {
249
+ content: [{ type: "text", text: `Error: ${error instanceof Error ? error.message : String(error)}` }]
250
+ };
251
+ }
252
+ });
253
+ // ---------------------------------------------------------------------------
254
+ // tx_update - Update an existing task
255
+ // ---------------------------------------------------------------------------
256
+ server.tool("tx_update", "Update an existing task", {
257
+ id: z.string().describe("Task ID to update"),
258
+ title: z.string().optional().describe("New title"),
259
+ description: z.string().optional().describe("New description"),
260
+ status: z.string().optional().describe(`New status: ${TASK_STATUSES.join(", ")}`),
261
+ parentId: z.string().nullable().optional().describe("New parent ID (null to remove parent)"),
262
+ score: z.number().int().optional().describe("New priority score")
263
+ }, async ({ id, title, description, status, parentId, score }) => {
264
+ try {
265
+ const task = await runEffect(Effect.gen(function* () {
266
+ const taskService = yield* TaskService;
267
+ yield* taskService.update(id, {
268
+ title: title ?? undefined,
269
+ description: description ?? undefined,
270
+ status: status,
271
+ parentId: parentId,
272
+ score: score ?? undefined
273
+ });
274
+ // Return with deps after update
275
+ return yield* taskService.getWithDeps(id);
276
+ }));
277
+ const serialized = serializeTask(task);
278
+ return {
279
+ content: [
280
+ { type: "text", text: `Updated task: ${task.id}` },
281
+ { type: "text", text: JSON.stringify(serialized) }
282
+ ]
283
+ };
284
+ }
285
+ catch (error) {
286
+ return {
287
+ content: [{ type: "text", text: `Error: ${error instanceof Error ? error.message : String(error)}` }]
288
+ };
289
+ }
290
+ });
291
+ // ---------------------------------------------------------------------------
292
+ // tx_done - Mark a task as complete
293
+ // ---------------------------------------------------------------------------
294
+ server.tool("tx_done", "Mark a task as complete and return any tasks that are now ready", { id: z.string().describe("Task ID to complete") }, async ({ id }) => {
295
+ try {
296
+ const result = await runEffect(Effect.gen(function* () {
297
+ const taskService = yield* TaskService;
298
+ const readyService = yield* ReadyService;
299
+ // Get tasks that this task blocks (before completing)
300
+ const blocking = yield* readyService.getBlocking(id);
301
+ // Mark the task as done
302
+ yield* taskService.update(id, { status: "done" });
303
+ // Get the updated task with deps
304
+ const completedTask = yield* taskService.getWithDeps(id);
305
+ // Find newly unblocked tasks using batch query
306
+ // Filter to workable statuses (skip done tasks) and get their full deps info in one batch
307
+ const candidateIds = blocking
308
+ .filter(t => ["backlog", "ready", "planning"].includes(t.status))
309
+ .map(t => t.id);
310
+ const candidatesWithDeps = yield* taskService.getWithDepsBatch(candidateIds);
311
+ const nowReady = candidatesWithDeps.filter(t => t.isReady);
312
+ return { completedTask, nowReady };
313
+ }));
314
+ const serializedTask = serializeTask(result.completedTask);
315
+ const serializedNowReady = result.nowReady.map(serializeTask);
316
+ return {
317
+ content: [
318
+ { type: "text", text: `Completed task: ${result.completedTask.id}${result.nowReady.length > 0 ? `. ${result.nowReady.length} task(s) now ready.` : ""}` },
319
+ { type: "text", text: JSON.stringify({ task: serializedTask, nowReady: serializedNowReady }) }
320
+ ]
321
+ };
322
+ }
323
+ catch (error) {
324
+ return {
325
+ content: [{ type: "text", text: `Error: ${error instanceof Error ? error.message : String(error)}` }]
326
+ };
327
+ }
328
+ });
329
+ // ---------------------------------------------------------------------------
330
+ // tx_delete - Delete a task
331
+ // ---------------------------------------------------------------------------
332
+ server.tool("tx_delete", "Delete a task permanently", { id: z.string().describe("Task ID to delete") }, async ({ id }) => {
333
+ try {
334
+ await runEffect(Effect.gen(function* () {
335
+ const taskService = yield* TaskService;
336
+ yield* taskService.remove(id);
337
+ }));
338
+ return {
339
+ content: [
340
+ { type: "text", text: `Deleted task: ${id}` },
341
+ { type: "text", text: JSON.stringify({ success: true, id }) }
342
+ ]
343
+ };
344
+ }
345
+ catch (error) {
346
+ return {
347
+ content: [{ type: "text", text: `Error: ${error instanceof Error ? error.message : String(error)}` }]
348
+ };
349
+ }
350
+ });
351
+ // ---------------------------------------------------------------------------
352
+ // tx_block - Add a dependency (blocker blocks taskId)
353
+ // ---------------------------------------------------------------------------
354
+ server.tool("tx_block", "Add a dependency: blockerId blocks taskId (taskId cannot start until blockerId is done). Rejects circular dependencies.", {
355
+ taskId: z.string().describe("Task ID that will be blocked"),
356
+ blockerId: z.string().describe("Task ID that blocks the other task")
357
+ }, async ({ taskId, blockerId }) => {
358
+ try {
359
+ const task = await runEffect(Effect.gen(function* () {
360
+ const depService = yield* DependencyService;
361
+ const taskService = yield* TaskService;
362
+ // Add the blocker relationship
363
+ yield* depService.addBlocker(taskId, blockerId);
364
+ // Return the updated task with deps
365
+ return yield* taskService.getWithDeps(taskId);
366
+ }));
367
+ const serialized = serializeTask(task);
368
+ return {
369
+ content: [
370
+ { type: "text", text: `Added dependency: ${blockerId} blocks ${taskId}` },
371
+ { type: "text", text: JSON.stringify({ success: true, task: serialized }) }
372
+ ]
373
+ };
374
+ }
375
+ catch (error) {
376
+ return {
377
+ content: [{ type: "text", text: `Error: ${error instanceof Error ? error.message : String(error)}` }]
378
+ };
379
+ }
380
+ });
381
+ // ---------------------------------------------------------------------------
382
+ // tx_unblock - Remove a dependency
383
+ // ---------------------------------------------------------------------------
384
+ server.tool("tx_unblock", "Remove a dependency: blockerId no longer blocks taskId", {
385
+ taskId: z.string().describe("Task ID that is currently blocked"),
386
+ blockerId: z.string().describe("Task ID to remove as a blocker")
387
+ }, async ({ taskId, blockerId }) => {
388
+ try {
389
+ const task = await runEffect(Effect.gen(function* () {
390
+ const depService = yield* DependencyService;
391
+ const taskService = yield* TaskService;
392
+ // Remove the blocker relationship
393
+ yield* depService.removeBlocker(taskId, blockerId);
394
+ // Return the updated task with deps
395
+ return yield* taskService.getWithDeps(taskId);
396
+ }));
397
+ const serialized = serializeTask(task);
398
+ return {
399
+ content: [
400
+ { type: "text", text: `Removed dependency: ${blockerId} no longer blocks ${taskId}` },
401
+ { type: "text", text: JSON.stringify({ success: true, task: serialized }) }
402
+ ]
403
+ };
404
+ }
405
+ catch (error) {
406
+ return {
407
+ content: [{ type: "text", text: `Error: ${error instanceof Error ? error.message : String(error)}` }]
408
+ };
409
+ }
410
+ });
411
+ return server;
412
+ };
413
+ /**
414
+ * Start the MCP server with stdio transport.
415
+ * Initializes runtime and begins accepting tool calls.
416
+ * Registers graceful shutdown handlers for SIGINT/SIGTERM.
417
+ */
418
+ export const startMcpServer = async (dbPath = ".tx/tasks.db") => {
419
+ // Initialize runtime (runs migrations, builds service layer ONCE)
420
+ await initRuntime(dbPath);
421
+ const server = createMcpServer();
422
+ const transport = new StdioServerTransport();
423
+ // Track shutdown state to prevent multiple cleanup attempts
424
+ let isShuttingDown = false;
425
+ const gracefulShutdown = async (signal) => {
426
+ if (isShuttingDown) {
427
+ return;
428
+ }
429
+ isShuttingDown = true;
430
+ try {
431
+ // Close the MCP server connection
432
+ await server.close();
433
+ }
434
+ catch (error) {
435
+ // Log error but continue shutdown
436
+ console.error(`MCP server close error during ${signal}:`, error);
437
+ }
438
+ try {
439
+ // Dispose of the Effect runtime (releases database connections)
440
+ await disposeRuntime();
441
+ }
442
+ catch (error) {
443
+ // Log error but continue shutdown
444
+ console.error(`Runtime dispose error during ${signal}:`, error);
445
+ }
446
+ process.exit(0);
447
+ };
448
+ // Register shutdown handlers
449
+ process.on("SIGINT", () => gracefulShutdown("SIGINT"));
450
+ process.on("SIGTERM", () => gracefulShutdown("SIGTERM"));
451
+ await server.connect(transport);
452
+ };
453
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,104 @@
1
+ import { Context, Effect, Layer } from "effect";
2
+ import { SqliteClient } from "../db.js";
3
+ import { DatabaseError } from "../errors.js";
4
+ import { rowToDependency } from "../schema.js";
5
+ export class DependencyRepository extends Context.Tag("DependencyRepository")() {
6
+ }
7
+ export const DependencyRepositoryLive = Layer.effect(DependencyRepository, Effect.gen(function* () {
8
+ const db = yield* SqliteClient;
9
+ return {
10
+ insert: (blockerId, blockedId) => Effect.try({
11
+ try: () => {
12
+ db.prepare("INSERT INTO task_dependencies (blocker_id, blocked_id, created_at) VALUES (?, ?, ?)").run(blockerId, blockedId, new Date().toISOString());
13
+ },
14
+ catch: (cause) => new DatabaseError({ cause })
15
+ }),
16
+ remove: (blockerId, blockedId) => Effect.try({
17
+ try: () => {
18
+ db.prepare("DELETE FROM task_dependencies WHERE blocker_id = ? AND blocked_id = ?").run(blockerId, blockedId);
19
+ },
20
+ catch: (cause) => new DatabaseError({ cause })
21
+ }),
22
+ getBlockerIds: (blockedId) => Effect.try({
23
+ try: () => {
24
+ const rows = db.prepare("SELECT blocker_id FROM task_dependencies WHERE blocked_id = ?").all(blockedId);
25
+ return rows.map(r => r.blocker_id);
26
+ },
27
+ catch: (cause) => new DatabaseError({ cause })
28
+ }),
29
+ getBlockingIds: (blockerId) => Effect.try({
30
+ try: () => {
31
+ const rows = db.prepare("SELECT blocked_id FROM task_dependencies WHERE blocker_id = ?").all(blockerId);
32
+ return rows.map(r => r.blocked_id);
33
+ },
34
+ catch: (cause) => new DatabaseError({ cause })
35
+ }),
36
+ getBlockerIdsForMany: (blockedIds) => Effect.try({
37
+ try: () => {
38
+ const result = new Map();
39
+ if (blockedIds.length === 0)
40
+ return result;
41
+ const placeholders = blockedIds.map(() => "?").join(",");
42
+ const rows = db.prepare(`SELECT blocked_id, blocker_id FROM task_dependencies WHERE blocked_id IN (${placeholders})`).all(...blockedIds);
43
+ // Initialize all requested IDs with empty arrays
44
+ for (const id of blockedIds) {
45
+ result.set(id, []);
46
+ }
47
+ // Group by blocked_id
48
+ for (const row of rows) {
49
+ const existing = result.get(row.blocked_id) ?? [];
50
+ result.set(row.blocked_id, [...existing, row.blocker_id]);
51
+ }
52
+ return result;
53
+ },
54
+ catch: (cause) => new DatabaseError({ cause })
55
+ }),
56
+ getBlockingIdsForMany: (blockerIds) => Effect.try({
57
+ try: () => {
58
+ const result = new Map();
59
+ if (blockerIds.length === 0)
60
+ return result;
61
+ const placeholders = blockerIds.map(() => "?").join(",");
62
+ const rows = db.prepare(`SELECT blocker_id, blocked_id FROM task_dependencies WHERE blocker_id IN (${placeholders})`).all(...blockerIds);
63
+ // Initialize all requested IDs with empty arrays
64
+ for (const id of blockerIds) {
65
+ result.set(id, []);
66
+ }
67
+ // Group by blocker_id
68
+ for (const row of rows) {
69
+ const existing = result.get(row.blocker_id) ?? [];
70
+ result.set(row.blocker_id, [...existing, row.blocked_id]);
71
+ }
72
+ return result;
73
+ },
74
+ catch: (cause) => new DatabaseError({ cause })
75
+ }),
76
+ // BFS cycle detection: can we reach toId by following blocker chains from fromId?
77
+ hasPath: (fromId, toId) => Effect.try({
78
+ try: () => {
79
+ const visited = new Set();
80
+ const queue = [fromId];
81
+ while (queue.length > 0) {
82
+ const current = queue.shift();
83
+ if (current === toId)
84
+ return true;
85
+ if (visited.has(current))
86
+ continue;
87
+ visited.add(current);
88
+ const rows = db.prepare("SELECT blocker_id FROM task_dependencies WHERE blocked_id = ?").all(current);
89
+ queue.push(...rows.map(r => r.blocker_id));
90
+ }
91
+ return false;
92
+ },
93
+ catch: (cause) => new DatabaseError({ cause })
94
+ }),
95
+ getAll: () => Effect.try({
96
+ try: () => {
97
+ const rows = db.prepare("SELECT blocker_id, blocked_id, created_at FROM task_dependencies").all();
98
+ return rows.map(rowToDependency);
99
+ },
100
+ catch: (cause) => new DatabaseError({ cause })
101
+ })
102
+ };
103
+ }));
104
+ //# sourceMappingURL=dep-repo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dep-repo.js","sourceRoot":"","sources":["../../src/repo/dep-repo.ts"],"names":[],"mappings":"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"}