@hasna/todos 0.10.21 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -754,6 +754,58 @@ var MIGRATIONS = [
754
754
  `
755
755
  ALTER TABLE tasks ADD COLUMN task_type TEXT;
756
756
  CREATE INDEX IF NOT EXISTS idx_tasks_task_type ON tasks(task_type);
757
+ ALTER TABLE tasks ADD COLUMN cost_tokens INTEGER DEFAULT 0;
758
+ ALTER TABLE tasks ADD COLUMN cost_usd REAL DEFAULT 0;
759
+ ALTER TABLE tasks ADD COLUMN delegated_from TEXT;
760
+ ALTER TABLE tasks ADD COLUMN delegation_depth INTEGER DEFAULT 0;
761
+ ALTER TABLE tasks ADD COLUMN retry_count INTEGER DEFAULT 0;
762
+ ALTER TABLE tasks ADD COLUMN max_retries INTEGER DEFAULT 3;
763
+ ALTER TABLE tasks ADD COLUMN retry_after TEXT;
764
+ ALTER TABLE tasks ADD COLUMN sla_minutes INTEGER;
765
+
766
+ CREATE TABLE IF NOT EXISTS task_traces (
767
+ id TEXT PRIMARY KEY,
768
+ task_id TEXT NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
769
+ agent_id TEXT,
770
+ trace_type TEXT NOT NULL CHECK(trace_type IN ('tool_call','llm_call','error','handoff','custom')),
771
+ name TEXT,
772
+ input_summary TEXT,
773
+ output_summary TEXT,
774
+ duration_ms INTEGER,
775
+ tokens INTEGER,
776
+ cost_usd REAL,
777
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
778
+ );
779
+ CREATE INDEX IF NOT EXISTS idx_task_traces_task ON task_traces(task_id);
780
+ CREATE INDEX IF NOT EXISTS idx_task_traces_agent ON task_traces(agent_id);
781
+
782
+ CREATE TABLE IF NOT EXISTS context_snapshots (
783
+ id TEXT PRIMARY KEY,
784
+ agent_id TEXT,
785
+ task_id TEXT REFERENCES tasks(id) ON DELETE SET NULL,
786
+ project_id TEXT REFERENCES projects(id) ON DELETE SET NULL,
787
+ snapshot_type TEXT NOT NULL CHECK(snapshot_type IN ('interrupt','complete','handoff','checkpoint')),
788
+ plan_summary TEXT,
789
+ files_open TEXT DEFAULT '[]',
790
+ attempts TEXT DEFAULT '[]',
791
+ blockers TEXT DEFAULT '[]',
792
+ next_steps TEXT,
793
+ metadata TEXT DEFAULT '{}',
794
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
795
+ );
796
+ CREATE INDEX IF NOT EXISTS idx_snapshots_agent ON context_snapshots(agent_id);
797
+ CREATE INDEX IF NOT EXISTS idx_snapshots_task ON context_snapshots(task_id);
798
+
799
+ CREATE TABLE IF NOT EXISTS agent_budgets (
800
+ agent_id TEXT PRIMARY KEY,
801
+ max_concurrent INTEGER DEFAULT 5,
802
+ max_cost_usd REAL,
803
+ max_task_minutes INTEGER,
804
+ period_hours INTEGER DEFAULT 24,
805
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
806
+ updated_at TEXT NOT NULL DEFAULT (datetime('now'))
807
+ );
808
+
757
809
  INSERT OR IGNORE INTO _migrations (id) VALUES (35);
758
810
  `
759
811
  ];
