@hasna/todos 0.10.1 → 0.10.3

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/cli/index.js CHANGED
@@ -2212,6 +2212,7 @@ function ensureSchema(db) {
2212
2212
  CREATE TABLE agents (
2213
2213
  id TEXT PRIMARY KEY, name TEXT NOT NULL UNIQUE, description TEXT,
2214
2214
  role TEXT DEFAULT 'agent', permissions TEXT DEFAULT '["*"]',
2215
+ status TEXT NOT NULL DEFAULT 'active' CHECK(status IN ('active', 'archived')),
2215
2216
  metadata TEXT DEFAULT '{}',
2216
2217
  created_at TEXT NOT NULL DEFAULT (datetime('now')),
2217
2218
  last_seen_at TEXT NOT NULL DEFAULT (datetime('now'))
@@ -2870,6 +2871,11 @@ var init_database = __esm(() => {
2870
2871
  `
2871
2872
  ALTER TABLE agents ADD COLUMN capabilities TEXT DEFAULT '[]';
2872
2873
  INSERT OR IGNORE INTO _migrations (id) VALUES (29);
2874
+ `,
2875
+ `
2876
+ ALTER TABLE agents ADD COLUMN status TEXT NOT NULL DEFAULT 'active' CHECK(status IN ('active', 'archived'));
2877
+ CREATE INDEX IF NOT EXISTS idx_agents_status ON agents(status);
2878
+ INSERT OR IGNORE INTO _migrations (id) VALUES (30);
2873
2879
  `
2874
2880
  ];
2875
2881
  });
@@ -3206,8 +3212,7 @@ __export(exports_config, {
3206
3212
  getCompletionGuardConfig: () => getCompletionGuardConfig,
3207
3213
  getAgentTasksDir: () => getAgentTasksDir,
3208
3214
  getAgentTaskListId: () => getAgentTaskListId,
3209
- getAgentPoolForProject: () => getAgentPoolForProject,
3210
- DEFAULT_AGENT_POOL: () => DEFAULT_AGENT_POOL
3215
+ getAgentPoolForProject: () => getAgentPoolForProject
3211
3216
  });
3212
3217
  import { existsSync as existsSync3 } from "fs";
3213
3218
  import { join as join3 } from "path";
@@ -3267,7 +3272,7 @@ function getAgentPoolForProject(workingDir) {
3267
3272
  return config.project_pools[bestKey];
3268
3273
  }
3269
3274
  }
3270
- return config.agent_pool || DEFAULT_AGENT_POOL;
3275
+ return config.agent_pool || null;
3271
3276
  }
3272
3277
  function getCompletionGuardConfig(projectPath) {
3273
3278
  const config = loadConfig();
@@ -3277,26 +3282,9 @@ function getCompletionGuardConfig(projectPath) {
3277
3282
  }
3278
3283
  return global;
3279
3284
  }
