@hasna/todos 0.11.83 → 0.11.85

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/dist/index.js CHANGED
@@ -23532,12 +23532,23 @@ function createPostgresTodosStorageAdapter(options) {
23532
23532
  dependencies: {
23533
23533
  add: (taskId, dependsOn, context) => addDependency2(taskId, dependsOn, store, context),
23534
23534
  remove: (taskId, dependsOn) => removeDependency2(taskId, dependsOn, store),
23535
- list: (taskId) => listDependencies(taskId, store)
23535
+ list: (taskId) => listDependencies(taskId, store),
23536
+ listAll: () => store.list("dependencies")
23536
23537
  },
23537
23538
  verifications: {
23538
23539
  add: (input, context) => addVerification(input, store, context),
23539
23540
  list: (taskId) => listVerifications(taskId, store)
23540
23541
  },
23542
+ commits: {
23543
+ add: (input, context) => addCommit(input, store, context),
23544
+ list: (taskId) => listCommits(taskId, store),
23545
+ find: (sha) => findCommit(sha, store)
23546
+ },
23547
+ gitRefs: {
23548
+ add: (input, context) => addGitRef(input, store, context),
23549
+ list: (taskId) => listGitRefs(taskId, store),
23550
+ find: (ref) => findGitRefs(ref, store)
23551
+ },
23541
23552
  projects: {
23542
23553
  create: (input, context) => createProject2(input, store, context),
23543
23554
  get: (id) => store.get("projects", id),
@@ -23558,7 +23569,9 @@ function createPostgresTodosStorageAdapter(options) {
23558
23569
  get: (id) => store.get("agents", id),
23559
23570
  getByName: async (name) => (await store.list("agents")).find((agent) => agent.name === name) ?? null,
23560
23571
  list: async (options2) => (await store.list("agents")).filter((agent) => options2?.include_archived || agent.status !== "archived").sort((a, b) => a.name.localeCompare(b.name)),
23561
- update: (id, input) => updateAgent2(id, input, store)
23572
+ update: (id, input) => updateAgent2(id, input, store),
23573
+ heartbeat: (idOrName, context) => heartbeatAgent(idOrName, store, context),
23574
+ release: (idOrName, sessionId, context) => releaseAgent2(idOrName, sessionId, store, context)
23562
23575
  },
23563
23576
  taskLists: {
23564
23577
  create: (input, context) => createTaskList2(input, store, context),
@@ -24089,6 +24102,53 @@ async function addVerification(input, store, context) {
24089
24102
  async function listVerifications(taskId, store) {
24090
24103
  return (await store.list("verifications")).filter((verification) => verification.task_id === taskId).sort((a, b) => b.run_at.localeCompare(a.run_at));
24091
24104
  }
24105
+ async function addCommit(input, store, context) {
24106
+ if (!await store.get("tasks", input.task_id))
24107
+ throw new Error(`Task not found: ${input.task_id}`);
24108
+ const timestamp2 = new Date().toISOString();
24109
+ const commit = {
24110
+ id: randomUUID3(),
24111
+ task_id: input.task_id,
24112
+ sha: input.sha,
24113
+ message: input.message ?? null,
24114
+ author: input.author ?? null,
24115
+ files_changed: input.files_changed ?? null,
24116
+ created_at: timestamp2
24117
+ };
24118
+ await store.upsert("commits", { ...commit, updated_at: timestamp2 }, context);
24119
+ return commit;
24120
+ }
24121
+ async function listCommits(taskId, store) {
24122
+ return (await store.list("commits")).filter((commit) => commit.task_id === taskId).sort((a, b) => b.created_at.localeCompare(a.created_at));
24123
+ }
24124
+ async function findCommit(sha, store) {
24125
+ const matches = (await store.list("commits")).filter((commit) => commit.sha === sha || commit.sha.startsWith(sha) || sha.startsWith(commit.sha)).sort((a, b) => b.created_at.localeCompare(a.created_at));
24126
+ return matches[0] ?? null;
24127
+ }
24128
+ async function addGitRef(input, store, context) {
24129
+ if (!await store.get("tasks", input.task_id))
24130
+ throw new Error(`Task not found: ${input.task_id}`);
24131
+ const timestamp2 = new Date().toISOString();
24132
+ const gitRef = {
24133
+ id: randomUUID3(),
24134
+ task_id: input.task_id,
24135
+ ref_type: input.ref_type,
24136
+ name: input.name,
24137
+ url: input.url ?? null,
24138
+ provider: input.provider ?? null,
24139
+ metadata: input.metadata ?? {},
24140
+ created_at: timestamp2,
24141
+ updated_at: timestamp2
24142
+ };
24143
+ await store.upsert("refs", gitRef, context);
24144
+ return gitRef;
24145
+ }
24146
+ async function listGitRefs(taskId, store) {
24147
+ return (await store.list("refs")).filter((ref) => ref.task_id === taskId).sort((a, b) => b.created_at.localeCompare(a.created_at));
24148
+ }
24149
+ async function findGitRefs(ref, store) {
24150
+ return (await store.list("refs")).filter((r) => r.name === ref).sort((a, b) => b.created_at.localeCompare(a.created_at));
24151
+ }
24092
24152
  var TASK_ORDER_BY = "ORDER BY CASE payload->>'priority' WHEN 'critical' THEN 0 WHEN 'high' THEN 1 WHEN 'medium' THEN 2 WHEN 'low' THEN 3 ELSE 4 END ASC, payload->>'created_at' ASC, payload->>'id' ASC";
24093
24153
  function toFilterArray(value) {
24094
24154
  return Array.isArray(value) ? value : [value];
@@ -24236,6 +24296,28 @@ async function updateAgent2(id, input, store) {
24236
24296
  last_seen_at: new Date().toISOString()
24237
24297
  });
24238
24298
  }
24299
+ async function resolveAgent(idOrName, store) {
24300
+ const byId = await store.get("agents", idOrName);
24301
+ if (byId)
24302
+ return byId;
24303
+ return (await store.list("agents")).find((agent) => agent.name === idOrName) ?? null;
24304
+ }
24305
+ async function heartbeatAgent(idOrName, store, context) {
24306
+ const agent = await resolveAgent(idOrName, store);
24307
+ if (!agent)
24308
+ return null;
24309
+ return store.upsert("agents", { ...agent, last_seen_at: new Date().toISOString() }, context);
24310
+ }
24311
+ async function releaseAgent2(idOrName, sessionId, store, context) {
24312
+ const agent = await resolveAgent(idOrName, store);
24313
+ if (!agent)
24314
+ return null;
24315
+ if (sessionId && agent.session_id && agent.session_id !== sessionId) {
24316
+ return { agent, released: false };
24317
+ }
24318
+ const updated = await store.upsert("agents", { ...agent, session_id: null, last_seen_at: new Date().toISOString() }, context);
24319
+ return { agent: updated, released: true };
24320
+ }
24239
24321
  async function createTaskList2(input, store, context) {
24240
24322
  const timestamp2 = new Date().toISOString();
24241
24323
  return store.upsert("task_lists", {
@@ -31316,7 +31398,7 @@ function resolveRun(parsed, db) {
31316
31398
  }
31317
31399
  return resolution;
31318
31400
  }
31319
- function resolveAgent(parsed, db) {
31401
+ function resolveAgent2(parsed, db) {
31320
31402
  const resolution = blankResolution(parsed);
31321
31403
  const id = resolvePartialId(db, "agents", parsed.target);
31322
31404
  const agent = id ? getAgent(id, db) : getAgentByName(parsed.target, db);
@@ -31353,7 +31435,7 @@ function resolveTask(parsed, db) {
31353
31435
  function resolveUnknown(parsed, workspace, db, maxSymbolMatches) {
31354
31436
  const attempts = [
31355
31437
  () => resolveTask({ ...parsed, kind: "task" }, db),
31356
- () => resolveAgent({ ...parsed, kind: "agent" }, db),
31438
+ () => resolveAgent2({ ...parsed, kind: "agent" }, db),
31357
31439
  () => resolvePlan({ ...parsed, kind: "plan" }, db),
31358
31440
  () => resolveSymbol({ ...parsed, kind: "symbol" }, workspace, maxSymbolMatches)
31359
31441
  ];
@@ -31388,7 +31470,7 @@ function resolveMentions(input, db) {
31388
31470
  case "run":
31389
31471
  return resolveRun(parsed, d);
31390
31472
  case "agent":
31391
- return resolveAgent(parsed, d);
31473
+ return resolveAgent2(parsed, d);
31392
31474
  case "task":
31393
31475
  return resolveTask(parsed, d);
31394
31476
  default:
@@ -42206,7 +42288,7 @@ function resolveProjectId(value, db) {
42206
42288
  return null;
42207
42289
  return resolvePartialId(db, "projects", value) || value;
42208
42290
  }
42209
- function resolveAgent2(agentId, db) {
42291
+ function resolveAgent3(agentId, db) {
42210
42292
  return db.query("SELECT id, name FROM agents WHERE id = ? OR LOWER(name) = LOWER(?)").get(agentId, agentId);
42211
42293
  }
42212
42294
  function agentTaskWhere(agent, options, db) {
@@ -42250,7 +42332,7 @@ function scoreHandoffs(created, withTaskRefs, withBlockers) {
42250
42332
  }
42251
42333
  function getAgentReliabilityScorecard(agentId, options = {}, db) {
42252
42334
  const d = db || getDatabase();
42253
- const agent = resolveAgent2(agentId, d);
42335
+ const agent = resolveAgent3(agentId, d);
42254
42336
  if (!agent)
42255
42337
  return null;
42256
42338
  const generatedAt = now();
@@ -42419,7 +42501,7 @@ function getAgentReliabilityScorecard(agentId, options = {}, db) {
42419
42501
  }
42420
42502
  function listAgentReliabilityScorecards(options = {}, db) {
42421
42503
  const d = db || getDatabase();
42422
- const agents = options.agent_id ? resolveAgent2(options.agent_id, d) ? [resolveAgent2(options.agent_id, d)] : [] : d.query("SELECT id, name FROM agents ORDER BY name").all();
42504
+ const agents = options.agent_id ? resolveAgent3(options.agent_id, d) ? [resolveAgent3(options.agent_id, d)] : [] : d.query("SELECT id, name FROM agents ORDER BY name").all();
42423
42505
  const limit = Number.isFinite(options.limit) && options.limit > 0 ? Math.min(Math.floor(options.limit), 500) : 50;
42424
42506
  return agents.map((agent) => getAgentReliabilityScorecard(agent.id, options, d)).filter((scorecard) => Boolean(scorecard)).filter((scorecard) => {
42425
42507
  const signals = scorecard.signals;
package/dist/mcp/index.js CHANGED
@@ -22870,6 +22870,18 @@ async function cloudRegisterAgent(client, input) {
22870
22870
  }
22871
22871
  return raw;
22872
22872
  }
22873
+ async function cloudHeartbeatAgent(client, idOrName) {
22874
+ const raw = await client.transport.post(`/agents/${encodeURIComponent(idOrName)}/heartbeat`, {});
22875
+ if (raw && typeof raw === "object" && "agent" in raw) {
22876
+ return raw.agent;
22877
+ }
22878
+ return raw ?? null;
22879
+ }
22880
+ async function cloudReleaseAgent(client, idOrName, sessionId) {
22881
+ const raw = await client.transport.post(`/agents/${encodeURIComponent(idOrName)}/release`, sessionId ? { session_id: sessionId } : {});
22882
+ const env = raw ?? {};
22883
+ return { agent: env.agent ?? null, released: env.released !== false };
22884
+ }
22873
22885
  var _cache;
22874
22886
  var init_cloud_router = __esm(() => {
22875
22887
  init_storage();
@@ -44496,6 +44508,19 @@ ID: ${updated.id}${taskNote}`
44496
44508
  agent_id: exports_external.string().describe("Your agent ID or name.")
44497
44509
  }, async ({ agent_id }) => {
44498
44510
  try {
44511
+ const cloud = getTodosCloudClient();
44512
+ if (cloud) {
44513
+ const a = await cloudHeartbeatAgent(cloud, agent_id);
44514
+ if (!a) {
44515
+ return { content: [{ type: "text", text: `Agent not found: ${agent_id}` }], isError: true };
44516
+ }
44517
+ return {
44518
+ content: [{
44519
+ type: "text",
44520
+ text: `Heartbeat: ${a.name} (${a.id}) \u2014 last_seen_at updated to ${a.last_seen_at}`
44521
+ }]
44522
+ };
44523
+ }
44499
44524
  const agent = getAgent(agent_id) || getAgentByName(agent_id);
44500
44525
  if (!agent) {
44501
44526
  return { content: [{ type: "text", text: `Agent not found: ${agent_id}` }], isError: true };
@@ -44518,6 +44543,22 @@ ID: ${updated.id}${taskNote}`
44518
44543
  session_id: exports_external.string().optional().describe("Your session ID \u2014 if provided, release only succeeds if it matches (prevents other sessions from releasing your agent).")
44519
44544
  }, async ({ agent_id, session_id }) => {
44520
44545
  try {
44546
+ const cloud = getTodosCloudClient();
44547
+ if (cloud) {
44548
+ const result = await cloudReleaseAgent(cloud, agent_id, session_id);
44549
+ if (!result.agent) {
44550
+ return { content: [{ type: "text", text: `Agent not found: ${agent_id}` }], isError: true };
44551
+ }
44552
+ if (!result.released) {
44553
+ return { content: [{ type: "text", text: `Release denied: session_id does not match agent's current session.` }], isError: true };
44554
+ }
44555
+ return {
44556
+ content: [{
44557
+ type: "text",
44558
+ text: `Agent released: ${result.agent.name} (${result.agent.id}) \u2014 session cleared, name is now available.`
44559
+ }]
44560
+ };
44561
+ }
44521
44562
  const agent = getAgent(agent_id) || getAgentByName(agent_id);
44522
44563
  if (!agent) {
44523
44564
  return { content: [{ type: "text", text: `Agent not found: ${agent_id}` }], isError: true };
@@ -48135,12 +48176,23 @@ function createPostgresTodosStorageAdapter(options) {
48135
48176
  dependencies: {
48136
48177
  add: (taskId, dependsOn, context) => addDependency2(taskId, dependsOn, store, context),
48137
48178
  remove: (taskId, dependsOn) => removeDependency2(taskId, dependsOn, store),
48138
- list: (taskId) => listDependencies(taskId, store)
48179
+ list: (taskId) => listDependencies(taskId, store),
48180
+ listAll: () => store.list("dependencies")
48139
48181
  },
48140
48182
  verifications: {
48141
48183
  add: (input, context) => addVerification(input, store, context),
48142
48184
  list: (taskId) => listVerifications(taskId, store)
48143
48185
  },
48186
+ commits: {
48187
+ add: (input, context) => addCommit(input, store, context),
48188
+ list: (taskId) => listCommits(taskId, store),
48189
+ find: (sha) => findCommit(sha, store)
48190
+ },
48191
+ gitRefs: {
48192
+ add: (input, context) => addGitRef(input, store, context),
48193
+ list: (taskId) => listGitRefs(taskId, store),
48194
+ find: (ref) => findGitRefs(ref, store)
48195
+ },
48144
48196
  projects: {
48145
48197
  create: (input, context) => createProject2(input, store, context),
48146
48198
  get: (id) => store.get("projects", id),
@@ -48161,7 +48213,9 @@ function createPostgresTodosStorageAdapter(options) {
48161
48213
  get: (id) => store.get("agents", id),
48162
48214
  getByName: async (name) => (await store.list("agents")).find((agent) => agent.name === name) ?? null,
48163
48215
  list: async (options2) => (await store.list("agents")).filter((agent) => options2?.include_archived || agent.status !== "archived").sort((a, b) => a.name.localeCompare(b.name)),
48164
- update: (id, input) => updateAgent2(id, input, store)
48216
+ update: (id, input) => updateAgent2(id, input, store),
48217
+ heartbeat: (idOrName, context) => heartbeatAgent(idOrName, store, context),
48218
+ release: (idOrName, sessionId, context) => releaseAgent2(idOrName, sessionId, store, context)
48165
48219
  },
48166
48220
  taskLists: {
48167
48221
  create: (input, context) => createTaskList2(input, store, context),
@@ -48691,6 +48745,53 @@ async function addVerification(input, store, context) {
48691
48745
  async function listVerifications(taskId, store) {
48692
48746
  return (await store.list("verifications")).filter((verification) => verification.task_id === taskId).sort((a, b) => b.run_at.localeCompare(a.run_at));
48693
48747
  }
48748
+ async function addCommit(input, store, context) {
48749
+ if (!await store.get("tasks", input.task_id))
48750
+ throw new Error(`Task not found: ${input.task_id}`);
48751
+ const timestamp3 = new Date().toISOString();
48752
+ const commit = {
48753
+ id: randomUUID3(),
48754
+ task_id: input.task_id,
48755
+ sha: input.sha,
48756
+ message: input.message ?? null,
48757
+ author: input.author ?? null,
48758
+ files_changed: input.files_changed ?? null,
48759
+ created_at: timestamp3
48760
+ };
48761
+ await store.upsert("commits", { ...commit, updated_at: timestamp3 }, context);
48762
+ return commit;
48763
+ }
48764
+ async function listCommits(taskId, store) {
48765
+ return (await store.list("commits")).filter((commit) => commit.task_id === taskId).sort((a, b) => b.created_at.localeCompare(a.created_at));
48766
+ }
48767
+ async function findCommit(sha, store) {
48768
+ const matches = (await store.list("commits")).filter((commit) => commit.sha === sha || commit.sha.startsWith(sha) || sha.startsWith(commit.sha)).sort((a, b) => b.created_at.localeCompare(a.created_at));
48769
+ return matches[0] ?? null;
48770
+ }
48771
+ async function addGitRef(input, store, context) {
48772
+ if (!await store.get("tasks", input.task_id))
48773
+ throw new Error(`Task not found: ${input.task_id}`);
48774
+ const timestamp3 = new Date().toISOString();
48775
+ const gitRef = {
48776
+ id: randomUUID3(),
48777
+ task_id: input.task_id,
48778
+ ref_type: input.ref_type,
48779
+ name: input.name,
48780
+ url: input.url ?? null,
48781
+ provider: input.provider ?? null,
48782
+ metadata: input.metadata ?? {},
48783
+ created_at: timestamp3,
48784
+ updated_at: timestamp3
48785
+ };
48786
+ await store.upsert("refs", gitRef, context);
48787
+ return gitRef;
48788
+ }
48789
+ async function listGitRefs(taskId, store) {
48790
+ return (await store.list("refs")).filter((ref) => ref.task_id === taskId).sort((a, b) => b.created_at.localeCompare(a.created_at));
48791
+ }
48792
+ async function findGitRefs(ref, store) {
48793
+ return (await store.list("refs")).filter((r) => r.name === ref).sort((a, b) => b.created_at.localeCompare(a.created_at));
48794
+ }
48694
48795
  function toFilterArray(value) {
48695
48796
  return Array.isArray(value) ? value : [value];
48696
48797
  }
@@ -48837,6 +48938,28 @@ async function updateAgent2(id, input, store) {
48837
48938
  last_seen_at: new Date().toISOString()
48838
48939
  });
48839
48940
  }
48941
+ async function resolveAgent3(idOrName, store) {
48942
+ const byId = await store.get("agents", idOrName);
48943
+ if (byId)
48944
+ return byId;
48945
+ return (await store.list("agents")).find((agent) => agent.name === idOrName) ?? null;
48946
+ }
48947
+ async function heartbeatAgent(idOrName, store, context) {
48948
+ const agent = await resolveAgent3(idOrName, store);
48949
+ if (!agent)
48950
+ return null;
48951
+ return store.upsert("agents", { ...agent, last_seen_at: new Date().toISOString() }, context);
48952
+ }
48953
+ async function releaseAgent2(idOrName, sessionId, store, context) {
48954
+ const agent = await resolveAgent3(idOrName, store);
48955
+ if (!agent)
48956
+ return null;
48957
+ if (sessionId && agent.session_id && agent.session_id !== sessionId) {
48958
+ return { agent, released: false };
48959
+ }
48960
+ const updated = await store.upsert("agents", { ...agent, session_id: null, last_seen_at: new Date().toISOString() }, context);
48961
+ return { agent: updated, released: true };
48962
+ }
48840
48963
  async function createTaskList2(input, store, context) {
48841
48964
  const timestamp3 = new Date().toISOString();
48842
48965
  return store.upsert("task_lists", {
@@ -49721,6 +49844,70 @@ async function handleV1Request(req, url) {
49721
49844
  }
49722
49845
  return error(405, `method ${method} not allowed on /v1/tasks/:id/verifications`);
49723
49846
  }
49847
+ if (action === "commits") {
49848
+ if (!store.commits)
49849
+ return error(501, "commit links are not supported by this storage backend");
49850
+ if (method === "GET") {
49851
+ if (!await store.tasks.get(id))
49852
+ return error(404, "task not found");
49853
+ const commits = await store.commits.list(id);
49854
+ return json2({ commits, count: commits.length });
49855
+ }
49856
+ if (method === "POST") {
49857
+ const body2 = await readJson(req) ?? {};
49858
+ if (typeof body2.sha !== "string" || !body2.sha.trim())
49859
+ return error(400, "sha is required");
49860
+ try {
49861
+ const commit = await store.commits.add({
49862
+ task_id: id,
49863
+ sha: body2.sha,
49864
+ message: body2.message,
49865
+ author: body2.author,
49866
+ files_changed: Array.isArray(body2.files_changed) ? body2.files_changed : undefined
49867
+ }, contextFromPrincipal(principal));
49868
+ return json2({ commit }, 201);
49869
+ } catch (e) {
49870
+ const msg = e.message || "";
49871
+ if (msg.includes("not found"))
49872
+ return error(404, msg);
49873
+ throw e;
49874
+ }
49875
+ }
49876
+ return error(405, `method ${method} not allowed on /v1/tasks/:id/commits`);
49877
+ }
49878
+ if (action === "refs") {
49879
+ if (!store.gitRefs)
49880
+ return error(501, "git ref links are not supported by this storage backend");
49881
+ if (method === "GET") {
49882
+ if (!await store.tasks.get(id))
49883
+ return error(404, "task not found");
49884
+ const refs = await store.gitRefs.list(id);
49885
+ return json2({ refs, count: refs.length });
49886
+ }
49887
+ if (method === "POST") {
49888
+ const body2 = await readJson(req) ?? {};
49889
+ const refType = body2.ref_type === "pull_request" || body2.ref_type === "branch" ? body2.ref_type : "branch";
49890
+ if (typeof body2.name !== "string" || !body2.name.trim())
49891
+ return error(400, "name is required");
49892
+ try {
49893
+ const ref = await store.gitRefs.add({
49894
+ task_id: id,
49895
+ ref_type: refType,
49896
+ name: body2.name,
49897
+ url: body2.url,
49898
+ provider: body2.provider,
49899
+ metadata: body2.metadata
49900
+ }, contextFromPrincipal(principal));
49901
+ return json2({ ref }, 201);
49902
+ } catch (e) {
49903
+ const msg = e.message || "";
49904
+ if (msg.includes("not found"))
49905
+ return error(404, msg);
49906
+ throw e;
49907
+ }
49908
+ }
49909
+ return error(405, `method ${method} not allowed on /v1/tasks/:id/refs`);
49910
+ }
49724
49911
  const body = await readJson(req) ?? {};
49725
49912
  const agentId = body.agent_id || principal.agent || "todos-serve";
49726
49913
  if (action === "start" && method === "POST") {
@@ -49833,11 +50020,87 @@ async function handleV1Request(req, url) {
49833
50020
  }
49834
50021
  return json2({ agent: result }, 201);
49835
50022
  }
50023
+ if (id && action === "heartbeat") {
50024
+ if (method !== "POST")
50025
+ return error(405, `method ${method} not allowed on /v1/agents/:id/heartbeat`);
50026
+ if (typeof store.agents.heartbeat !== "function") {
50027
+ return error(501, "agent heartbeat is not supported by this storage backend");
50028
+ }
50029
+ const agent = await store.agents.heartbeat(id, contextFromPrincipal(principal));
50030
+ return agent ? json2({ agent }) : error(404, "agent not found");
50031
+ }
50032
+ if (id && action === "release") {
50033
+ if (method !== "POST")
50034
+ return error(405, `method ${method} not allowed on /v1/agents/:id/release`);
50035
+ if (typeof store.agents.release !== "function") {
50036
+ return error(501, "agent release is not supported by this storage backend");
50037
+ }
50038
+ const body = await readJson(req) ?? {};
50039
+ const result = await store.agents.release(id, body.session_id, contextFromPrincipal(principal));
50040
+ if (!result)
50041
+ return error(404, "agent not found");
50042
+ if (!result.released) {
50043
+ return error(409, "release denied: session_id does not match agent's current session", { released: false });
50044
+ }
50045
+ return json2({ agent: result.agent, released: true });
50046
+ }
49836
50047
  if (id && method === "GET") {
49837
50048
  const agent = await store.agents.get(id);
49838
50049
  return agent ? json2({ agent }) : error(404, "agent not found");
49839
50050
  }
49840
50051
  }
50052
+ if (resource === "activity" && !id) {
50053
+ if (method !== "GET")
50054
+ return error(405, `method ${method} not allowed on /v1/activity`);
50055
+ const limitParam = url.searchParams.get("limit");
50056
+ const limit = limitParam ? Math.max(1, Math.min(1e4, Number(limitParam) || 50)) : 50;
50057
+ const activity = await store.audit.getRecentActivity(limit);
50058
+ return json2({ activity, count: activity.length });
50059
+ }
50060
+ if (resource === "task-lists" && !id) {
50061
+ if (method !== "GET")
50062
+ return error(405, `method ${method} not allowed on /v1/task-lists`);
50063
+ const projectId = url.searchParams.get("project_id") ?? undefined;
50064
+ const taskLists = await store.taskLists.list(projectId);
50065
+ return json2({ task_lists: taskLists, count: taskLists.length });
50066
+ }
50067
+ if (resource === "dependencies" && !id) {
50068
+ if (method !== "GET")
50069
+ return error(405, `method ${method} not allowed on /v1/dependencies`);
50070
+ if (typeof store.dependencies?.listAll !== "function") {
50071
+ return error(501, "dependency edge listing is not supported by this storage backend");
50072
+ }
50073
+ const dependencies = await store.dependencies.listAll();
50074
+ return json2({ dependencies, count: dependencies.length });
50075
+ }
50076
+ if (resource === "commits" && id) {
50077
+ if (method !== "GET")
50078
+ return error(405, `method ${method} not allowed on /v1/commits/:sha`);
50079
+ if (!store.commits)
50080
+ return error(501, "commit links are not supported by this storage backend");
50081
+ const commit = await store.commits.find(id);
50082
+ return json2({ commit: commit ?? null });
50083
+ }
50084
+ if (resource === "refs" && id) {
50085
+ if (method !== "GET")
50086
+ return error(405, `method ${method} not allowed on /v1/refs/:ref`);
50087
+ if (!store.gitRefs)
50088
+ return error(501, "git ref links are not supported by this storage backend");
50089
+ const refs = await store.gitRefs.find(id);
50090
+ return json2({ refs, count: refs.length });
50091
+ }
50092
+ if (resource === "next" && !id) {
50093
+ if (method !== "GET")
50094
+ return error(405, `method ${method} not allowed on /v1/next`);
50095
+ const agent = url.searchParams.get("agent") ?? undefined;
50096
+ const filters = {
50097
+ ...url.searchParams.get("project_id") ? { project_id: url.searchParams.get("project_id") } : {},
50098
+ ...url.searchParams.get("task_list_id") ? { task_list_id: url.searchParams.get("task_list_id") } : {},
50099
+ ...url.searchParams.get("plan_id") ? { plan_id: url.searchParams.get("plan_id") } : {}
50100
+ };
50101
+ const task2 = await store.tasks.getNext(agent, filters);
50102
+ return json2({ task: task2 ?? null });
50103
+ }
49841
50104
  if (resource === "stats" && method === "GET") {
49842
50105
  const [tasks, tasksAll, projects] = await Promise.all([
49843
50106
  store.tasks.count(),
@@ -1 +1 @@
1
- {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/agents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAOzE,UAAU,UAAU;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,KAAK,OAAO,GAAG;IACb,kBAAkB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IAC9C,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAClD,WAAW,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,MAAM,CAAC;IACpC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACvC,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,UAAU,GAAG,SAAS,CAAC;CAC5D,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,kBAAkB,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,EAAE,OAAO,GAAG,IAAI,CA6cjJ"}
1
+ {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/agents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAOzE,UAAU,UAAU;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,KAAK,OAAO,GAAG;IACb,kBAAkB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IAC9C,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAClD,WAAW,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,MAAM,CAAC;IACpC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACvC,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,UAAU,GAAG,SAAS,CAAC;CAC5D,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,kBAAkB,EAAE,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,EAAE,OAAO,GAAG,IAAI,CA+ejJ"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "packageName": "@hasna/todos",
3
- "packageVersion": "0.11.83",
3
+ "packageVersion": "0.11.85",
4
4
  "repository": "https://github.com/hasna/todos.git",
5
- "gitCommit": "69a46e4c566599f0e473686aa6c49aa6df6be20d",
6
- "generatedAt": "2026-07-08T14:22:35.687Z"
5
+ "gitCommit": "51d25377a0dd06b9a3f535abe61f49c881b49bd3",
6
+ "generatedAt": "2026-07-08T16:10:52.301Z"
7
7
  }