@@ -936,6 +988,15 @@ function ensureSchema(db) {
936
988
  ensureColumn("tasks", "assigned_by", "TEXT");
937
989
  ensureColumn("tasks", "assigned_from_project", "TEXT");
938
990
  ensureColumn("tasks", "started_at", "TEXT");
991
+ ensureColumn("tasks", "task_type", "TEXT");
992
+ ensureColumn("tasks", "cost_tokens", "INTEGER DEFAULT 0");
993
+ ensureColumn("tasks", "cost_usd", "REAL DEFAULT 0");
994
+ ensureColumn("tasks", "delegated_from", "TEXT");
995
+ ensureColumn("tasks", "delegation_depth", "INTEGER DEFAULT 0");
996
+ ensureColumn("tasks", "retry_count", "INTEGER DEFAULT 0");
997
+ ensureColumn("tasks", "max_retries", "INTEGER DEFAULT 3");
998
+ ensureColumn("tasks", "retry_after", "TEXT");
999
+ ensureColumn("tasks", "sla_minutes", "INTEGER");
939
1000
  ensureColumn("agents", "role", "TEXT DEFAULT 'agent'");
940
1001
  ensureColumn("agents", "permissions", `TEXT DEFAULT '["*"]'`);
941
1002
  ensureColumn("agents", "reports_to", "TEXT");
@@ -2252,6 +2313,20 @@ function completeTask(id, agentId, db, options) {
2252
2313
  if (spawnedFromTemplate) {
2253
2314
  meta._spawned_task = { id: spawnedFromTemplate.id, short_id: spawnedFromTemplate.short_id, title: spawnedFromTemplate.title };
2254
2315
  }
2316
+ const unblockedDeps = d.query(`SELECT DISTINCT t.id, t.short_id, t.title FROM tasks t
2317
+ JOIN task_dependencies td ON td.task_id = t.id
2318
+ WHERE td.depends_on = ? AND t.status = 'pending'
2319
+ AND NOT EXISTS (
2320
+ SELECT 1 FROM task_dependencies td2
2321
+ JOIN tasks dep2 ON dep2.id = td2.depends_on
2322
+ WHERE td2.task_id = t.id AND dep2.status NOT IN ('completed', 'cancelled') AND dep2.id != ?
2323
+ )`).all(id, id);
2324
+ if (unblockedDeps.length > 0) {
2325
+ meta._unblocked = unblockedDeps.map((d2) => ({ id: d2.id, short_id: d2.short_id, title: d2.title }));
2326
+ for (const dep of unblockedDeps) {
2327
+ dispatchWebhook("task.unblocked", { id: dep.id, unblocked_by: id, title: dep.title }, d).catch(() => {});
2328
+ }
2329
+ }
2255
2330
  return { ...task, status: "completed", locked_by: null, locked_at: null, completed_at: timestamp, confidence, version: task.version + 1, updated_at: timestamp, metadata: meta };
2256
2331
  }
2257
2332
  function lockTask(id, agentId, db) {
@@ -2548,24 +2623,36 @@ function failTask(id, agentId, reason, options, db) {
2548
2623
  };
2549
2624
  let retryTask;
2550
2625
  if (options?.retry) {
2551
- let title = task.title;
2552
- if (task.short_id && title.startsWith(task.short_id + ": ")) {
2553
- title = title.slice(task.short_id.length + 2);
2626
+ const retryCount = (task.retry_count || 0) + 1;
2627
+ const maxRetries = task.max_retries || 3;
2628
+ if (retryCount > maxRetries) {
2629
+ d.run("UPDATE tasks SET metadata = ? WHERE id = ?", [
2630
+ JSON.stringify({ ...meta, _retry_exhausted: { retry_count: retryCount - 1, max_retries: maxRetries } }),
2631
+ id
2632
+ ]);
2633
+ } else {
2634
+ const backoffMinutes = Math.pow(5, retryCount - 1);
2635
+ const retryAfter = options.retry_after || new Date(Date.now() + backoffMinutes * 60 * 1000).toISOString();
2636
+ let title = task.title;
2637
+ if (task.short_id && title.startsWith(task.short_id + ": ")) {
2638
+ title = title.slice(task.short_id.length + 2);
2639
+ }
2640
+ retryTask = createTask({
2641
+ title,
2642
+ description: task.description ?? undefined,
2643
+ priority: task.priority,
2644
+ project_id: task.project_id ?? undefined,
2645
+ task_list_id: task.task_list_id ?? undefined,
2646
+ plan_id: task.plan_id ?? undefined,
2647
+ assigned_to: task.assigned_to ?? undefined,
2648
+ tags: task.tags,
2649
+ metadata: { ...task.metadata, _retry: { original_id: task.id, retry_count: retryCount, max_retries: maxRetries, retry_after: retryAfter, failure_reason: reason } },
2650
+ estimated_minutes: task.estimated_minutes ?? undefined,
2651
+ recurrence_rule: task.recurrence_rule ?? undefined,
2652
+ due_at: retryAfter
2653
+ }, d);
2654
+ d.run("UPDATE tasks SET retry_count = ?, max_retries = ?, retry_after = ? WHERE id = ?", [retryCount, maxRetries, retryAfter, retryTask.id]);
2554
2655
  }
2555
- retryTask = createTask({
2556
- title,
2557
- description: task.description ?? undefined,
2558
- priority: task.priority,
2559
- project_id: task.project_id ?? undefined,
2560
- task_list_id: task.task_list_id ?? undefined,
2561
- plan_id: task.plan_id ?? undefined,
2562
- assigned_to: task.assigned_to ?? undefined,
2563
- tags: task.tags,
2564
- metadata: { ...task.metadata, _retry: { original_id: task.id, retry_after: options.retry_after || null, failure_reason: reason } },
2565
- estimated_minutes: task.estimated_minutes ?? undefined,
2566
- recurrence_rule: task.recurrence_rule ?? undefined,
2567
- due_at: options.retry_after || task.due_at || undefined
2568
- }, d);
2569
2656
  }
2570
2657
  return { task: failedTask, retryTask };
2571
2658
  }
@@ -2589,6 +2676,40 @@ function getStaleTasks(staleMinutes = 30, filters, db) {
2589
2676
  const rows = d.query(`SELECT * FROM tasks WHERE ${where} ORDER BY updated_at ASC`).all(...params);
2590
2677
  return rows.map(rowToTask);
2591
2678
  }
2679
+ function logCost(taskId, tokens, usd, db) {
2680
+ const d = db || getDatabase();
2681
+ d.run("UPDATE tasks SET cost_tokens = cost_tokens + ?, cost_usd = cost_usd + ?, updated_at = ? WHERE id = ?", [tokens, usd, now(), taskId]);
2682
+ }
2683
+ function stealTask(agentId, opts, db) {
2684
+ const d = db || getDatabase();
2685
+ const staleMinutes = opts?.stale_minutes ?? 30;
2686
+ const staleTasks = getStaleTasks(staleMinutes, { project_id: opts?.project_id, task_list_id: opts?.task_list_id }, d);
2687
+ if (staleTasks.length === 0)
2688
+ return null;
2689
+ const priorityOrder = { critical: 0, high: 1, medium: 2, low: 3 };
2690
+ staleTasks.sort((a, b) => (priorityOrder[a.priority] ?? 9) - (priorityOrder[b.priority] ?? 9));
2691
+ const target = staleTasks[0];
2692
+ const timestamp = now();
2693
+ d.run(`UPDATE tasks SET assigned_to = ?, locked_by = ?, locked_at = ?, updated_at = ?, version = version + 1 WHERE id = ?`, [agentId, agentId, timestamp, timestamp, target.id]);
2694
+ logTaskChange(target.id, "steal", "assigned_to", target.assigned_to, agentId, agentId, d);
2695
+ dispatchWebhook("task.assigned", { id: target.id, agent_id: agentId, title: target.title, stolen_from: target.assigned_to }, d).catch(() => {});
2696
+ return { ...target, assigned_to: agentId, locked_by: agentId, locked_at: timestamp, updated_at: timestamp, version: target.version + 1 };
2697
+ }
2698
+ function claimOrSteal(agentId, filters, db) {
2699
+ const d = db || getDatabase();
2700
+ const tx = d.transaction(() => {
2701
+ const next = getNextTask(agentId, filters, d);
2702
+ if (next) {
2703
+ const started = startTask(next.id, agentId, d);
2704
+ return { task: started, stolen: false };
2705
+ }
2706
+ const stolen = stealTask(agentId, { stale_minutes: filters?.stale_minutes, project_id: filters?.project_id, task_list_id: filters?.task_list_id }, d);
2707
+ if (stolen)
2708
+ return { task: stolen, stolen: true };
2709
+ return null;
2710
+ });
2711
+ return tx();
2712
+ }
2592
2713
  function getStatus(filters, agentId, options, db) {
2593
2714
  const d = db || getDatabase();
2594
2715
  const pending = countTasks({ ...filters, status: "pending" }, d);
@@ -4998,6 +5119,188 @@ function issueToTask(issue, opts) {
4998
5119
  agent_id: opts?.agent_id
4999
5120
  };
5000
5121
  }
5122
+ // src/db/traces.ts
5123
+ function logTrace(input, db) {
5124
+ const d = db || getDatabase();
5125
+ const id = uuid();
5126
+ const timestamp = now();
5127
+ d.run(`INSERT INTO task_traces (id, task_id, agent_id, trace_type, name, input_summary, output_summary, duration_ms, tokens, cost_usd, created_at)
5128
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
5129
+ id,
5130
+ input.task_id,
5131
+ input.agent_id || null,
5132
+ input.trace_type,
5133
+ input.name || null,
5134
+ input.input_summary || null,
5135
+ input.output_summary || null,
5136
+ input.duration_ms ?? null,
5137
+ input.tokens ?? null,
5138
+ input.cost_usd ?? null,
5139
+ timestamp
5140
+ ]);
5141
+ return {
5142
+ id,
5143
+ task_id: input.task_id,
5144
+ agent_id: input.agent_id || null,
5145
+ trace_type: input.trace_type,
5146
+ name: input.name || null,
5147
+ input_summary: input.input_summary || null,
5148
+ output_summary: input.output_summary || null,
5149
+ duration_ms: input.duration_ms ?? null,
5150
+ tokens: input.tokens ?? null,
5151
+ cost_usd: input.cost_usd ?? null,
5152
+ created_at: timestamp
5153
+ };
5154
+ }
5155
+ function getTaskTraces(taskId, db) {
5156
+ const d = db || getDatabase();
5157
+ return d.query("SELECT * FROM task_traces WHERE task_id = ? ORDER BY created_at DESC").all(taskId);
5158
+ }
5159
+ function getTraceStats(taskId, db) {
5160
+ const d = db || getDatabase();
5161
+ const row = d.query(`SELECT COUNT(*) as total,
5162
+ SUM(CASE WHEN trace_type = 'tool_call' THEN 1 ELSE 0 END) as tool_calls,
5163
+ SUM(CASE WHEN trace_type = 'llm_call' THEN 1 ELSE 0 END) as llm_calls,
5164
+ SUM(CASE WHEN trace_type = 'error' THEN 1 ELSE 0 END) as errors,
5165
+ COALESCE(SUM(tokens), 0) as total_tokens,
5166
+ COALESCE(SUM(cost_usd), 0) as total_cost_usd,
5167
+ COALESCE(SUM(duration_ms), 0) as total_duration_ms
5168
+ FROM task_traces WHERE task_id = ?`).get(taskId);
5169
+ return row;
5170
+ }
5171
+ // src/db/snapshots.ts
5172
+ function rowToSnapshot(row) {
5173
+ return {
5174
+ ...row,
5175
+ snapshot_type: row.snapshot_type,
5176
+ files_open: JSON.parse(row.files_open || "[]"),
5177
+ attempts: JSON.parse(row.attempts || "[]"),
5178
+ blockers: JSON.parse(row.blockers || "[]"),
5179
+ metadata: JSON.parse(row.metadata || "{}")
5180
+ };
5181
+ }
5182
+ function saveSnapshot(input, db) {
5183
+ const d = db || getDatabase();
5184
+ const id = uuid();
5185
+ const timestamp = now();
5186
+ d.run(`INSERT INTO context_snapshots (id, agent_id, task_id, project_id, snapshot_type, plan_summary, files_open, attempts, blockers, next_steps, metadata, created_at)
5187
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
5188
+ id,
5189
+ input.agent_id || null,
5190
+ input.task_id || null,
5191
+ input.project_id || null,
5192
+ input.snapshot_type,
5193
+ input.plan_summary || null,
5194
+ JSON.stringify(input.files_open || []),
5195
+ JSON.stringify(input.attempts || []),
5196
+ JSON.stringify(input.blockers || []),
5197
+ input.next_steps || null,
5198
+ JSON.stringify(input.metadata || {}),
5199
+ timestamp
5200
+ ]);
5201
+ return {
5202
+ id,
5203
+ agent_id: input.agent_id || null,
5204
+ task_id: input.task_id || null,
5205
+ project_id: input.project_id || null,
5206
+ snapshot_type: input.snapshot_type,
5207
+ plan_summary: input.plan_summary || null,
5208
+ files_open: input.files_open || [],
5209
+ attempts: input.attempts || [],
5210
+ blockers: input.blockers || [],
5211
+ next_steps: input.next_steps || null,
5212
+ metadata: input.metadata || {},
5213
+ created_at: timestamp
5214
+ };
5215
+ }
5216
+ function getLatestSnapshot(agentId, taskId, db) {
5217
+ const d = db || getDatabase();
5218
+ const conditions = [];
5219
+ const params = [];
5220
+ if (agentId) {
5221
+ conditions.push("agent_id = ?");
5222
+ params.push(agentId);
5223
+ }
5224
+ if (taskId) {
5225
+ conditions.push("task_id = ?");
5226
+ params.push(taskId);
5227
+ }
5228
+ if (conditions.length === 0)
5229
+ return null;
5230
+ const where = conditions.join(" AND ");
5231
+ const row = d.query(`SELECT * FROM context_snapshots WHERE ${where} ORDER BY created_at DESC LIMIT 1`).get(...params);
5232
+ return row ? rowToSnapshot(row) : null;
5233
+ }
5234
+ function listSnapshots(opts, db) {
5235
+ const d = db || getDatabase();
5236
+ const conditions = [];
5237
+ const params = [];
5238
+ if (opts.agent_id) {
5239
+ conditions.push("agent_id = ?");
5240
+ params.push(opts.agent_id);
5241
+ }
5242
+ if (opts.task_id) {
5243
+ conditions.push("task_id = ?");
5244
+ params.push(opts.task_id);
5245
+ }
5246
+ if (opts.project_id) {
5247
+ conditions.push("project_id = ?");
5248
+ params.push(opts.project_id);
5249
+ }
5250
+ const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
5251
+ const limit = opts.limit || 20;
5252
+ params.push(limit);
5253
+ return d.query(`SELECT * FROM context_snapshots ${where} ORDER BY created_at DESC LIMIT ?`).all(...params).map(rowToSnapshot);
5254
+ }
5255
+ // src/db/budgets.ts
5256
+ function setBudget(agentId, opts, db) {
5257
+ const d = db || getDatabase();
5258
+ const timestamp = now();
5259
+ d.run(`INSERT INTO agent_budgets (agent_id, max_concurrent, max_cost_usd, max_task_minutes, period_hours, created_at, updated_at)
5260
+ VALUES (?, ?, ?, ?, ?, ?, ?)
5261
+ ON CONFLICT(agent_id) DO UPDATE SET
5262
+ max_concurrent = COALESCE(?, max_concurrent),
5263
+ max_cost_usd = COALESCE(?, max_cost_usd),
5264
+ max_task_minutes = COALESCE(?, max_task_minutes),
5265
+ period_hours = COALESCE(?, period_hours),
5266
+ updated_at = ?`, [
5267
+ agentId,
5268
+ opts.max_concurrent ?? 5,
5269
+ opts.max_cost_usd ?? null,
5270
+ opts.max_task_minutes ?? null,
5271
+ opts.period_hours ?? 24,
5272
+ timestamp,
5273
+ timestamp,
5274
+ opts.max_concurrent ?? null,
5275
+ opts.max_cost_usd ?? null,
5276
+ opts.max_task_minutes ?? null,
5277
+ opts.period_hours ?? null,
5278
+ timestamp
5279
+ ]);
5280
+ return getBudget(agentId, d);
5281
+ }
5282
+ function getBudget(agentId, db) {
5283
+ const d = db || getDatabase();
5284
+ return d.query("SELECT * FROM agent_budgets WHERE agent_id = ?").get(agentId);
5285
+ }
5286
+ function checkBudget(agentId, db) {
5287
+ const d = db || getDatabase();
5288
+ const budget = getBudget(agentId, d);
5289
+ if (!budget)
5290
+ return { allowed: true, current_concurrent: 0, max_concurrent: 999 };
5291
+ const concurrent = countTasks({ status: "in_progress", assigned_to: agentId }, d);
5292
+ if (concurrent >= budget.max_concurrent) {
5293
+ return { allowed: false, reason: `Concurrent limit reached (${concurrent}/${budget.max_concurrent})`, current_concurrent: concurrent, max_concurrent: budget.max_concurrent };
5294
+ }
5295
+ if (budget.max_cost_usd != null) {
5296
+ const periodStart = new Date(Date.now() - budget.period_hours * 60 * 60 * 1000).toISOString();
5297
+ const costRow = d.query("SELECT COALESCE(SUM(cost_usd), 0) as total FROM tasks WHERE (assigned_to = ? OR agent_id = ?) AND updated_at > ?").get(agentId, agentId, periodStart);
5298
+ if (costRow.total >= budget.max_cost_usd) {
5299
+ return { allowed: false, reason: `Cost limit reached ($${costRow.total.toFixed(2)}/$${budget.max_cost_usd.toFixed(2)} in ${budget.period_hours}h)`, current_concurrent: concurrent, max_concurrent: budget.max_concurrent, current_cost_usd: costRow.total, max_cost_usd: budget.max_cost_usd };
5300
+ }
5301
+ }
5302
+ return { allowed: true, current_concurrent: concurrent, max_concurrent: budget.max_concurrent };
5303
+ }
5001
5304
  export {
5002
5305
  uuid,
5003
5306
  updateTaskList,
@@ -5017,12 +5320,15 @@ export {
5017
5320
  syncWithAgents,
5018
5321
  syncWithAgent,
5019
5322
  syncKgEdges,
5323
+ stealTask,
5020
5324
  startTask,
5021
5325
  slugify,
5022
5326
  setTaskStatus,
5023
5327
  setTaskPriority,
5328
+ setBudget,
5024
5329
  searchTasks,
5025
5330
  scoreTask,
5331
+ saveSnapshot,
5026
5332
  resolvePartialId,
5027
5333
  resetDatabase,
5028
5334
  removeTaskRelationshipByPair,
@@ -5044,8 +5350,10 @@ export {
5044
5350
  nextOccurrence,
5045
5351
  moveTask,
5046
5352
  matchCapabilities,
5353
+ logTrace,
5047
5354
  logTaskChange,
5048
5355
  logProgress,
5356
+ logCost,
5049
5357
  lockTask,
5050
5358
  loadConfig,
5051
5359
  listWebhooks,
@@ -5053,6 +5361,7 @@ export {
5053
5361
  listTasks,
5054
5362
  listTaskLists,
5055
5363
  listTaskFiles,
5364
+ listSnapshots,
5056
5365
  listSessions,
5057
5366
  listProjects,
5058
5367
  listProjectSources,
@@ -5065,9 +5374,11 @@ export {
5065
5374
  isValidRecurrenceRule,
5066
5375
  isAgentConflict,
5067
5376
  getWebhook,
5377
+ getTraceStats,
5068
5378
  getTemplate,
5069
5379
  getTasksChangedSince,
5070
5380
  getTaskWithRelations,
5381
+ getTaskTraces,
5071
5382
  getTaskStats,
5072
5383
  getTaskRelationships,
5073
5384
  getTaskRelationship,
@@ -5096,6 +5407,7 @@ export {
5096
5407
  getOrg,
5097
5408
  getNextTask,
5098
5409
  getLeaderboard,
5410
+ getLatestSnapshot,
5099
5411
  getLatestHandoff,
5100
5412
  getImpactAnalysis,
5101
5413
  getDirectReports,
@@ -5107,6 +5419,7 @@ export {
5107
5419
  getChecklist,
5108
5420
  getCapableAgents,
5109
5421
  getBurndown,
5422
+ getBudget,
5110
5423
  getBlockingDeps,
5111
5424
  getAgentMetrics,
5112
5425
  getAgentByName,
@@ -5150,10 +5463,12 @@ export {
5150
5463
  cloneTask,
5151
5464
  clearChecklist,
5152
5465
  cleanExpiredLocks,
5466
+ claimOrSteal,
5153
5467
  claimNextTask,
5154
5468
  checkLock,
5155
5469
  checkCompletionGuard,
5156
5470
  checkChecklistItem,
5471
+ checkBudget,
5157
5472
  bulkUpdateTasks,
5158
5473
  bulkCreateTasks,
5159
5474
  bulkAddTaskFiles,
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":";AA6IA,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAO9E"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":";AA+IA,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAO9E"}