cmdr-agent 2.2.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/dist/package.json +1 -1
  2. package/dist/src/cli/commands.js +1 -1
  3. package/dist/src/cli/commands.js.map +1 -1
  4. package/dist/src/cli/ink/App.d.ts +2 -0
  5. package/dist/src/cli/ink/App.d.ts.map +1 -1
  6. package/dist/src/cli/ink/App.js +56 -7
  7. package/dist/src/cli/ink/App.js.map +1 -1
  8. package/dist/src/cli/repl.d.ts.map +1 -1
  9. package/dist/src/cli/repl.js +35 -1
  10. package/dist/src/cli/repl.js.map +1 -1
  11. package/dist/src/config/mcp-registry.d.ts +45 -0
  12. package/dist/src/config/mcp-registry.d.ts.map +1 -0
  13. package/dist/src/config/mcp-registry.js +156 -0
  14. package/dist/src/config/mcp-registry.js.map +1 -0
  15. package/dist/src/config/schema.d.ts +8 -8
  16. package/dist/src/core/agent-runner.d.ts.map +1 -1
  17. package/dist/src/core/agent-runner.js +22 -0
  18. package/dist/src/core/agent-runner.js.map +1 -1
  19. package/dist/src/core/hooks.d.ts +61 -0
  20. package/dist/src/core/hooks.d.ts.map +1 -0
  21. package/dist/src/core/hooks.js +140 -0
  22. package/dist/src/core/hooks.js.map +1 -0
  23. package/dist/src/core/permissions.d.ts +43 -0
  24. package/dist/src/core/permissions.d.ts.map +1 -1
  25. package/dist/src/core/permissions.js +108 -0
  26. package/dist/src/core/permissions.js.map +1 -1
  27. package/dist/src/core/types.d.ts +5 -0
  28. package/dist/src/core/types.d.ts.map +1 -1
  29. package/dist/src/tools/built-in/cron-tools.d.ts +19 -0
  30. package/dist/src/tools/built-in/cron-tools.d.ts.map +1 -0
  31. package/dist/src/tools/built-in/cron-tools.js +86 -0
  32. package/dist/src/tools/built-in/cron-tools.js.map +1 -0
  33. package/dist/src/tools/built-in/index.d.ts +7 -1
  34. package/dist/src/tools/built-in/index.d.ts.map +1 -1
  35. package/dist/src/tools/built-in/index.js +13 -2
  36. package/dist/src/tools/built-in/index.js.map +1 -1
  37. package/dist/src/tools/built-in/mcp-resource-tools.d.ts +16 -0
  38. package/dist/src/tools/built-in/mcp-resource-tools.d.ts.map +1 -0
  39. package/dist/src/tools/built-in/mcp-resource-tools.js +73 -0
  40. package/dist/src/tools/built-in/mcp-resource-tools.js.map +1 -0
  41. package/dist/src/tools/built-in/plan-tools.d.ts +13 -0
  42. package/dist/src/tools/built-in/plan-tools.d.ts.map +1 -0
  43. package/dist/src/tools/built-in/plan-tools.js +42 -0
  44. package/dist/src/tools/built-in/plan-tools.js.map +1 -0
  45. package/dist/src/tools/built-in/task-tools.d.ts +22 -0
  46. package/dist/src/tools/built-in/task-tools.d.ts.map +1 -0
  47. package/dist/src/tools/built-in/task-tools.js +113 -0
  48. package/dist/src/tools/built-in/task-tools.js.map +1 -0
  49. package/dist/src/tools/built-in/todo-tool.d.ts +21 -0
  50. package/dist/src/tools/built-in/todo-tool.d.ts.map +1 -0
  51. package/dist/src/tools/built-in/todo-tool.js +52 -0
  52. package/dist/src/tools/built-in/todo-tool.js.map +1 -0
  53. package/dist/src/tools/built-in/web-search.d.ts +9 -0
  54. package/dist/src/tools/built-in/web-search.d.ts.map +1 -0
  55. package/dist/src/tools/built-in/web-search.js +89 -0
  56. package/dist/src/tools/built-in/web-search.js.map +1 -0
  57. package/package.json +1 -1