3280
- var DEFAULT_AGENT_POOL, cached = null, GUARD_DEFAULTS;
3285
+ var cached = null, GUARD_DEFAULTS;
3281
3286
  var init_config = __esm(() => {
3282
3287
  init_sync_utils();
3283
- DEFAULT_AGENT_POOL = [
3284
- "maximus",
3285
- "cassius",
3286
- "aurelius",
3287
- "brutus",
3288
- "titus",
3289
- "nero",
3290
- "cicero",
3291
- "seneca",
3292
- "cato",
3293
- "julius",
3294
- "marcus",
3295
- "lucius",
3296
- "quintus",
3297
- "gaius",
3298
- "publius"
3299
- ];
3300
3288
  GUARD_DEFAULTS = {
3301
3289
  enabled: false,
3302
3290
  min_work_seconds: 30,
@@ -4747,6 +4735,7 @@ var exports_agents = {};
4747
4735
  __export(exports_agents, {
4748
4736
  updateAgentActivity: () => updateAgentActivity,
4749
4737
  updateAgent: () => updateAgent,
4738
+ unarchiveAgent: () => unarchiveAgent,
4750
4739
  registerAgent: () => registerAgent,
4751
4740
  matchCapabilities: () => matchCapabilities,
4752
4741
  listAgents: () => listAgents,
@@ -4757,11 +4746,12 @@ __export(exports_agents, {
4757
4746
  getAvailableNamesFromPool: () => getAvailableNamesFromPool,
4758
4747
  getAgentByName: () => getAgentByName,
4759
4748
  getAgent: () => getAgent,
4760
- deleteAgent: () => deleteAgent
4749
+ deleteAgent: () => deleteAgent,
4750
+ archiveAgent: () => archiveAgent
4761
4751
  });
4762
4752
  function getAvailableNamesFromPool(pool, db) {
4763
4753
  const cutoff = new Date(Date.now() - AGENT_ACTIVE_WINDOW_MS).toISOString();
4764
- const activeNames = new Set(db.query("SELECT name FROM agents WHERE last_seen_at > ?").all(cutoff).map((r) => r.name.toLowerCase()));
4754
+ const activeNames = new Set(db.query("SELECT name FROM agents WHERE status = 'active' AND last_seen_at > ?").all(cutoff).map((r) => r.name.toLowerCase()));
4765
4755
  return pool.filter((name) => !activeNames.has(name.toLowerCase()));
4766
4756
  }
4767
4757
  function shortUuid() {
@@ -4772,30 +4762,13 @@ function rowToAgent(row) {
4772
4762
  ...row,
4773
4763
  permissions: JSON.parse(row.permissions || '["*"]'),
4774
4764
  capabilities: JSON.parse(row.capabilities || "[]"),
4765
+ status: row.status || "active",
4775
4766
  metadata: JSON.parse(row.metadata || "{}")
4776
4767
  };
4777
4768
  }
4778
4769
  function registerAgent(input, db) {
4779
4770
  const d = db || getDatabase();
4780
4771
  const normalizedName = input.name.trim().toLowerCase();
4781
- if (input.pool && input.pool.length > 0) {
4782
- const poolLower = input.pool.map((n) => n.toLowerCase());
4783
- if (!poolLower.includes(normalizedName)) {
4784
- const available = getAvailableNamesFromPool(input.pool, d);
4785
- const suggestion = available.length > 0 ? available[0] : null;
4786
- return {
4787
- conflict: true,
4788
- pool_violation: true,
4789
- existing_id: "",
4790
- existing_name: normalizedName,
4791
- last_seen_at: "",
4792
- session_hint: null,
4793
- working_dir: input.working_dir || null,
4794
- suggestions: available.slice(0, 5),
4795
- message: `"${normalizedName}" is not in this project's agent pool [${input.pool.join(", ")}]. ${available.length > 0 ? `Try: ${available.slice(0, 3).join(", ")}` : "No names are currently available \u2014 wait for an active agent to go stale."}${suggestion ? ` Suggested: ${suggestion}` : ""}`
4796
- };
4797
- }
4798
- }
4799
4772
  const existing = getAgentByName(normalizedName, d);
4800
4773
  if (existing) {
4801
4774
  const lastSeenMs = new Date(existing.last_seen_at).getTime();
@@ -4816,7 +4789,7 @@ function registerAgent(input, db) {
4816
4789
  message: `Agent "${normalizedName}" is already active (last seen ${minutesAgo}m ago, session ${existing.session_id?.slice(0, 8)}\u2026, dir: ${existing.working_dir ?? "unknown"}). Are you that agent? If so, pass session_id="${existing.session_id}" to reclaim it. Otherwise choose a different name.${suggestions.length > 0 ? ` Available: ${suggestions.slice(0, 3).join(", ")}` : ""}`
4817
4790
  };
4818
4791
  }
4819
- const updates = ["last_seen_at = ?"];
4792
+ const updates = ["last_seen_at = ?", "status = 'active'"];
4820
4793
  const params = [now()];
4821
4794
  if (input.session_id && !sameSession) {
4822
4795
  updates.push("session_id = ?");
@@ -4870,9 +4843,19 @@ function getAgentByName(name, db) {
4870
4843
  const row = d.query("SELECT * FROM agents WHERE LOWER(name) = ?").get(normalizedName);
4871
4844
  return row ? rowToAgent(row) : null;
4872
4845
  }
4873
- function listAgents(db) {
4874
- const d = db || getDatabase();
4875
- return d.query("SELECT * FROM agents ORDER BY name").all().map(rowToAgent);
4846
+ function listAgents(opts, db) {
4847
+ let d;
4848
+ let includeArchived = false;
4849
+ if (opts && typeof opts === "object" && "query" in opts) {
4850
+ d = opts;
4851
+ } else {
4852
+ includeArchived = opts?.include_archived ?? false;
4853
+ d = db || getDatabase();
4854
+ }
4855
+ if (includeArchived) {
4856
+ return d.query("SELECT * FROM agents ORDER BY name").all().map(rowToAgent);
4857
+ }
4858
+ return d.query("SELECT * FROM agents WHERE status = 'active' ORDER BY name").all().map(rowToAgent);
4876
4859
  }
4877
4860
  function updateAgentActivity(id, db) {
4878
4861
  const d = db || getDatabase();
@@ -4931,7 +4914,17 @@ function updateAgent(id, input, db) {
4931
4914
  }
4932
4915
  function deleteAgent(id, db) {
4933
4916
  const d = db || getDatabase();
4934
- return d.run("DELETE FROM agents WHERE id = ?", [id]).changes > 0;
4917
+ return d.run("UPDATE agents SET status = 'archived', last_seen_at = ? WHERE id = ?", [now(), id]).changes > 0;
4918
+ }
4919
+ function archiveAgent(id, db) {
4920
+ const d = db || getDatabase();
4921
+ d.run("UPDATE agents SET status = 'archived', last_seen_at = ? WHERE id = ?", [now(), id]);
4922
+ return getAgent(id, d);
4923
+ }
4924
+ function unarchiveAgent(id, db) {
4925
+ const d = db || getDatabase();
4926
+ d.run("UPDATE agents SET status = 'active', last_seen_at = ? WHERE id = ?", [now(), id]);
4927
+ return getAgent(id, d);
4935
4928
  }
4936
4929
  function getDirectReports(agentId, db) {
4937
4930
  const d = db || getDatabase();
@@ -10664,13 +10657,15 @@ var init_mcp = __esm(() => {
10664
10657
  "add_comment",
10665
10658
  "get_next_task",
10666
10659
  "bootstrap",
10667
- "get_tasks_changed_since"
10660
+ "get_tasks_changed_since",
10661
+ "heartbeat"
10668
10662
  ]);
10669
10663
  STANDARD_EXCLUDED = new Set([
10670
10664
  "get_org_chart",
10671
10665
  "set_reports_to",
10672
10666
  "rename_agent",
10673
10667
  "delete_agent",
10668
+ "unarchive_agent",
10674
10669
  "create_webhook",
10675
10670
  "list_webhooks",
10676
10671
  "delete_webhook",
@@ -11516,8 +11511,8 @@ ${text}` }] };
11516
11511
  });
11517
11512
  }
11518
11513
  if (shouldRegisterTool("register_agent")) {
11519
- server.tool("register_agent", "Register an agent. Name must be from the project's configured pool. Returns a conflict error with available name suggestions if the name is taken or not allowed.", {
11520
- name: exports_external.string().describe("Agent name \u2014 must be from the project's allowed pool (Roman names by default). Use suggest_agent_name first if unsure."),
11514
+ server.tool("register_agent", "Register an agent. Any name is allowed \u2014 the configured pool is advisory, not enforced. Returns a conflict error if the name is held by a recently-active agent.", {
11515
+ name: exports_external.string().describe("Agent name \u2014 any name is allowed. Use suggest_agent_name to see pool suggestions and avoid conflicts."),
11521
11516
  description: exports_external.string().optional(),
11522
11517
  capabilities: exports_external.array(exports_external.string()).optional().describe("Agent capabilities/skills for task routing (e.g. ['typescript', 'testing', 'devops'])"),
11523
11518
  session_id: exports_external.string().optional().describe("Unique ID for this coding session (e.g. process PID + timestamp, or env var). Used to detect name collisions across sessions. Store it and pass on every register_agent call."),
@@ -11525,17 +11520,19 @@ ${text}` }] };
11525
11520
  }, async ({ name, description, capabilities, session_id, working_dir }) => {
11526
11521
  try {
11527
11522
  const pool = getAgentPoolForProject(working_dir);
11528
- const result = registerAgent({ name, description, capabilities, session_id, working_dir, pool });
11523
+ const result = registerAgent({ name, description, capabilities, session_id, working_dir, pool: pool || undefined });
11529
11524
  if (isAgentConflict(result)) {
11530
11525
  const suggestLine = result.suggestions && result.suggestions.length > 0 ? `
11531
11526
  Available names: ${result.suggestions.join(", ")}` : "";
11532
- const hint = result.pool_violation ? `POOL_VIOLATION: ${result.message}${suggestLine}` : `CONFLICT: ${result.message}${suggestLine}`;
11527
+ const hint = `CONFLICT: ${result.message}${suggestLine}`;
11533
11528
  return {
11534
11529
  content: [{ type: "text", text: hint }],
11535
11530
  isError: true
11536
11531
  };
11537
11532
  }
11538
11533
  const agent = result;
11534
+ const poolLine = pool ? `
11535
+ Pool: [${pool.join(", ")}]` : "";
11539
11536
  return {
11540
11537
  content: [{
11541
11538
  type: "text",
@@ -11543,8 +11540,7 @@ Available names: ${result.suggestions.join(", ")}` : "";
11543
11540
  ID: ${agent.id}
11544
11541
  Name: ${agent.name}${agent.description ? `
11545
11542
  Description: ${agent.description}` : ""}
11546
- Session: ${agent.session_id ?? "unbound"}
11547
- Pool: [${pool.join(", ")}]
11543
+ Session: ${agent.session_id ?? "unbound"}${poolLine}
11548
11544
  Created: ${agent.created_at}
11549
11545
  Last seen: ${agent.last_seen_at}`
11550
11546
  }]
@@ -11555,21 +11551,32 @@ Last seen: ${agent.last_seen_at}`
11555
11551
  });
11556
11552
  }
11557
11553
  if (shouldRegisterTool("suggest_agent_name")) {
11558
- server.tool("suggest_agent_name", "Get available agent names for a project. Call this before register_agent to avoid conflicts.", {
11559
- working_dir: exports_external.string().optional().describe("Your working directory \u2014 used to look up the project's allowed name pool")
11554
+ server.tool("suggest_agent_name", "Get available agent names for a project. Shows configured pool, active agents, and suggestions. If no pool is configured, any name is allowed.", {
11555
+ working_dir: exports_external.string().optional().describe("Your working directory \u2014 used to look up the project's allowed name pool from config")
11560
11556
  }, async ({ working_dir }) => {
11561
11557
  try {
11562
11558
  const pool = getAgentPoolForProject(working_dir);
11563
- const available = getAvailableNamesFromPool(pool, getDatabase());
11564
11559
  const cutoff = new Date(Date.now() - 30 * 60 * 1000).toISOString();
11565
- const active = listAgents().filter((a) => a.last_seen_at > cutoff && pool.map((n) => n.toLowerCase()).includes(a.name));
11560
+ const allActive = listAgents().filter((a) => a.last_seen_at > cutoff);
11561
+ if (!pool) {
11562
+ const lines2 = [
11563
+ "No agent pool configured \u2014 any name is allowed.",
11564
+ allActive.length > 0 ? `Active agents (avoid these names): ${allActive.map((a) => `${a.name} (seen ${Math.round((Date.now() - new Date(a.last_seen_at).getTime()) / 60000)}m ago)`).join(", ")}` : "No active agents.",
11565
+ `
11566
+ To restrict names, configure agent_pool or project_pools in ~/.todos/config.json`
11567
+ ];
11568
+ return { content: [{ type: "text", text: lines2.join(`
11569
+ `) }] };
11570
+ }
11571
+ const available = getAvailableNamesFromPool(pool, getDatabase());
11572
+ const activeInPool = allActive.filter((a) => pool.map((n) => n.toLowerCase()).includes(a.name));
11566
11573
  const lines = [
11567
11574
  `Project pool: ${pool.join(", ")}`,
11568
11575
  `Available now (${available.length}): ${available.length > 0 ? available.join(", ") : "none \u2014 all names in use"}`,
11569
- active.length > 0 ? `Active agents: ${active.map((a) => `${a.name} (seen ${Math.round((Date.now() - new Date(a.last_seen_at).getTime()) / 60000)}m ago)`).join(", ")}` : "Active agents: none",
11576
+ activeInPool.length > 0 ? `Active agents: ${activeInPool.map((a) => `${a.name} (seen ${Math.round((Date.now() - new Date(a.last_seen_at).getTime()) / 60000)}m ago)`).join(", ")}` : "Active agents: none",
11570
11577
  available.length > 0 ? `
11571
11578
  Suggested: ${available[0]}` : `
11572
- No names available yet. Wait for an active agent to go stale (30min timeout).`
11579
+ No names available. Wait for an active agent to go stale (30min timeout).`
11573
11580
  ];
11574
11581
  return { content: [{ type: "text", text: lines.join(`
11575
11582
  `) }] };
@@ -11579,14 +11586,17 @@ No names available yet. Wait for an active agent to go stale (30min timeout).`
11579
11586
  });
11580
11587
  }
11581
11588
  if (shouldRegisterTool("list_agents")) {
11582
- server.tool("list_agents", "List all registered agents", {}, async () => {
11589
+ server.tool("list_agents", "List all registered agents. By default shows only active agents \u2014 set include_archived to see archived ones too.", {
11590
+ include_archived: exports_external.boolean().optional().describe("Include archived agents in the list (default: false)")
11591
+ }, async ({ include_archived }) => {
11583
11592
  try {
11584
- const agents = listAgents();
11593
+ const agents = listAgents({ include_archived: include_archived ?? false });
11585
11594
  if (agents.length === 0) {
11586
11595
  return { content: [{ type: "text", text: "No agents registered." }] };
11587
11596
  }
11588
11597
  const text = agents.map((a) => {
11589
- return `${a.id} | ${a.name}${a.description ? ` - ${a.description}` : ""} (last seen: ${a.last_seen_at})`;
11598
+ const statusTag = a.status === "archived" ? " [archived]" : "";
11599
+ return `${a.id} | ${a.name}${statusTag}${a.description ? ` - ${a.description}` : ""} (last seen: ${a.last_seen_at})`;
11590
11600
  }).join(`
11591
11601
  `);
11592
11602
  return { content: [{ type: "text", text: `${agents.length} agent(s):
@@ -11654,7 +11664,7 @@ ID: ${updated.id}`
11654
11664
  });
11655
11665
  }
11656
11666
  if (shouldRegisterTool("delete_agent")) {
11657
- server.tool("delete_agent", "Delete an agent permanently. Resolve by id or name.", {
11667
+ server.tool("delete_agent", "Archive an agent (soft delete). The agent is hidden from list_agents but preserved for task history. Use unarchive_agent to restore. Resolve by id or name.", {
11658
11668
  id: exports_external.string().optional(),
11659
11669
  name: exports_external.string().optional()
11660
11670
  }, async ({ id, name }) => {
@@ -11666,13 +11676,63 @@ ID: ${updated.id}`
11666
11676
  if (!agent) {
11667
11677
  return { content: [{ type: "text", text: `Agent not found: ${id || name}` }], isError: true };
11668
11678
  }
11669
- const deleted = deleteAgent(agent.id);
11679
+ const archived = archiveAgent(agent.id);
11670
11680
  return {
11671
11681
  content: [{
11672
11682
  type: "text",
11673
- text: deleted ? `Agent deleted: ${agent.name} (${agent.id})` : `Failed to delete agent: ${agent.name}`
11683
+ text: archived ? `Agent archived: ${agent.name} (${agent.id}). Use unarchive_agent to restore.` : `Failed to archive agent: ${agent.name}`
11674
11684
  }],
11675
- isError: !deleted
11685
+ isError: !archived
11686
+ };
11687
+ } catch (e) {
11688
+ return { content: [{ type: "text", text: formatError(e) }], isError: true };
11689
+ }
11690
+ });
11691
+ }
11692
+ if (shouldRegisterTool("unarchive_agent")) {
11693
+ server.tool("unarchive_agent", "Restore an archived agent back to active status. Resolve by id or name.", {
11694
+ id: exports_external.string().optional(),
11695
+ name: exports_external.string().optional()
11696
+ }, async ({ id, name }) => {
11697
+ try {
11698
+ if (!id && !name) {
11699
+ return { content: [{ type: "text", text: "Provide either id or name." }], isError: true };
11700
+ }
11701
+ const agent = id ? getAgent(id) : getAgentByName(name);
11702
+ if (!agent) {
11703
+ return { content: [{ type: "text", text: `Agent not found: ${id || name}` }], isError: true };
11704
+ }
11705
+ if (agent.status === "active") {
11706
+ return { content: [{ type: "text", text: `Agent ${agent.name} is already active.` }] };
11707
+ }
11708
+ const restored = unarchiveAgent(agent.id);
11709
+ return {
11710
+ content: [{
11711
+ type: "text",
11712
+ text: restored ? `Agent restored: ${agent.name} (${agent.id}) is now active.` : `Failed to restore agent: ${agent.name}`
11713
+ }],
11714
+ isError: !restored
11715
+ };
11716
+ } catch (e) {
11717
+ return { content: [{ type: "text", text: formatError(e) }], isError: true };
11718
+ }
11719
+ });
11720
+ }
11721
+ if (shouldRegisterTool("heartbeat")) {
11722
+ server.tool("heartbeat", "Update your last_seen_at timestamp to signal you're still active. Call periodically during long tasks to prevent being marked stale.", {
11723
+ agent_id: exports_external.string().describe("Your agent ID or name.")
11724
+ }, async ({ agent_id }) => {
11725
+ try {
11726
+ const agent = getAgent(agent_id) || getAgentByName(agent_id);
11727
+ if (!agent) {
11728
+ return { content: [{ type: "text", text: `Agent not found: ${agent_id}` }], isError: true };
11729
+ }
11730
+ updateAgentActivity(agent.id);
11731
+ return {
11732
+ content: [{
11733
+ type: "text",
11734
+ text: `Heartbeat: ${agent.name} (${agent.id}) \u2014 last_seen_at updated to ${new Date().toISOString()}`
11735
+ }]
11676
11736
  };
11677
11737
  } catch (e) {
11678
11738
  return { content: [{ type: "text", text: formatError(e) }], isError: true };
@@ -12775,6 +12835,8 @@ Claimed: ${formatTask(result.claimed)}`);
12775
12835
  "get_agent",
12776
12836
  "rename_agent",
12777
12837
  "delete_agent",
12838
+ "unarchive_agent",
12839
+ "heartbeat",
12778
12840
  "get_my_tasks",
12779
12841
  "get_org_chart",
12780
12842
  "set_reports_to",
@@ -12912,22 +12974,30 @@ Claimed: ${formatTask(result.claimed)}`);
12912
12974
  delete_plan: `Delete a plan. Tasks in the plan are orphaned, not deleted.
12913
12975
  Params: id(string, req)
12914
12976
  Example: {id: 'a1b2c3d4'}`,
12915
- suggest_agent_name: `Get available agent names for your project before registering. Shows the pool, which names are active, and the best suggestion.
12916
- Params: working_dir(string \u2014 your working directory, used to look up project pool)
12977
+ suggest_agent_name: `Check available agent names before registering. Shows active agents and, if a pool is configured, which pool names are free.
12978
+ Params: working_dir(string \u2014 your working directory, used to look up project pool from config)
12917
12979
  Example: {working_dir: '/workspace/platform'}`,
12918
- register_agent: `Register an agent. Name must be from the project's pool (call suggest_agent_name first). Returns CONFLICT or POOL_VIOLATION with suggestions if name is taken or not allowed.
12919
- Params: name(string, req), description(string), session_id(string \u2014 unique per session, e.g. PID+timestamp), working_dir(string, req \u2014 used to determine project pool)
12920
- Example: {name: 'cassius', session_id: 'abc123-1741952000', working_dir: '/workspace/platform'}`,
12921
- list_agents: "List all registered agents with IDs, names, and last seen timestamps. No params.",
12980
+ register_agent: `Register an agent. Any name is allowed \u2014 pool is advisory. Returns CONFLICT if name is held by a recently-active agent.
12981
+ Params: name(string, req), description(string), capabilities(string[]), session_id(string \u2014 unique per session), working_dir(string \u2014 used to determine project pool)
12982
+ Example: {name: 'my-agent', session_id: 'abc123-1741952000', working_dir: '/workspace/platform'}`,
12983
+ list_agents: `List all registered agents (active by default). Set include_archived: true to see archived agents.
12984
+ Params: include_archived(boolean, optional)
12985
+ Example: {include_archived: true}`,
12922
12986
  get_agent: `Get agent details by ID or name. Provide one of id or name.
12923
12987
  Params: id(string), name(string)
12924
12988
  Example: {name: 'maximus'}`,
12925
12989
  rename_agent: `Rename an agent. Resolve by id or current name.
12926
12990
  Params: id(string), name(string \u2014 current name), new_name(string, req)
12927
12991
  Example: {name: 'old-name', new_name: 'new-name'}`,
12928
- delete_agent: `Delete an agent permanently. Resolve by id or name.
12992
+ delete_agent: `Archive an agent (soft delete). Agent is preserved for task history but hidden from list_agents. Use unarchive_agent to restore.
12993
+ Params: id(string), name(string)
12994
+ Example: {name: 'maximus'}`,
12995
+ unarchive_agent: `Restore an archived agent back to active status.
12929
12996
  Params: id(string), name(string)
12930
12997
  Example: {name: 'maximus'}`,
12998
+ heartbeat: `Update last_seen_at timestamp to signal you're still active. Call periodically during long tasks.
12999
+ Params: agent_id(string, req \u2014 your agent ID or name)
13000
+ Example: {agent_id: 'maximus'}`,
12931
13001
  get_my_tasks: `Get all tasks assigned to/created by an agent, with stats (pending/active/done/rate).
12932
13002
  Params: agent_name(string, req)
12933
13003
  Example: {agent_name: 'maximus'}`,
@@ -19,7 +19,9 @@ export declare function registerAgent(input: RegisterAgentInput, db?: Database):
19
19
  export declare function isAgentConflict(result: Agent | AgentConflictError): result is AgentConflictError;
20
20
  export declare function getAgent(id: string, db?: Database): Agent | null;
21
21
  export declare function getAgentByName(name: string, db?: Database): Agent | null;
22
- export declare function listAgents(db?: Database): Agent[];
22
+ export declare function listAgents(opts?: {
23
+ include_archived?: boolean;
24
+ } | Database, db?: Database): Agent[];
23
25
  export declare function updateAgentActivity(id: string, db?: Database): void;
24
26
  export declare function updateAgent(id: string, input: {
25
27
  name?: string;
@@ -33,7 +35,12 @@ export declare function updateAgent(id: string, input: {
33
35
  org_id?: string | null;
34
36
  metadata?: Record<string, unknown>;
35
37
  }, db?: Database): Agent;
38
+ /** Soft-delete: archives the agent instead of removing it. Tasks referencing this agent are preserved. */
36
39
  export declare function deleteAgent(id: string, db?: Database): boolean;
40
+ /** Archive an agent (soft delete). */
41
+ export declare function archiveAgent(id: string, db?: Database): Agent | null;
42
+ /** Restore an archived agent. */
43
+ export declare function unarchiveAgent(id: string, db?: Database): Agent | null;
37
44
  /** Get direct reports of an agent. */
38
45
  export declare function getDirectReports(agentId: string, db?: Database): Agent[];
39
46
  /** Get the full org tree starting from top-level agents (reports_to IS NULL). */
@@ -1 +1 @@
1
- {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/db/agents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,KAAK,EAAE,kBAAkB,EAAY,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAMjG;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,QAAQ,GAAG,MAAM,EAAE,CAOhF;AAeD;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,kBAAkB,CAkFlG;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,KAAK,GAAG,kBAAkB,GAAG,MAAM,IAAI,kBAAkB,CAEhG;AAED,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,IAAI,CAIhE;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,KAAK,GAAG,IAAI,CAKxE;AAED,wBAAgB,UAAU,CAAC,EAAE,CAAC,EAAE,QAAQ,GAAG,KAAK,EAAE,CAGjD;AAED,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,IAAI,CAGnE;AAED,wBAAgB,WAAW,CACzB,EAAE,EAAE,MAAM,EACV,KAAK,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,EACtO,EAAE,CAAC,EAAE,QAAQ,GACZ,KAAK,CAoDP;AAED,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,OAAO,CAG9D;AAED,sCAAsC;AACtC,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,KAAK,EAAE,CAGxE;AAED,iFAAiF;AACjF,wBAAgB,WAAW,CAAC,EAAE,CAAC,EAAE,QAAQ,GAAG,OAAO,EAAE,CAepD;AAED,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,KAAK,CAAC;IACb,OAAO,EAAE,OAAO,EAAE,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,iBAAiB,EAAE,MAAM,EAAE,EAAE,oBAAoB,EAAE,MAAM,EAAE,GAAG,MAAM,CAUrG;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,MAAM,EAAE,EACtB,IAAI,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,EAC7C,EAAE,CAAC,EAAE,QAAQ,GACZ;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,CAanC"}
1
+ {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/db/agents.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/db/database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAItC,eAAO,MAAM,mBAAmB,KAAK,CAAC;AAwgBtC,wBAAgB,WAAW,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAkBrD;AAwRD,wBAAgB,aAAa,IAAI,IAAI,CAKpC;AAED,wBAAgB,aAAa,IAAI,IAAI,CAEpC;AAED,wBAAgB,GAAG,IAAI,MAAM,CAE5B;AAED,wBAAgB,IAAI,IAAI,MAAM,CAE7B;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAK9D;AAED,wBAAgB,gBAAgB,CAAC,KAAK,SAAa,GAAG,MAAM,CAG3D;AAED,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI,CAGpD;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA0B9F"}
1
+ {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/db/database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAItC,eAAO,MAAM,mBAAmB,KAAK,CAAC;AA8gBtC,wBAAgB,WAAW,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAkBrD;AAyRD,wBAAgB,aAAa,IAAI,IAAI,CAKpC;AAED,wBAAgB,aAAa,IAAI,IAAI,CAEpC;AAED,wBAAgB,GAAG,IAAI,MAAM,CAE5B;AAED,wBAAgB,IAAI,IAAI,MAAM,CAE7B;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAK9D;AAED,wBAAgB,gBAAgB,CAAC,KAAK,SAAa,GAAG,MAAM,CAG3D;AAED,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,QAAQ,GAAG,IAAI,CAGpD;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CA0B9F"}
package/dist/index.d.ts CHANGED
@@ -6,7 +6,7 @@ export type { TaskGraphNode, TaskGraph, BulkCreateTaskInput, ActiveWorkItem, Sta
6
6
  export { createProject, getProject, getProjectByPath, getProjectWithSources, listProjects, updateProject, deleteProject, ensureProject, nextTaskShortId, slugify, addProjectSource, removeProjectSource, listProjectSources, } from "./db/projects.js";
7
7
  export { createPlan, getPlan, listPlans, updatePlan, deletePlan, } from "./db/plans.js";
8
8
  export { addComment, getComment, listComments, deleteComment, logProgress, } from "./db/comments.js";
9
- export { registerAgent, isAgentConflict, getAgent, getAgentByName, listAgents, updateAgent, updateAgentActivity, deleteAgent, getDirectReports, getOrgChart, matchCapabilities, getCapableAgents, } from "./db/agents.js";
9
+ export { registerAgent, isAgentConflict, getAgent, getAgentByName, listAgents, updateAgent, updateAgentActivity, deleteAgent, archiveAgent, unarchiveAgent, getDirectReports, getOrgChart, matchCapabilities, getCapableAgents, } from "./db/agents.js";
10
10
  export type { OrgNode } from "./db/agents.js";
11
11
  export { createTaskList, getTaskList, getTaskListBySlug, listTaskLists, updateTaskList, deleteTaskList, ensureTaskList, } from "./db/task-lists.js";
12
12
  export { createSession, getSession, listSessions, updateSessionActivity, deleteSession, } from "./db/sessions.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACrD,YAAY,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAGnD,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,gBAAgB,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAG1G,OAAO,EACL,UAAU,EACV,OAAO,EACP,oBAAoB,EACpB,SAAS,EACT,UAAU,EACV,UAAU,EACV,UAAU,EACV,SAAS,EACT,YAAY,EACZ,QAAQ,EACR,UAAU,EACV,aAAa,EACb,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,eAAe,EACf,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,QAAQ,EACR,WAAW,EACX,aAAa,EACb,aAAa,EACb,QAAQ,EACR,oBAAoB,EACpB,aAAa,EACb,SAAS,EACT,cAAc,EACd,aAAa,EACb,eAAe,EACf,sBAAsB,EACtB,eAAe,GAChB,MAAM,eAAe,CAAC;AACvB,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,mBAAmB,EAAE,cAAc,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAGzI,OAAO,EACL,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,qBAAqB,EACrB,YAAY,EACZ,aAAa,EACb,aAAa,EACb,aAAa,EACb,eAAe,EACf,OAAO,EACP,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,UAAU,EACV,OAAO,EACP,SAAS,EACT,UAAU,EACV,UAAU,GACX,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,UAAU,EACV,UAAU,EACV,YAAY,EACZ,aAAa,EACb,WAAW,GACZ,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,aAAa,EACb,eAAe,EACf,QAAQ,EACR,cAAc,EACd,UAAU,EACV,WAAW,EACX,mBAAmB,EACnB,WAAW,EACX,gBAAgB,EAChB,WAAW,EACX,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAG9C,OAAO,EACL,cAAc,EACd,WAAW,EACX,iBAAiB,EACjB,aAAa,EACb,cAAc,EACd,cAAc,EACd,cAAc,GACf,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EACL,aAAa,EACb,UAAU,EACV,YAAY,EACZ,qBAAqB,EACrB,aAAa,GACd,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAGjF,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAG3G,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAGjH,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,EACvB,mBAAmB,EACnB,cAAc,EACd,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACjF,YAAY,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAGpE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,aAAa,EAAE,eAAe,EAAE,oBAAoB,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtJ,YAAY,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAGrE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACvF,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAGlD,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAG/F,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,EACtB,4BAA4B,EAC5B,oBAAoB,EACpB,kBAAkB,EAClB,2BAA2B,GAC5B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,YAAY,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAG/G,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,iBAAiB,EAAE,eAAe,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC7H,YAAY,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAGzC,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAC7D,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAGhE,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACnF,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAG5E,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC9C,YAAY,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGrD,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACjF,YAAY,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGtD,OAAO,EAAE,UAAU,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AACvE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAGvF,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAGjE,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACjG,YAAY,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGtD,YAAY,EACV,IAAI,EACJ,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,UAAU,EACV,UAAU,EACV,YAAY,EACZ,cAAc,EACd,WAAW,EACX,kBAAkB,EAClB,OAAO,EACP,kBAAkB,EAClB,aAAa,EACb,gBAAgB,EAChB,wBAAwB,EACxB,aAAa,EACb,gBAAgB,EAChB,wBAAwB,EACxB,IAAI,EACJ,eAAe,EACf,eAAe,EACf,UAAU,EACV,OAAO,EACP,kBAAkB,EAClB,KAAK,EACL,QAAQ,EACR,kBAAkB,EAClB,QAAQ,EACR,WAAW,EACX,mBAAmB,EACnB,mBAAmB,EACnB,UAAU,EACV,OAAO,EACP,UAAU,EACV,WAAW,EACX,OAAO,EACP,kBAAkB,EAClB,YAAY,EACZ,mBAAmB,EACnB,GAAG,EACH,cAAc,GACf,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,aAAa,EACb,eAAe,EACf,aAAa,EACb,oBAAoB,EACpB,iBAAiB,EACjB,oBAAoB,EACpB,iBAAiB,EACjB,SAAS,EACT,oBAAoB,EACpB,kBAAkB,EAClB,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -697,6 +697,11 @@ var MIGRATIONS = [
697
697
  `
698
698
  ALTER TABLE agents ADD COLUMN capabilities TEXT DEFAULT '[]';
699
699
  INSERT OR IGNORE INTO _migrations (id) VALUES (29);
700
+ `,
701
+ `
702
+ ALTER TABLE agents ADD COLUMN status TEXT NOT NULL DEFAULT 'active' CHECK(status IN ('active', 'archived'));
703
+ CREATE INDEX IF NOT EXISTS idx_agents_status ON agents(status);
704
+ INSERT OR IGNORE INTO _migrations (id) VALUES (30);
700
705
  `
701
706
  ];
702
707
  var _db = null;
@@ -764,6 +769,7 @@ function ensureSchema(db) {
764
769
  CREATE TABLE agents (
765
770
  id TEXT PRIMARY KEY, name TEXT NOT NULL UNIQUE, description TEXT,
766
771
  role TEXT DEFAULT 'agent', permissions TEXT DEFAULT '["*"]',
772
+ status TEXT NOT NULL DEFAULT 'active' CHECK(status IN ('active', 'archived')),
767
773
  metadata TEXT DEFAULT '{}',
768
774
  created_at TEXT NOT NULL DEFAULT (datetime('now')),
769
775
  last_seen_at TEXT NOT NULL DEFAULT (datetime('now'))
@@ -2830,7 +2836,7 @@ function deleteComment(id, db) {
2830
2836
  var AGENT_ACTIVE_WINDOW_MS = 30 * 60 * 1000;
2831
2837
  function getAvailableNamesFromPool(pool, db) {
2832
2838
  const cutoff = new Date(Date.now() - AGENT_ACTIVE_WINDOW_MS).toISOString();
2833
- const activeNames = new Set(db.query("SELECT name FROM agents WHERE last_seen_at > ?").all(cutoff).map((r) => r.name.toLowerCase()));
2839
+ const activeNames = new Set(db.query("SELECT name FROM agents WHERE status = 'active' AND last_seen_at > ?").all(cutoff).map((r) => r.name.toLowerCase()));
2834
2840
  return pool.filter((name) => !activeNames.has(name.toLowerCase()));
2835
2841
  }
2836
2842
  function shortUuid() {
@@ -2841,30 +2847,13 @@ function rowToAgent(row) {
2841
2847
  ...row,
2842
2848
  permissions: JSON.parse(row.permissions || '["*"]'),
2843
2849
  capabilities: JSON.parse(row.capabilities || "[]"),
2850
+ status: row.status || "active",
2844
2851
  metadata: JSON.parse(row.metadata || "{}")
2845
2852
  };
2846
2853
  }
2847
2854
  function registerAgent(input, db) {
2848
2855
  const d = db || getDatabase();
2849
2856
  const normalizedName = input.name.trim().toLowerCase();
2850
- if (input.pool && input.pool.length > 0) {
2851
- const poolLower = input.pool.map((n) => n.toLowerCase());
2852
- if (!poolLower.includes(normalizedName)) {
2853
- const available = getAvailableNamesFromPool(input.pool, d);
2854
- const suggestion = available.length > 0 ? available[0] : null;
2855
- return {
2856
- conflict: true,
2857
- pool_violation: true,
2858
- existing_id: "",
2859
- existing_name: normalizedName,
2860
- last_seen_at: "",
2861
- session_hint: null,
2862
- working_dir: input.working_dir || null,
2863
- suggestions: available.slice(0, 5),
2864
- message: `"${normalizedName}" is not in this project's agent pool [${input.pool.join(", ")}]. ${available.length > 0 ? `Try: ${available.slice(0, 3).join(", ")}` : "No names are currently available \u2014 wait for an active agent to go stale."}${suggestion ? ` Suggested: ${suggestion}` : ""}`
2865
- };
2866
- }
2867
- }
2868
2857
  const existing = getAgentByName(normalizedName, d);
2869
2858
  if (existing) {
2870
2859
  const lastSeenMs = new Date(existing.last_seen_at).getTime();
@@ -2885,7 +2874,7 @@ function registerAgent(input, db) {
2885
2874
  message: `Agent "${normalizedName}" is already active (last seen ${minutesAgo}m ago, session ${existing.session_id?.slice(0, 8)}\u2026, dir: ${existing.working_dir ?? "unknown"}). Are you that agent? If so, pass session_id="${existing.session_id}" to reclaim it. Otherwise choose a different name.${suggestions.length > 0 ? ` Available: ${suggestions.slice(0, 3).join(", ")}` : ""}`
2886
2875
  };
2887
2876
  }
2888
- const updates = ["last_seen_at = ?"];
2877
+ const updates = ["last_seen_at = ?", "status = 'active'"];
2889
2878
  const params = [now()];
2890
2879
  if (input.session_id && !sameSession) {
2891
2880
  updates.push("session_id = ?");
@@ -2939,9 +2928,19 @@ function getAgentByName(name, db) {
2939
2928
  const row = d.query("SELECT * FROM agents WHERE LOWER(name) = ?").get(normalizedName);
2940
2929
  return row ? rowToAgent(row) : null;
2941
2930
  }
2942
- function listAgents(db) {
2943
- const d = db || getDatabase();
2944
- return d.query("SELECT * FROM agents ORDER BY name").all().map(rowToAgent);
2931
+ function listAgents(opts, db) {
2932
+ let d;
2933
+ let includeArchived = false;
2934
+ if (opts && typeof opts === "object" && "query" in opts) {
2935
+ d = opts;
2936
+ } else {
2937
+ includeArchived = opts?.include_archived ?? false;
2938
+ d = db || getDatabase();
2939
+ }
2940
+ if (includeArchived) {
2941
+ return d.query("SELECT * FROM agents ORDER BY name").all().map(rowToAgent);
2942
+ }
2943
+ return d.query("SELECT * FROM agents WHERE status = 'active' ORDER BY name").all().map(rowToAgent);
2945
2944
  }
2946
2945
  function updateAgentActivity(id, db) {
2947
2946
  const d = db || getDatabase();
@@ -3000,7 +2999,17 @@ function updateAgent(id, input, db) {
3000
2999
  }
3001
3000
  function deleteAgent(id, db) {
3002
3001
  const d = db || getDatabase();
3003
- return d.run("DELETE FROM agents WHERE id = ?", [id]).changes > 0;
3002
+ return d.run("UPDATE agents SET status = 'archived', last_seen_at = ? WHERE id = ?", [now(), id]).changes > 0;
3003
+ }
3004
+ function archiveAgent(id, db) {
3005
+ const d = db || getDatabase();
3006
+ d.run("UPDATE agents SET status = 'archived', last_seen_at = ? WHERE id = ?", [now(), id]);
3007
+ return getAgent(id, d);
3008
+ }
3009
+ function unarchiveAgent(id, db) {
3010
+ const d = db || getDatabase();
3011
+ d.run("UPDATE agents SET status = 'active', last_seen_at = ? WHERE id = ?", [now(), id]);
3012
+ return getAgent(id, d);
3004
3013
  }
3005
3014
  function getDirectReports(agentId, db) {
3006
3015
  const d = db || getDatabase();
@@ -4524,6 +4533,7 @@ export {
4524
4533
  updateAgentActivity,
4525
4534
  updateAgent,
4526
4535
  unlockTask,
4536
+ unarchiveAgent,
4527
4537
  taskFromTemplate,
4528
4538
  syncWithAgents,
4529
4539
  syncWithAgent,
@@ -4661,6 +4671,7 @@ export {
4661
4671
  bulkCreateTasks,
4662
4672
  bulkAddTaskFiles,
4663
4673
  autoDetectFileRelationships,
4674
+ archiveAgent,
4664
4675
  addTaskRelationship,
4665
4676
  addTaskFile,
4666
4677
  addProjectSource,
@@ -29,11 +29,6 @@ export interface TodosConfig {
29
29
  /** Per-project agent name pools, keyed by working directory path prefix. */
30
30
  project_pools?: Record<string, string[]>;
31
31
  }
32
- /**
33
- * Built-in default agent name pool (Roman names convention).
34
- * Used when no pool is configured in config.json.
35
- */
36
- export declare const DEFAULT_AGENT_POOL: string[];
37
32
  export declare function loadConfig(): TodosConfig;
38
33
  export declare function getSyncAgentsFromConfig(): string[] | null;
39
34
  export declare function getAgentTaskListId(agent: string): string | null;
@@ -42,8 +37,8 @@ export declare function getTaskPrefixConfig(): TaskPrefixConfig | null;
42
37
  /**
43
38
  * Get the agent name pool for a given working directory.
44
39
  * Checks project_pools for the longest matching path prefix, then falls back
45
- * to agent_pool, then to the built-in DEFAULT_AGENT_POOL.
40
+ * to agent_pool. Returns null if no pool is configured (no name restriction).
46
41
  */
47
- export declare function getAgentPoolForProject(workingDir?: string): string[];
42
+ export declare function getAgentPoolForProject(workingDir?: string): string[] | null;
48
43
  export declare function getCompletionGuardConfig(projectPath?: string | null): Required<CompletionGuardConfig>;
49
44
  //# sourceMappingURL=config.d.ts.map