@hasna/todos 0.9.79 → 0.9.80

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
@@ -9658,6 +9658,9 @@ var init_handoffs = __esm(() => {
9658
9658
 
9659
9659
  // src/mcp/index.ts
9660
9660
  var exports_mcp = {};
9661
+ __export(exports_mcp, {
9662
+ applyFocus: () => applyFocus
9663
+ });
9661
9664
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
9662
9665
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
9663
9666
  import { readFileSync as readFileSync3 } from "fs";
@@ -9679,6 +9682,28 @@ function shouldRegisterTool(name) {
9679
9682
  return !STANDARD_EXCLUDED.has(name);
9680
9683
  return true;
9681
9684
  }
9685
+ function getAgentFocus(agentId) {
9686
+ const sessionFocus = agentFocusMap.get(agentId);
9687
+ if (sessionFocus)
9688
+ return sessionFocus;
9689
+ try {
9690
+ const agent = getAgentByName(agentId) || getAgent(agentId);
9691
+ if (agent && agent.active_project_id) {
9692
+ return { agent_id: agentId, project_id: agent.active_project_id };
9693
+ }
9694
+ } catch {}
9695
+ return;
9696
+ }
9697
+ function applyFocus(params, agentId) {
9698
+ if (!agentId)
9699
+ return;
9700
+ if (params.project_id)
9701
+ return;
9702
+ const focus = getAgentFocus(agentId);
9703
+ if (focus?.project_id) {
9704
+ params.project_id = focus.project_id;
9705
+ }
9706
+ }
9682
9707
  function formatError(error) {
9683
9708
  if (error instanceof VersionConflictError) {
9684
9709
  return JSON.stringify({ code: VersionConflictError.code, message: error.message, suggestion: VersionConflictError.suggestion });
@@ -9777,7 +9802,7 @@ async function main() {
9777
9802
  const transport = new StdioServerTransport;
9778
9803
  await server.connect(transport);
9779
9804
  }
9780
- var server, TODOS_PROFILE, MINIMAL_TOOLS, STANDARD_EXCLUDED;
9805
+ var server, TODOS_PROFILE, MINIMAL_TOOLS, STANDARD_EXCLUDED, agentFocusMap;
9781
9806
  var init_mcp = __esm(() => {
9782
9807
  init_zod();
9783
9808
  init_tasks();
@@ -9824,6 +9849,7 @@ var init_mcp = __esm(() => {
9824
9849
  "delete_template",
9825
9850
  "approve_task"
9826
9851
  ]);
9852
+ agentFocusMap = new Map;
9827
9853
  if (shouldRegisterTool("create_task")) {
9828
9854
  server.tool("create_task", "Create a new task", {
9829
9855
  title: exports_external.string(),
@@ -10602,6 +10628,52 @@ ${text}` }] };
10602
10628
  }
10603
10629
  });
10604
10630
  }
10631
+ if (shouldRegisterTool("set_focus")) {
10632
+ server.tool("set_focus", "Focus this agent on a project. All list/search/status tools will default to this project.", {
10633
+ agent_id: exports_external.string().describe("Agent ID or name"),
10634
+ project_id: exports_external.string().optional().describe("Project to focus on. Omit to clear."),
10635
+ task_list_id: exports_external.string().optional().describe("Task list to focus on")
10636
+ }, async ({ agent_id, project_id, task_list_id }) => {
10637
+ try {
10638
+ const resolvedProject = project_id ? resolveId(project_id, "projects") : undefined;
10639
+ const focus = { agent_id, project_id: resolvedProject, task_list_id };
10640
+ agentFocusMap.set(agent_id, focus);
10641
+ try {
10642
+ const agent = getAgentByName(agent_id) || getAgent(agent_id);
10643
+ if (agent) {
10644
+ const db = getDatabase();
10645
+ db.run("UPDATE agents SET active_project_id = ? WHERE id = ?", [resolvedProject || null, agent.id]);
10646
+ }
10647
+ } catch {}
10648
+ const projectName = resolvedProject ? ` (${resolvedProject.slice(0, 8)})` : "";
10649
+ return { content: [{ type: "text", text: `Focused on project${projectName}. Read tools will default to this scope. Pass explicit project_id to override.` }] };
10650
+ } catch (e) {
10651
+ return { content: [{ type: "text", text: formatError(e) }], isError: true };
10652
+ }
10653
+ });
10654
+ }
10655
+ if (shouldRegisterTool("get_focus")) {
10656
+ server.tool("get_focus", "Get the current focus for an agent.", { agent_id: exports_external.string().describe("Agent ID or name") }, async ({ agent_id }) => {
10657
+ const focus = getAgentFocus(agent_id);
10658
+ if (!focus?.project_id) {
10659
+ return { content: [{ type: "text", text: "No focus set. Showing all projects." }] };
10660
+ }
10661
+ return { content: [{ type: "text", text: `Focused on project: ${focus.project_id}${focus.task_list_id ? `, task list: ${focus.task_list_id}` : ""}` }] };
10662
+ });
10663
+ }
10664
+ if (shouldRegisterTool("unfocus")) {
10665
+ server.tool("unfocus", "Clear focus \u2014 show all projects and tasks.", { agent_id: exports_external.string().describe("Agent ID or name") }, async ({ agent_id }) => {
10666
+ agentFocusMap.delete(agent_id);
10667
+ try {
10668
+ const agent = getAgentByName(agent_id) || getAgent(agent_id);
10669
+ if (agent) {
10670
+ const db = getDatabase();
10671
+ db.run("UPDATE agents SET active_project_id = NULL WHERE id = ?", [agent.id]);
10672
+ }
10673
+ } catch {}
10674
+ return { content: [{ type: "text", text: "Focus cleared. Showing all projects." }] };
10675
+ });
10676
+ }
10605
10677
  if (shouldRegisterTool("register_agent")) {
10606
10678
  server.tool("register_agent", "Register an agent. Pass session_id (unique per coding session) to prevent name conflicts. Returns conflict error if name is taken by an active agent in a different session.", {
10607
10679
  name: exports_external.string(),
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env bun
2
- export {};
2
+ export declare function applyFocus(params: Record<string, any>, agentId?: string): void;
3
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":""}
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"}
package/dist/mcp/index.js CHANGED
@@ -7447,6 +7447,29 @@ function shouldRegisterTool(name) {
7447
7447
  return !STANDARD_EXCLUDED.has(name);
7448
7448
  return true;
7449
7449
  }
7450
+ var agentFocusMap = new Map;
7451
+ function getAgentFocus(agentId) {
7452
+ const sessionFocus = agentFocusMap.get(agentId);
7453
+ if (sessionFocus)
7454
+ return sessionFocus;
7455
+ try {
7456
+ const agent = getAgentByName(agentId) || getAgent(agentId);
7457
+ if (agent && agent.active_project_id) {
7458
+ return { agent_id: agentId, project_id: agent.active_project_id };
7459
+ }
7460
+ } catch {}
7461
+ return;
7462
+ }
7463
+ function applyFocus(params, agentId) {
7464
+ if (!agentId)
7465
+ return;
7466
+ if (params.project_id)
7467
+ return;
7468
+ const focus = getAgentFocus(agentId);
7469
+ if (focus?.project_id) {
7470
+ params.project_id = focus.project_id;
7471
+ }
7472
+ }
7450
7473
  function formatError(error) {
7451
7474
  if (error instanceof VersionConflictError) {
7452
7475
  return JSON.stringify({ code: VersionConflictError.code, message: error.message, suggestion: VersionConflictError.suggestion });
@@ -8319,6 +8342,52 @@ if (shouldRegisterTool("sync")) {
8319
8342
  }
8320
8343
  });
8321
8344
  }
8345
+ if (shouldRegisterTool("set_focus")) {
8346
+ server.tool("set_focus", "Focus this agent on a project. All list/search/status tools will default to this project.", {
8347
+ agent_id: exports_external.string().describe("Agent ID or name"),
8348
+ project_id: exports_external.string().optional().describe("Project to focus on. Omit to clear."),
8349
+ task_list_id: exports_external.string().optional().describe("Task list to focus on")
8350
+ }, async ({ agent_id, project_id, task_list_id }) => {
8351
+ try {
8352
+ const resolvedProject = project_id ? resolveId(project_id, "projects") : undefined;
8353
+ const focus = { agent_id, project_id: resolvedProject, task_list_id };
8354
+ agentFocusMap.set(agent_id, focus);
8355
+ try {
8356
+ const agent = getAgentByName(agent_id) || getAgent(agent_id);
8357
+ if (agent) {
8358
+ const db = getDatabase();
8359
+ db.run("UPDATE agents SET active_project_id = ? WHERE id = ?", [resolvedProject || null, agent.id]);
8360
+ }
8361
+ } catch {}
8362
+ const projectName = resolvedProject ? ` (${resolvedProject.slice(0, 8)})` : "";
8363
+ return { content: [{ type: "text", text: `Focused on project${projectName}. Read tools will default to this scope. Pass explicit project_id to override.` }] };
8364
+ } catch (e) {
8365
+ return { content: [{ type: "text", text: formatError(e) }], isError: true };
8366
+ }
8367
+ });
8368
+ }
8369
+ if (shouldRegisterTool("get_focus")) {
8370
+ server.tool("get_focus", "Get the current focus for an agent.", { agent_id: exports_external.string().describe("Agent ID or name") }, async ({ agent_id }) => {
8371
+ const focus = getAgentFocus(agent_id);
8372
+ if (!focus?.project_id) {
8373
+ return { content: [{ type: "text", text: "No focus set. Showing all projects." }] };
8374
+ }
8375
+ return { content: [{ type: "text", text: `Focused on project: ${focus.project_id}${focus.task_list_id ? `, task list: ${focus.task_list_id}` : ""}` }] };
8376
+ });
8377
+ }
8378
+ if (shouldRegisterTool("unfocus")) {
8379
+ server.tool("unfocus", "Clear focus \u2014 show all projects and tasks.", { agent_id: exports_external.string().describe("Agent ID or name") }, async ({ agent_id }) => {
8380
+ agentFocusMap.delete(agent_id);
8381
+ try {
8382
+ const agent = getAgentByName(agent_id) || getAgent(agent_id);
8383
+ if (agent) {
8384
+ const db = getDatabase();
8385
+ db.run("UPDATE agents SET active_project_id = NULL WHERE id = ?", [agent.id]);
8386
+ }
8387
+ } catch {}
8388
+ return { content: [{ type: "text", text: "Focus cleared. Showing all projects." }] };
8389
+ });
8390
+ }
8322
8391
  if (shouldRegisterTool("register_agent")) {
8323
8392
  server.tool("register_agent", "Register an agent. Pass session_id (unique per coding session) to prevent name conflicts. Returns conflict error if name is taken by an active agent in a different session.", {
8324
8393
  name: exports_external.string(),
@@ -9900,3 +9969,6 @@ main().catch((err) => {
9900
9969
  console.error("MCP server error:", err);
9901
9970
  process.exit(1);
9902
9971
  });
9972
+ export {
9973
+ applyFocus
9974
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/todos",
3
- "version": "0.9.79",
3
+ "version": "0.9.80",
4
4
  "description": "Universal task management for AI coding agents - CLI + MCP server + interactive TUI",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",