@@ -0,0 +1,73 @@
1
+ /**
2
+ * MCP resource tools — list and read resources from connected MCP servers.
3
+ *
4
+ * MCP servers can expose resources (files, database schemas, API docs, etc.)
5
+ * in addition to tools. These tools let the LLM discover and read them.
6
+ */
7
+ import { z } from 'zod';
8
+ import { defineTool } from '../registry.js';
9
+ let mcpClientRef = null;
10
+ export function setMcpClient(client) {
11
+ mcpClientRef = client;
12
+ }
13
+ export const mcpListResourcesTool = defineTool({
14
+ name: 'mcp_list_resources',
15
+ description: 'List available resources from connected MCP servers. Resources are additional context like files, database schemas, or documentation that MCP servers can provide.',
16
+ inputSchema: z.object({
17
+ server: z.string().optional().describe('Optional: filter to a specific MCP server name'),
18
+ }),
19
+ execute: async (input) => {
20
+ if (!mcpClientRef) {
21
+ return { data: 'No MCP client available', isError: true };
22
+ }
23
+ const connections = mcpClientRef.listConnections();
24
+ if (connections.length === 0) {
25
+ return { data: 'No MCP servers connected. Use /mcp to manage connections.' };
26
+ }
27
+ const filtered = input.server
28
+ ? connections.filter(c => c.name === input.server)
29
+ : connections;
30
+ if (filtered.length === 0) {
31
+ return { data: `MCP server "${input.server}" not found. Connected: ${connections.map(c => c.name).join(', ')}`, isError: true };
32
+ }
33
+ // Note: Resource listing requires the MCP server to support resources/list.
34
+ // This is a best-effort — many servers only support tools.
35
+ const lines = filtered.map(c => `${c.name} (${c.transport}) — ${c.tools} tools${c.connected ? '' : ' [disconnected]'}`);
36
+ return {
37
+ data: `Connected MCP servers:\n${lines.join('\n')}\n\nNote: Use mcp_read_resource with a specific server and resource URI to read content.`,
38
+ };
39
+ },
40
+ });
41
+ export const mcpReadResourceTool = defineTool({
42
+ name: 'mcp_read_resource',
43
+ description: 'Read a specific resource from an MCP server by URI. The resource URI format depends on the server (e.g. "file:///path", "db://schema/table").',
44
+ inputSchema: z.object({
45
+ server: z.string().describe('The MCP server name'),
46
+ uri: z.string().describe('The resource URI to read'),
47
+ }),
48
+ execute: async (input) => {
49
+ if (!mcpClientRef) {
50
+ return { data: 'No MCP client available', isError: true };
51
+ }
52
+ // Validate URI format
53
+ try {
54
+ new URL(input.uri);
55
+ }
56
+ catch {
57
+ // Allow relative URIs too — some MCP servers use simple paths
58
+ }
59
+ try {
60
+ // Use the MCP client's callTool to send a resources/read request
61
+ // This piggybacks on the existing transport infrastructure
62
+ const result = await mcpClientRef.callTool(input.server, '__resources_read__', {
63
+ uri: input.uri,
64
+ });
65
+ return result;
66
+ }
67
+ catch (err) {
68
+ const msg = err instanceof Error ? err.message : String(err);
69
+ return { data: `Failed to read resource: ${msg}`, isError: true };
70
+ }
71
+ },
72
+ });
73
+ //# sourceMappingURL=mcp-resource-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-resource-tools.js","sourceRoot":"","sources":["../../../../src/tools/built-in/mcp-resource-tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Plan mode tools — allow the LLM to self-manage planning vs execution mode.
3
+ *
4
+ * When in plan mode, the LLM should describe its approach before executing.
5
+ * These tools let the LLM switch modes programmatically.
6
+ */
7
+ export declare function isPlanMode(): boolean;
8
+ export declare function setPlanMode(active: boolean): void;
9
+ export declare const enterPlanModeTool: import("../registry.js").ToolDefinition<{
10
+ reason?: string | undefined;
11
+ }>;
12
+ export declare const exitPlanModeTool: import("../registry.js").ToolDefinition<{}>;
13
+ //# sourceMappingURL=plan-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-tools.d.ts","sourceRoot":"","sources":["../../../../src/tools/built-in/plan-tools.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,wBAAgB,UAAU,IAAI,OAAO,CAEpC;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAEjD;AAED,eAAO,MAAM,iBAAiB;;EAa5B,CAAA;AAEF,eAAO,MAAM,gBAAgB,6CAU3B,CAAA"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Plan mode tools — allow the LLM to self-manage planning vs execution mode.
3
+ *
4
+ * When in plan mode, the LLM should describe its approach before executing.
5
+ * These tools let the LLM switch modes programmatically.
6
+ */
7
+ import { z } from 'zod';
8
+ import { defineTool } from '../registry.js';
9
+ // Global plan mode state — can also be set by /plan command
10
+ let planModeActive = false;
11
+ export function isPlanMode() {
12
+ return planModeActive;
13
+ }
14
+ export function setPlanMode(active) {
15
+ planModeActive = active;
16
+ }
17
+ export const enterPlanModeTool = defineTool({
18
+ name: 'enter_plan_mode',
19
+ description: 'Switch to plan mode. In plan mode, describe your approach and reasoning before executing any tools. Use this when the task is complex and would benefit from planning first.',
20
+ inputSchema: z.object({
21
+ reason: z.string().optional().describe('Why you are entering plan mode'),
22
+ }),
23
+ execute: async (input) => {
24
+ planModeActive = true;
25
+ const reason = input.reason ? ` Reason: ${input.reason}` : '';
26
+ return {
27
+ data: `Plan mode activated.${reason}\n\nYou are now in plan mode. Describe your approach step-by-step before executing. Use exit_plan_mode when ready to execute.`,
28
+ };
29
+ },
30
+ });
31
+ export const exitPlanModeTool = defineTool({
32
+ name: 'exit_plan_mode',
33
+ description: 'Exit plan mode and return to execution mode. Use this after you have laid out your plan and are ready to start implementing.',
34
+ inputSchema: z.object({}),
35
+ execute: async () => {
36
+ planModeActive = false;
37
+ return {
38
+ data: 'Plan mode deactivated. You are now in execution mode. Proceed with implementing your plan.',
39
+ };
40
+ },
41
+ });
42
+ //# sourceMappingURL=plan-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-tools.js","sourceRoot":"","sources":["../../../../src/tools/built-in/plan-tools.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAE3C,4DAA4D;AAC5D,IAAI,cAAc,GAAG,KAAK,CAAA;AAE1B,MAAM,UAAU,UAAU;IACxB,OAAO,cAAc,CAAA;AACvB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAAe;IACzC,cAAc,GAAG,MAAM,CAAA;AACzB,CAAC;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAG,UAAU,CAAC;IAC1C,IAAI,EAAE,iBAAiB;IACvB,WAAW,EAAE,8KAA8K;IAC3L,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;QACpB,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,gCAAgC,CAAC;KACzE,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;QACvB,cAAc,GAAG,IAAI,CAAA;QACrB,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;QAC7D,OAAO;YACL,IAAI,EAAE,uBAAuB,MAAM,+HAA+H;SACnK,CAAA;IACH,CAAC;CACF,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,UAAU,CAAC;IACzC,IAAI,EAAE,gBAAgB;IACtB,WAAW,EAAE,8HAA8H;IAC3I,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;IACzB,OAAO,EAAE,KAAK,IAAI,EAAE;QAClB,cAAc,GAAG,KAAK,CAAA;QACtB,OAAO;YACL,IAAI,EAAE,4FAA4F;SACnG,CAAA;IACH,CAAC;CACF,CAAC,CAAA"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Task management tools — LLM-driven wrappers around TaskScheduler.
3
+ *
4
+ * Provides task_create, task_list, task_get, task_stop for the LLM to
5
+ * schedule and manage background tasks.
6
+ */
7
+ import type { TaskScheduler } from '../../scheduling/task-scheduler.js';
8
+ export declare function setTaskScheduler(ts: TaskScheduler): void;
9
+ export declare const taskCreateTool: import("../registry.js").ToolDefinition<{
10
+ command: string;
11
+ name: string;
12
+ intervalMs?: number | undefined;
13
+ delayMs?: number | undefined;
14
+ }>;
15
+ export declare const taskListTool: import("../registry.js").ToolDefinition<{}>;
16
+ export declare const taskGetTool: import("../registry.js").ToolDefinition<{
17
+ id: string;
18
+ }>;
19
+ export declare const taskStopTool: import("../registry.js").ToolDefinition<{
20
+ id: string;
21
+ }>;
22
+ //# sourceMappingURL=task-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-tools.d.ts","sourceRoot":"","sources":["../../../../src/tools/built-in/task-tools.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAA;AAKvE,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,aAAa,GAAG,IAAI,CAExD;AAED,eAAO,MAAM,cAAc;;;;;EA6BzB,CAAA;AAEF,eAAO,MAAM,YAAY,6CA4BvB,CAAA;AAEF,eAAO,MAAM,WAAW;;EA2BtB,CAAA;AAEF,eAAO,MAAM,YAAY;;EAkBvB,CAAA"}
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Task management tools — LLM-driven wrappers around TaskScheduler.
3
+ *
4
+ * Provides task_create, task_list, task_get, task_stop for the LLM to
5
+ * schedule and manage background tasks.
6
+ */
7
+ import { z } from 'zod';
8
+ import { defineTool } from '../registry.js';
9
+ // TaskScheduler reference is set during REPL startup
10
+ let scheduler = null;
11
+ export function setTaskScheduler(ts) {
12
+ scheduler = ts;
13
+ }
14
+ export const taskCreateTool = defineTool({
15
+ name: 'task_create',
16
+ description: 'Create a background scheduled task. Supports one-shot (delayed) and recurring (interval) tasks. The task runs a shell command.',
17
+ inputSchema: z.object({
18
+ name: z.string().describe('Human-readable name for the task'),
19
+ command: z.string().describe('Shell command to execute'),
20
+ intervalMs: z.number().optional().describe('Run every N milliseconds (recurring). Omit for one-shot.'),
21
+ delayMs: z.number().optional().describe('Delay before first/only run (default: 0 for immediate)'),
22
+ }),
23
+ execute: async (input) => {
24
+ if (!scheduler) {
25
+ return { data: 'TaskScheduler is not initialized', isError: true };
26
+ }
27
+ const { execSync } = await import('node:child_process');
28
+ const handler = async () => {
29
+ execSync(input.command, { timeout: 30000, stdio: 'pipe' });
30
+ };
31
+ let id;
32
+ if (input.intervalMs) {
33
+ id = scheduler.scheduleInterval(input.name, input.intervalMs, handler);
34
+ }
35
+ else {
36
+ id = scheduler.scheduleOnce(input.name, input.delayMs ?? 0, handler);
37
+ }
38
+ const type = input.intervalMs ? `recurring (every ${input.intervalMs}ms)` : `one-shot (delay ${input.delayMs ?? 0}ms)`;
39
+ return { data: `Task created: ${input.name} (${type})\nID: ${id}` };
40
+ },
41
+ });
42
+ export const taskListTool = defineTool({
43
+ name: 'task_list',
44
+ description: 'List all scheduled background tasks with their status, run count, and timing.',
45
+ inputSchema: z.object({}),
46
+ execute: async () => {
47
+ if (!scheduler) {
48
+ return { data: 'TaskScheduler is not initialized', isError: true };
49
+ }
50
+ const tasks = scheduler.list();
51
+ if (tasks.length === 0) {
52
+ return { data: 'No scheduled tasks.' };
53
+ }
54
+ const lines = tasks.map(t => {
55
+ const parts = [
56
+ ` ${t.name} [${t.status}]`,
57
+ ` ID: ${t.id}`,
58
+ ` Runs: ${t.runCount}`,
59
+ ];
60
+ if (t.lastRun)
61
+ parts.push(` Last: ${t.lastRun.toISOString()}`);
62
+ if (t.nextRun)
63
+ parts.push(` Next: ${t.nextRun.toISOString()}`);
64
+ if (t.error)
65
+ parts.push(` Error: ${t.error}`);
66
+ return parts.join('\n');
67
+ });
68
+ return { data: `Scheduled tasks (${tasks.length} total, ${scheduler.activeCount} active):\n\n${lines.join('\n\n')}` };
69
+ },
70
+ });
71
+ export const taskGetTool = defineTool({
72
+ name: 'task_get',
73
+ description: 'Get details of a specific scheduled task by ID.',
74
+ inputSchema: z.object({
75
+ id: z.string().describe('The task ID returned by task_create'),
76
+ }),
77
+ execute: async (input) => {
78
+ if (!scheduler) {
79
+ return { data: 'TaskScheduler is not initialized', isError: true };
80
+ }
81
+ const task = scheduler.get(input.id);
82
+ if (!task) {
83
+ return { data: `Task not found: ${input.id}`, isError: true };
84
+ }
85
+ const info = [
86
+ `Name: ${task.name}`,
87
+ `Status: ${task.status}`,
88
+ `Runs: ${task.runCount}`,
89
+ task.lastRun ? `Last run: ${task.lastRun.toISOString()}` : null,
90
+ task.nextRun ? `Next run: ${task.nextRun.toISOString()}` : null,
91
+ task.error ? `Error: ${task.error}` : null,
92
+ ].filter(Boolean).join('\n');
93
+ return { data: info };
94
+ },
95
+ });
96
+ export const taskStopTool = defineTool({
97
+ name: 'task_stop',
98
+ description: 'Stop/cancel a scheduled task by ID.',
99
+ inputSchema: z.object({
100
+ id: z.string().describe('The task ID to cancel'),
101
+ }),
102
+ execute: async (input) => {
103
+ if (!scheduler) {
104
+ return { data: 'TaskScheduler is not initialized', isError: true };
105
+ }
106
+ const success = scheduler.cancel(input.id);
107
+ if (!success) {
108
+ return { data: `Task not found: ${input.id}`, isError: true };
109
+ }
110
+ return { data: `Task ${input.id} cancelled.` };
111
+ },
112
+ });
113
+ //# sourceMappingURL=task-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-tools.js","sourceRoot":"","sources":["../../../../src/tools/built-in/task-tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * todo_write — session-scoped task checklist for tracking progress.
3
+ *
4
+ * The LLM can create, update, and manage a checklist of tasks
5
+ * within the current session, similar to Claude Code's TodoWrite tool.
6
+ */
7
+ interface TodoItem {
8
+ id: number;
9
+ title: string;
10
+ status: 'not-started' | 'in-progress' | 'completed';
11
+ }
12
+ export declare function getSessionTodos(): readonly TodoItem[];
13
+ export declare const todoWriteTool: import("../registry.js").ToolDefinition<{
14
+ todos: {
15
+ status: "completed" | "not-started" | "in-progress";
16
+ title: string;
17
+ id?: number | undefined;
18
+ }[];
19
+ }>;
20
+ export {};
21
+ //# sourceMappingURL=todo-tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"todo-tool.d.ts","sourceRoot":"","sources":["../../../../src/tools/built-in/todo-tool.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,UAAU,QAAQ;IAChB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,aAAa,GAAG,aAAa,GAAG,WAAW,CAAA;CACpD;AAMD,wBAAgB,eAAe,IAAI,SAAS,QAAQ,EAAE,CAErD;AAED,eAAO,MAAM,aAAa;;;;;;EAuCxB,CAAA"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * todo_write — session-scoped task checklist for tracking progress.
3
+ *
4
+ * The LLM can create, update, and manage a checklist of tasks
5
+ * within the current session, similar to Claude Code's TodoWrite tool.
6
+ */
7
+ import { z } from 'zod';
8
+ import { defineTool } from '../registry.js';
9
+ // Session-scoped todo list (shared across all tool invocations)
10
+ const sessionTodos = [];
11
+ let nextId = 1;
12
+ export function getSessionTodos() {
13
+ return sessionTodos;
14
+ }
15
+ export const todoWriteTool = defineTool({
16
+ name: 'todo_write',
17
+ description: 'Manage a session-scoped task checklist. Use to track progress on multi-step tasks. Provide the complete array of all todo items (both existing and new) each time.',
18
+ inputSchema: z.object({
19
+ todos: z.array(z.object({
20
+ id: z.number().optional().describe('Existing todo ID (omit for new items)'),
21
+ title: z.string().describe('Short description of the task'),
22
+ status: z.enum(['not-started', 'in-progress', 'completed']).describe('Current status'),
23
+ })).describe('Complete list of all todo items'),
24
+ }),
25
+ execute: async (input) => {
26
+ // Replace the entire todo list with the provided items
27
+ sessionTodos.length = 0;
28
+ for (const item of input.todos) {
29
+ sessionTodos.push({
30
+ id: item.id ?? nextId++,
31
+ title: item.title,
32
+ status: item.status,
33
+ });
34
+ // Keep nextId ahead of any provided IDs
35
+ if (item.id && item.id >= nextId) {
36
+ nextId = item.id + 1;
37
+ }
38
+ }
39
+ const total = sessionTodos.length;
40
+ const completed = sessionTodos.filter(t => t.status === 'completed').length;
41
+ const inProgress = sessionTodos.filter(t => t.status === 'in-progress').length;
42
+ const notStarted = sessionTodos.filter(t => t.status === 'not-started').length;
43
+ const lines = sessionTodos.map(t => {
44
+ const icon = t.status === 'completed' ? '✓' : t.status === 'in-progress' ? '▶' : '○';
45
+ return ` ${icon} [${t.id}] ${t.title} (${t.status})`;
46
+ });
47
+ return {
48
+ data: `Todo list updated (${completed}/${total} done, ${inProgress} in-progress, ${notStarted} not-started):\n${lines.join('\n')}`,
49
+ };
50
+ },
51
+ });
52
+ //# sourceMappingURL=todo-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"todo-tool.js","sourceRoot":"","sources":["../../../../src/tools/built-in/todo-tool.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAQ3C,gEAAgE;AAChE,MAAM,YAAY,GAAe,EAAE,CAAA;AACnC,IAAI,MAAM,GAAG,CAAC,CAAA;AAEd,MAAM,UAAU,eAAe;IAC7B,OAAO,YAAY,CAAA;AACrB,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,UAAU,CAAC;IACtC,IAAI,EAAE,YAAY;IAClB,WAAW,EAAE,oKAAoK;IACjL,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;QACpB,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC;YACtB,EAAE,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uCAAuC,CAAC;YAC3E,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC;YAC3D,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,aAAa,EAAE,aAAa,EAAE,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,gBAAgB,CAAC;SACvF,CAAC,CAAC,CAAC,QAAQ,CAAC,iCAAiC,CAAC;KAChD,CAAC;IACF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;QACvB,uDAAuD;QACvD,YAAY,CAAC,MAAM,GAAG,CAAC,CAAA;QACvB,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAC/B,YAAY,CAAC,IAAI,CAAC;gBAChB,EAAE,EAAE,IAAI,CAAC,EAAE,IAAI,MAAM,EAAE;gBACvB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,MAAM,EAAE,IAAI,CAAC,MAAM;aACpB,CAAC,CAAA;YACF,wCAAwC;YACxC,IAAI,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,EAAE,IAAI,MAAM,EAAE,CAAC;gBACjC,MAAM,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAA;YACtB,CAAC;QACH,CAAC;QAED,MAAM,KAAK,GAAG,YAAY,CAAC,MAAM,CAAA;QACjC,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,MAAM,CAAA;QAC3E,MAAM,UAAU,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,aAAa,CAAC,CAAC,MAAM,CAAA;QAC9E,MAAM,UAAU,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,aAAa,CAAC,CAAC,MAAM,CAAA;QAE9E,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;YACjC,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAA;YACpF,OAAO,KAAK,IAAI,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,MAAM,GAAG,CAAA;QACvD,CAAC,CAAC,CAAA;QAEF,OAAO;YACL,IAAI,EAAE,sBAAsB,SAAS,IAAI,KAAK,UAAU,UAAU,iBAAiB,UAAU,mBAAmB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;SACnI,CAAA;IACH,CAAC;CACF,CAAC,CAAA"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * web_search — search the web using DuckDuckGo HTML scraping (no API key required).
3
+ * Falls back to Brave Search API if BRAVE_SEARCH_API_KEY is set.
4
+ */
5
+ export declare const webSearchTool: import("../registry.js").ToolDefinition<{
6
+ query: string;
7
+ maxResults?: number | undefined;
8
+ }>;
9
+ //# sourceMappingURL=web-search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-search.d.ts","sourceRoot":"","sources":["../../../../src/tools/built-in/web-search.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA4EH,eAAO,MAAM,aAAa;;;EA8BxB,CAAA"}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * web_search — search the web using DuckDuckGo HTML scraping (no API key required).
3
+ * Falls back to Brave Search API if BRAVE_SEARCH_API_KEY is set.
4
+ */
5
+ import { z } from 'zod';
6
+ import { defineTool } from '../registry.js';
7
+ async function searchDuckDuckGo(query, maxResults) {
8
+ const encoded = encodeURIComponent(query);
9
+ const url = `https://html.duckduckgo.com/html/?q=${encoded}`;
10
+ const response = await fetch(url, {
11
+ headers: {
12
+ 'User-Agent': 'Mozilla/5.0 (compatible; cmdr-agent/1.0)',
13
+ },
14
+ signal: AbortSignal.timeout(15000),
15
+ });
16
+ if (!response.ok) {
17
+ throw new Error(`DuckDuckGo returned ${response.status}`);
18
+ }
19
+ const html = await response.text();
20
+ const results = [];
21
+ // Parse result entries from DuckDuckGo HTML
22
+ const resultPattern = /<a[^>]+class="result__a"[^>]*href="([^"]*)"[^>]*>([\s\S]*?)<\/a>[\s\S]*?<a[^>]+class="result__snippet"[^>]*>([\s\S]*?)<\/a>/g;
23
+ let match;
24
+ while ((match = resultPattern.exec(html)) !== null && results.length < maxResults) {
25
+ const rawUrl = match[1];
26
+ const title = match[2].replace(/<[^>]*>/g, '').trim();
27
+ const snippet = match[3].replace(/<[^>]*>/g, '').trim();
28
+ // DuckDuckGo wraps URLs in a redirect — extract the actual URL
29
+ let finalUrl = rawUrl;
30
+ try {
31
+ const parsed = new URL(rawUrl, 'https://duckduckgo.com');
32
+ const uddg = parsed.searchParams.get('uddg');
33
+ if (uddg)
34
+ finalUrl = decodeURIComponent(uddg);
35
+ }
36
+ catch { /* use raw */ }
37
+ if (title && finalUrl) {
38
+ results.push({ title, url: finalUrl, snippet });
39
+ }
40
+ }
41
+ return results;
42
+ }
43
+ async function searchBrave(query, maxResults, apiKey) {
44
+ const encoded = encodeURIComponent(query);
45
+ const response = await fetch(`https://api.search.brave.com/res/v1/web/search?q=${encoded}&count=${maxResults}`, {
46
+ headers: {
47
+ 'Accept': 'application/json',
48
+ 'Accept-Encoding': 'gzip',
49
+ 'X-Subscription-Token': apiKey,
50
+ },
51
+ signal: AbortSignal.timeout(15000),
52
+ });
53
+ if (!response.ok) {
54
+ throw new Error(`Brave Search returned ${response.status}`);
55
+ }
56
+ const data = await response.json();
57
+ return (data.web?.results ?? []).slice(0, maxResults).map(r => ({
58
+ title: r.title,
59
+ url: r.url,
60
+ snippet: r.description,
61
+ }));
62
+ }
63
+ export const webSearchTool = defineTool({
64
+ name: 'web_search',
65
+ description: 'Search the web for information. Returns titles, URLs, and snippets of top results. Use this when you need current information not in your training data.',
66
+ inputSchema: z.object({
67
+ query: z.string().describe('The search query'),
68
+ maxResults: z.number().min(1).max(20).default(5).describe('Maximum number of results to return (default: 5)'),
69
+ }),
70
+ execute: async (input) => {
71
+ const braveKey = process.env.BRAVE_SEARCH_API_KEY;
72
+ const maxResults = input.maxResults ?? 5;
73
+ try {
74
+ const results = braveKey
75
+ ? await searchBrave(input.query, maxResults, braveKey)
76
+ : await searchDuckDuckGo(input.query, maxResults);
77
+ if (results.length === 0) {
78
+ return { data: `No results found for: "${input.query}"` };
79
+ }
80
+ const formatted = results.map((r, i) => `${i + 1}. ${r.title}\n ${r.url}\n ${r.snippet}`).join('\n\n');
81
+ return { data: `Search results for "${input.query}":\n\n${formatted}` };
82
+ }
83
+ catch (err) {
84
+ const msg = err instanceof Error ? err.message : String(err);
85
+ return { data: `Search failed: ${msg}`, isError: true };
86
+ }
87
+ },
88
+ });
89
+ //# sourceMappingURL=web-search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web-search.js","sourceRoot":"","sources":["../../../../src/tools/built-in/web-search.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cmdr-agent",
3
- "version": "2.2.0",
3
+ "version": "2.3.0",
4
4
  "description": "Open-source multi-agent coding tool for your terminal. Powered by Ollama.",
5
5
  "type": "module",
6
6
  "bin": {