agentool 1.0.0 → 1.1.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 (80) hide show
  1. package/README.md +132 -21
  2. package/dist/chunk-44AFQ2B7.js +30 -0
  3. package/dist/{chunk-Y7KOKDFP.js → chunk-4HIATLKI.js} +1 -4
  4. package/dist/chunk-4HXAKPQH.cjs +36 -0
  5. package/dist/chunk-56CL4JCW.cjs +53 -0
  6. package/dist/{chunk-U2YMJM25.cjs → chunk-5O55DKOB.cjs} +1 -4
  7. package/dist/{chunk-IMZQ7ELK.cjs → chunk-5TDZF4IM.cjs} +10 -9
  8. package/dist/{chunk-JCTBB7H2.cjs → chunk-6DJSWTWQ.cjs} +1 -1
  9. package/dist/{chunk-ZHCMEQJJ.js → chunk-ACGW44YT.js} +3 -3
  10. package/dist/chunk-E6NBEYZD.js +51 -0
  11. package/dist/{chunk-7QL4BQCH.js → chunk-ECYT46FP.js} +1 -1
  12. package/dist/{chunk-QEJV2KZ4.cjs → chunk-HNP7JDQC.cjs} +14 -14
  13. package/dist/chunk-HNUL2CID.cjs +34 -0
  14. package/dist/chunk-IEX4NOVN.cjs +48 -0
  15. package/dist/chunk-IRRNYFI5.js +48 -0
  16. package/dist/chunk-L5JH4I77.cjs +51 -0
  17. package/dist/chunk-LK6SQH2G.cjs +30 -0
  18. package/dist/chunk-LTE5NG4D.js +53 -0
  19. package/dist/{chunk-TBVHHF3H.cjs → chunk-OM2UFTGS.cjs} +3 -3
  20. package/dist/{chunk-S6QEY7UY.js → chunk-P6Z5XFDS.js} +2 -2
  21. package/dist/chunk-S7IVHOA6.js +75 -0
  22. package/dist/chunk-TMW3XKKJ.js +34 -0
  23. package/dist/{chunk-XKG2A3EW.js → chunk-UDIG7332.js} +14 -14
  24. package/dist/chunk-VXZ4RKJI.js +36 -0
  25. package/dist/{chunk-6MDPYALY.js → chunk-XAQGZ374.js} +10 -9
  26. package/dist/{chunk-MXFW3XY6.cjs → chunk-ZBLQV6UO.cjs} +2 -2
  27. package/dist/chunk-ZFQZWXOI.cjs +75 -0
  28. package/dist/edit/index.cjs +2 -2
  29. package/dist/edit/index.d.cts +2 -2
  30. package/dist/edit/index.d.ts +2 -2
  31. package/dist/edit/index.js +1 -1
  32. package/dist/grep/index.cjs +2 -2
  33. package/dist/grep/index.js +1 -1
  34. package/dist/index.cjs +42 -11
  35. package/dist/index.d.cts +6 -1
  36. package/dist/index.d.ts +6 -1
  37. package/dist/index.js +53 -22
  38. package/dist/lsp/index.cjs +2 -2
  39. package/dist/lsp/index.d.cts +6 -9
  40. package/dist/lsp/index.d.ts +6 -9
  41. package/dist/lsp/index.js +1 -1
  42. package/dist/read/index.cjs +2 -2
  43. package/dist/read/index.js +1 -1
  44. package/dist/task-create/index.cjs +9 -0
  45. package/dist/task-create/index.d.cts +19 -0
  46. package/dist/task-create/index.d.ts +19 -0
  47. package/dist/task-create/index.js +9 -0
  48. package/dist/task-get/index.cjs +9 -0
  49. package/dist/task-get/index.d.cts +15 -0
  50. package/dist/task-get/index.d.ts +15 -0
  51. package/dist/task-get/index.js +9 -0
  52. package/dist/task-list/index.cjs +9 -0
  53. package/dist/task-list/index.d.cts +11 -0
  54. package/dist/task-list/index.d.ts +11 -0
  55. package/dist/task-list/index.js +9 -0
  56. package/dist/task-update/index.cjs +9 -0
  57. package/dist/task-update/index.d.cts +31 -0
  58. package/dist/task-update/index.d.ts +31 -0
  59. package/dist/task-update/index.js +9 -0
  60. package/dist/tool-search/index.cjs +8 -0
  61. package/dist/tool-search/index.d.cts +18 -0
  62. package/dist/tool-search/index.d.ts +18 -0
  63. package/dist/tool-search/index.js +8 -0
  64. package/dist/web-fetch/index.cjs +2 -2
  65. package/dist/web-fetch/index.d.cts +0 -2
  66. package/dist/web-fetch/index.d.ts +0 -2
  67. package/dist/web-fetch/index.js +1 -1
  68. package/dist/web-search/index.cjs +8 -0
  69. package/dist/web-search/index.d.cts +21 -0
  70. package/dist/web-search/index.d.ts +21 -0
  71. package/dist/web-search/index.js +8 -0
  72. package/dist/write/index.cjs +2 -2
  73. package/dist/write/index.js +1 -1
  74. package/package.json +31 -6
  75. package/dist/chunk-FAEGCFTO.js +0 -136
  76. package/dist/chunk-XLD2Y3SS.cjs +0 -136
  77. package/dist/task/index.cjs +0 -8
  78. package/dist/task/index.d.cts +0 -67
  79. package/dist/task/index.d.ts +0 -67
  80. package/dist/task/index.js +0 -8
@@ -0,0 +1,48 @@
1
+ // src/tool-search/index.ts
2
+ import { tool } from "ai";
3
+ import { z } from "zod";
4
+ function createToolSearch(config = {}) {
5
+ return tool({
6
+ description: "Search for available tools by name or keyword. Returns matching tool names and descriptions.",
7
+ inputSchema: z.object({
8
+ query: z.string().describe("Query to find tools by name or keyword"),
9
+ max_results: z.number().optional().default(5).describe("Max results to return")
10
+ }),
11
+ execute: async ({ query, max_results }) => {
12
+ try {
13
+ const registry = config.tools ?? {};
14
+ const entries = Object.entries(registry);
15
+ if (entries.length === 0) {
16
+ return "No tools registered. Provide a tools registry via createToolSearch({ tools: { ... } })";
17
+ }
18
+ const lower = query.toLowerCase();
19
+ const scored = entries.map(([name, { description }]) => {
20
+ let score = 0;
21
+ const nameLower = name.toLowerCase();
22
+ const descLower = description.toLowerCase();
23
+ if (nameLower === lower) score += 10;
24
+ else if (nameLower.includes(lower)) score += 5;
25
+ if (descLower.includes(lower)) score += 3;
26
+ for (const word of lower.split(/\s+/)) {
27
+ if (nameLower.includes(word)) score += 2;
28
+ if (descLower.includes(word)) score += 1;
29
+ }
30
+ return { name, description, score };
31
+ }).filter((e) => e.score > 0).sort((a, b) => b.score - a.score).slice(0, max_results);
32
+ if (scored.length === 0) {
33
+ return `No tools matched query "${query}".`;
34
+ }
35
+ return scored.map((e) => `${e.name}: ${e.description}`).join("\n");
36
+ } catch (error) {
37
+ const msg = error instanceof Error ? error.message : String(error);
38
+ return `Error [tool-search]: ${msg}`;
39
+ }
40
+ }
41
+ });
42
+ }
43
+ var toolSearch = createToolSearch();
44
+
45
+ export {
46
+ createToolSearch,
47
+ toolSearch
48
+ };
@@ -0,0 +1,51 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/shared/task-store.ts
2
+ var _promises = require('fs/promises');
3
+ var _path = require('path');
4
+ var _crypto = require('crypto');
5
+ function generateId() {
6
+ return _crypto.randomBytes.call(void 0, 4).toString("hex");
7
+ }
8
+ async function loadTasks(filePath) {
9
+ try {
10
+ const data = await _promises.readFile.call(void 0, filePath, "utf-8");
11
+ return JSON.parse(data);
12
+ } catch (e) {
13
+ return [];
14
+ }
15
+ }
16
+ async function saveTasks(filePath, tasks) {
17
+ await _promises.mkdir.call(void 0, _path.dirname.call(void 0, filePath), { recursive: true });
18
+ await _promises.writeFile.call(void 0, filePath, JSON.stringify(tasks, null, 2), "utf-8");
19
+ }
20
+ function formatTask(t) {
21
+ const lines = [
22
+ `ID: ${t.id}`,
23
+ `Subject: ${t.subject}`,
24
+ `Description: ${t.description}`,
25
+ `Status: ${t.status}`
26
+ ];
27
+ if (t.owner) lines.push(`Owner: ${t.owner}`);
28
+ if (t.activeForm) lines.push(`Active: ${t.activeForm}`);
29
+ if (t.blocks.length > 0) lines.push(`Blocks: ${t.blocks.join(", ")}`);
30
+ if (t.blockedBy.length > 0) lines.push(`Blocked by: ${t.blockedBy.join(", ")}`);
31
+ if (t.metadata && Object.keys(t.metadata).length > 0) {
32
+ lines.push(`Metadata: ${JSON.stringify(t.metadata)}`);
33
+ }
34
+ lines.push(`Created: ${t.createdAt}`);
35
+ lines.push(`Updated: ${t.updatedAt}`);
36
+ return lines.join("\n");
37
+ }
38
+ function formatTaskSummary(t) {
39
+ const parts = [`#${t.id} [${t.status}] ${t.subject}`];
40
+ if (t.owner) parts.push(`(owner: ${t.owner})`);
41
+ if (t.blockedBy.length > 0) parts.push(`[blocked by ${t.blockedBy.join(", ")}]`);
42
+ return parts.join(" ");
43
+ }
44
+
45
+
46
+
47
+
48
+
49
+
50
+
51
+ exports.generateId = generateId; exports.loadTasks = loadTasks; exports.saveTasks = saveTasks; exports.formatTask = formatTask; exports.formatTaskSummary = formatTaskSummary;
@@ -0,0 +1,30 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/web-search/index.ts
2
+ var _ai = require('ai');
3
+ var _zod = require('zod');
4
+ function createWebSearch(config = {}) {
5
+ return _ai.tool.call(void 0, {
6
+ description: "Search the web for information using a search query. Results can be filtered by allowed or blocked domains.",
7
+ inputSchema: _zod.z.object({
8
+ query: _zod.z.string().min(2).describe("The search query to use"),
9
+ allowed_domains: _zod.z.array(_zod.z.string()).optional().describe("Only include search results from these domains"),
10
+ blocked_domains: _zod.z.array(_zod.z.string()).optional().describe("Never include search results from these domains")
11
+ }),
12
+ execute: async ({ query, allowed_domains, blocked_domains }) => {
13
+ try {
14
+ if (!config.onSearch) {
15
+ return "Error [web-search]: No search callback configured. Provide onSearch via createWebSearch({ onSearch: async (query, opts) => ... })";
16
+ }
17
+ return await config.onSearch(query, { allowed_domains, blocked_domains });
18
+ } catch (error) {
19
+ const msg = error instanceof Error ? error.message : String(error);
20
+ return `Error [web-search]: ${msg}`;
21
+ }
22
+ }
23
+ });
24
+ }
25
+ var webSearch = createWebSearch();
26
+
27
+
28
+
29
+
30
+ exports.createWebSearch = createWebSearch; exports.webSearch = webSearch;
@@ -0,0 +1,53 @@
1
+ import {
2
+ formatTask,
3
+ generateId,
4
+ loadTasks,
5
+ saveTasks
6
+ } from "./chunk-E6NBEYZD.js";
7
+
8
+ // src/task-create/index.ts
9
+ import { tool } from "ai";
10
+ import { z } from "zod";
11
+ import { join } from "path";
12
+ function createTaskCreate(config = {}) {
13
+ const cwd = config.cwd ?? process.cwd();
14
+ const tasksFile = config.tasksFile ?? join(cwd, ".agentool", "tasks.json");
15
+ return tool({
16
+ description: 'Create a new task to track work. Each task gets a unique ID, starts with "pending" status, and can include optional metadata.',
17
+ inputSchema: z.object({
18
+ subject: z.string().describe("A brief title for the task"),
19
+ description: z.string().describe("What needs to be done"),
20
+ metadata: z.record(z.string(), z.unknown()).optional().describe("Arbitrary metadata to attach to the task")
21
+ }),
22
+ execute: async ({ subject, description, metadata }) => {
23
+ try {
24
+ const tasks = await loadTasks(tasksFile);
25
+ const now = (/* @__PURE__ */ new Date()).toISOString();
26
+ const entry = {
27
+ id: generateId(),
28
+ subject,
29
+ description,
30
+ status: "pending",
31
+ blocks: [],
32
+ blockedBy: [],
33
+ metadata,
34
+ createdAt: now,
35
+ updatedAt: now
36
+ };
37
+ tasks.push(entry);
38
+ await saveTasks(tasksFile, tasks);
39
+ return `Created task ${entry.id}.
40
+ ${formatTask(entry)}`;
41
+ } catch (error) {
42
+ const msg = error instanceof Error ? error.message : String(error);
43
+ return `Error [task-create]: ${msg}`;
44
+ }
45
+ }
46
+ });
47
+ }
48
+ var taskCreate = createTaskCreate();
49
+
50
+ export {
51
+ createTaskCreate,
52
+ taskCreate
53
+ };
@@ -15,9 +15,9 @@ function createRead(config = {}) {
15
15
  return _ai.tool.call(void 0, {
16
16
  description: 'Read a file from the local filesystem and return its contents with line numbers. Supports absolute paths, relative paths (resolved against the working directory), and tilde (~) home directory expansion. Returns numbered lines in "lineNumber\\tcontent" format. Use offset and limit to read specific ranges of large files.',
17
17
  inputSchema: _zod.z.object({
18
- file_path: _zod.z.string().describe("The path to the file to read (absolute, relative, or ~/...)"),
19
- offset: _zod.z.number().optional().describe("0-indexed line number to start reading from (default: 0)"),
20
- limit: _zod.z.number().optional().describe("Maximum number of lines to return (default: 2000)")
18
+ file_path: _zod.z.string().describe("The absolute path to the file to read"),
19
+ offset: _zod.z.number().int().nonnegative().optional().describe("The line number to start reading from (default: 0)"),
20
+ limit: _zod.z.number().int().positive().optional().describe("The number of lines to read (default: 2000)")
21
21
  }),
22
22
  execute: async ({ file_path, offset, limit }) => {
23
23
  try {
@@ -15,10 +15,10 @@ function createEdit(config = {}) {
15
15
  return tool({
16
16
  description: "Perform an exact string replacement in a file. Locates old_string in the file and replaces it with new_string. Supports curly-quote fallback matching. When replace_all is false (default), old_string must appear exactly once.",
17
17
  inputSchema: z.object({
18
- file_path: z.string().describe("Path to the file to edit"),
18
+ file_path: z.string().describe("The absolute path to the file to modify"),
19
19
  old_string: z.string().describe("The exact string to find and replace"),
20
20
  new_string: z.string().describe("The replacement string"),
21
- replace_all: z.boolean().optional().default(false).describe("Replace all occurrences (default: false)")
21
+ replace_all: z.boolean().default(false).optional().describe("Replace all occurrences (default: false)")
22
22
  }),
23
23
  execute: async ({ file_path, old_string, new_string, replace_all }) => {
24
24
  try {
@@ -0,0 +1,75 @@
1
+ import {
2
+ formatTask,
3
+ loadTasks,
4
+ saveTasks
5
+ } from "./chunk-E6NBEYZD.js";
6
+
7
+ // src/task-update/index.ts
8
+ import { tool } from "ai";
9
+ import { z } from "zod";
10
+ import { join } from "path";
11
+ function createTaskUpdate(config = {}) {
12
+ const cwd = config.cwd ?? process.cwd();
13
+ const tasksFile = config.tasksFile ?? join(cwd, ".agentool", "tasks.json");
14
+ return tool({
15
+ description: "Update a task by its ID. Can change status, subject, description, owner, metadata, and dependency relationships.",
16
+ inputSchema: z.object({
17
+ taskId: z.string().describe("The ID of the task to update"),
18
+ subject: z.string().optional().describe("New subject for the task"),
19
+ description: z.string().optional().describe("New description"),
20
+ status: z.enum(["pending", "in_progress", "completed", "deleted"]).optional().describe("New status for the task"),
21
+ owner: z.string().optional().describe("New owner for the task"),
22
+ activeForm: z.string().optional().describe("Present continuous form shown in spinner when in_progress"),
23
+ addBlocks: z.array(z.string()).optional().describe("Task IDs that this task blocks"),
24
+ addBlockedBy: z.array(z.string()).optional().describe("Task IDs that block this task"),
25
+ metadata: z.record(z.string(), z.unknown()).optional().describe("Metadata keys to merge. Set key to null to delete.")
26
+ }),
27
+ execute: async (input) => {
28
+ try {
29
+ const tasks = await loadTasks(tasksFile);
30
+ const idx = tasks.findIndex((t) => t.id === input.taskId);
31
+ if (idx === -1) return `Error [task-update]: Task "${input.taskId}" not found.`;
32
+ const entry = tasks[idx];
33
+ if (input.subject !== void 0) entry.subject = input.subject;
34
+ if (input.description !== void 0) entry.description = input.description;
35
+ if (input.status !== void 0) entry.status = input.status;
36
+ if (input.owner !== void 0) entry.owner = input.owner;
37
+ if (input.activeForm !== void 0) entry.activeForm = input.activeForm;
38
+ if (input.addBlocks) {
39
+ for (const id of input.addBlocks) {
40
+ if (!entry.blocks.includes(id)) entry.blocks.push(id);
41
+ }
42
+ }
43
+ if (input.addBlockedBy) {
44
+ for (const id of input.addBlockedBy) {
45
+ if (!entry.blockedBy.includes(id)) entry.blockedBy.push(id);
46
+ }
47
+ }
48
+ if (input.metadata) {
49
+ if (!entry.metadata) entry.metadata = {};
50
+ for (const [key, value] of Object.entries(input.metadata)) {
51
+ if (value === null) {
52
+ delete entry.metadata[key];
53
+ } else {
54
+ entry.metadata[key] = value;
55
+ }
56
+ }
57
+ }
58
+ entry.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
59
+ tasks[idx] = entry;
60
+ await saveTasks(tasksFile, tasks);
61
+ return `Updated task ${input.taskId}.
62
+ ${formatTask(entry)}`;
63
+ } catch (error) {
64
+ const msg = error instanceof Error ? error.message : String(error);
65
+ return `Error [task-update]: ${msg}`;
66
+ }
67
+ }
68
+ });
69
+ }
70
+ var taskUpdate = createTaskUpdate();
71
+
72
+ export {
73
+ createTaskUpdate,
74
+ taskUpdate
75
+ };
@@ -0,0 +1,34 @@
1
+ import {
2
+ formatTaskSummary,
3
+ loadTasks
4
+ } from "./chunk-E6NBEYZD.js";
5
+
6
+ // src/task-list/index.ts
7
+ import { tool } from "ai";
8
+ import { z } from "zod";
9
+ import { join } from "path";
10
+ function createTaskList(config = {}) {
11
+ const cwd = config.cwd ?? process.cwd();
12
+ const tasksFile = config.tasksFile ?? join(cwd, ".agentool", "tasks.json");
13
+ return tool({
14
+ description: "List all tasks with their status, owner, and dependencies.",
15
+ inputSchema: z.object({}),
16
+ execute: async () => {
17
+ try {
18
+ const tasks = await loadTasks(tasksFile);
19
+ const visible = tasks.filter((t) => t.status !== "deleted");
20
+ if (visible.length === 0) return "No tasks found.";
21
+ return visible.map(formatTaskSummary).join("\n");
22
+ } catch (error) {
23
+ const msg = error instanceof Error ? error.message : String(error);
24
+ return `Error [task-list]: ${msg}`;
25
+ }
26
+ }
27
+ });
28
+ }
29
+ var taskList = createTaskList();
30
+
31
+ export {
32
+ createTaskList,
33
+ taskList
34
+ };
@@ -50,20 +50,20 @@ function createGrep(config = {}) {
50
50
  return tool({
51
51
  description: 'Search file contents using ripgrep. Supports regex patterns, context lines, and three output modes: "content" (matching lines), "files_with_matches" (file paths), and "count" (match counts).',
52
52
  inputSchema: z.object({
53
- pattern: z.string().describe("Regex pattern to search for"),
54
- path: z.string().optional().describe("File or directory to search in"),
55
- glob: z.string().optional().describe('Glob pattern to filter files (e.g. "*.js")'),
56
- output_mode: z.enum(["content", "files_with_matches", "count"]).optional().describe('Output mode. Defaults to "files_with_matches".'),
57
- "-B": z.number().optional().describe("Lines of context before each match"),
58
- "-A": z.number().optional().describe("Lines of context after each match"),
59
- "-C": z.number().optional().describe("Lines of context around each match"),
60
- context: z.number().optional().describe("Context lines (alias for -C)"),
61
- "-n": z.boolean().optional().describe("Show line numbers (content mode, default true)"),
62
- "-i": z.boolean().optional().describe("Case insensitive search"),
63
- type: z.string().optional().describe('File type filter (e.g. "js", "py")'),
64
- head_limit: z.number().optional().describe("Max entries. Default 250, 0 = unlimited."),
65
- offset: z.number().optional().describe("Skip first N entries. Default 0."),
66
- multiline: z.boolean().optional().describe("Enable multiline matching")
53
+ pattern: z.string().describe("The regular expression pattern to search for in file contents"),
54
+ path: z.string().optional().describe("File or directory to search in (rg PATH). Defaults to current working directory."),
55
+ glob: z.string().optional().describe('Glob pattern to filter files (e.g. "*.js", "*.{ts,tsx}") - maps to rg --glob'),
56
+ output_mode: z.enum(["content", "files_with_matches", "count"]).optional().describe('Output mode: "content" shows matching lines (supports -A/-B/-C context, -n line numbers, head_limit), "files_with_matches" shows file paths (supports head_limit), "count" shows match counts (supports head_limit). Defaults to "files_with_matches".'),
57
+ "-B": z.number().optional().describe('Number of lines to show before each match (rg -B). Requires output_mode: "content", ignored otherwise.'),
58
+ "-A": z.number().optional().describe('Number of lines to show after each match (rg -A). Requires output_mode: "content", ignored otherwise.'),
59
+ "-C": z.number().optional().describe("Alias for context."),
60
+ context: z.number().optional().describe('Number of lines to show before and after each match (rg -C). Requires output_mode: "content", ignored otherwise.'),
61
+ "-n": z.boolean().optional().describe('Show line numbers in output (rg -n). Requires output_mode: "content", ignored otherwise. Defaults to true.'),
62
+ "-i": z.boolean().optional().describe("Case insensitive search (rg -i)"),
63
+ type: z.string().optional().describe("File type to search (rg --type). Common types: js, py, rust, go, java, etc. More efficient than include for standard file types."),
64
+ head_limit: z.number().optional().describe('Limit output to first N lines/entries, equivalent to "| head -N". Works across all output modes: content (limits output lines), files_with_matches (limits file paths), count (limits count entries). Defaults to 250 when unspecified. Pass 0 for unlimited (use sparingly \u2014 large result sets waste context).'),
65
+ offset: z.number().optional().describe('Skip first N lines/entries before applying head_limit, equivalent to "| tail -n +N | head -N". Works across all output modes. Defaults to 0.'),
66
+ multiline: z.boolean().optional().describe("Enable multiline mode where . matches newlines and patterns can span lines (rg -U --multiline-dotall). Default: false.")
67
67
  }),
68
68
  execute: async (input) => {
69
69
  try {
@@ -0,0 +1,36 @@
1
+ import {
2
+ formatTask,
3
+ loadTasks
4
+ } from "./chunk-E6NBEYZD.js";
5
+
6
+ // src/task-get/index.ts
7
+ import { tool } from "ai";
8
+ import { z } from "zod";
9
+ import { join } from "path";
10
+ function createTaskGet(config = {}) {
11
+ const cwd = config.cwd ?? process.cwd();
12
+ const tasksFile = config.tasksFile ?? join(cwd, ".agentool", "tasks.json");
13
+ return tool({
14
+ description: "Retrieve a task by its ID to see full details.",
15
+ inputSchema: z.object({
16
+ taskId: z.string().describe("The ID of the task to retrieve")
17
+ }),
18
+ execute: async ({ taskId }) => {
19
+ try {
20
+ const tasks = await loadTasks(tasksFile);
21
+ const found = tasks.find((t) => t.id === taskId);
22
+ if (!found) return `Error [task-get]: Task "${taskId}" not found.`;
23
+ return formatTask(found);
24
+ } catch (error) {
25
+ const msg = error instanceof Error ? error.message : String(error);
26
+ return `Error [task-get]: ${msg}`;
27
+ }
28
+ }
29
+ });
30
+ }
31
+ var taskGet = createTaskGet();
32
+
33
+ export {
34
+ createTaskGet,
35
+ taskGet
36
+ };
@@ -39,13 +39,14 @@ function operationToMethod(operation) {
39
39
  documentSymbol: "textDocument/documentSymbol",
40
40
  workspaceSymbol: "workspace/symbol",
41
41
  goToImplementation: "textDocument/implementation",
42
+ prepareCallHierarchy: "textDocument/prepareCallHierarchy",
42
43
  incomingCalls: "textDocument/prepareCallHierarchy",
43
44
  outgoingCalls: "textDocument/prepareCallHierarchy"
44
45
  };
45
46
  return map[operation] ?? operation;
46
47
  }
47
- function buildRequestParams(op, uri, line, char, query) {
48
- if (op === "workspaceSymbol") return { query: query ?? "" };
48
+ function buildRequestParams(op, uri, line, char) {
49
+ if (op === "workspaceSymbol") return { query: "" };
49
50
  const td = { uri };
50
51
  if (op === "documentSymbol") return { textDocument: td };
51
52
  const pos = { line, character: char };
@@ -128,7 +129,7 @@ async function executeLspOperation(serverConfig, params, timeoutMs) {
128
129
  textDocument: { uri, languageId: langId, version: 1, text: content }
129
130
  });
130
131
  const method = operationToMethod(params.operation);
131
- const reqParams = buildRequestParams(params.operation, uri, params.line ?? 0, params.character ?? 0, params.query);
132
+ const reqParams = buildRequestParams(params.operation, uri, params.line ?? 0, params.character ?? 0);
132
133
  let response = await rpc(sendRequest(proc, method, reqParams));
133
134
  if (response.error) return `Error [lsp]: Server error: ${response.error.message} (code ${response.error.code})`;
134
135
  if ((params.operation === "incomingCalls" || params.operation === "outgoingCalls") && Array.isArray(response.result) && response.result.length > 0) {
@@ -150,21 +151,21 @@ var LSP_OPERATIONS = [
150
151
  "documentSymbol",
151
152
  "workspaceSymbol",
152
153
  "goToImplementation",
154
+ "prepareCallHierarchy",
153
155
  "incomingCalls",
154
156
  "outgoingCalls"
155
157
  ];
156
158
  function createLsp(config = {}) {
157
159
  const timeoutMs = config.timeout ?? 3e4;
158
160
  return tool({
159
- description: "Perform language server operations like go-to-definition, find-references, and hover. Requires LSP server configuration. Supports 8 operations: goToDefinition, findReferences, hover, documentSymbol, workspaceSymbol, goToImplementation, incomingCalls, outgoingCalls.",
161
+ description: "Perform language server operations like go-to-definition, find-references, and hover. Requires LSP server configuration. Supports 9 operations: goToDefinition, findReferences, hover, documentSymbol, workspaceSymbol, goToImplementation, prepareCallHierarchy, incomingCalls, outgoingCalls.",
160
162
  inputSchema: z.object({
161
163
  operation: z.enum(LSP_OPERATIONS).describe("The LSP operation to perform"),
162
164
  filePath: z.string().describe("Path to the file"),
163
- line: z.number().optional().describe("Line number (0-indexed)"),
164
- character: z.number().optional().describe("Character offset (0-indexed)"),
165
- query: z.string().optional().describe("Search query for workspaceSymbol")
165
+ line: z.number().int().positive().describe("The line number (1-based, as shown in editors)"),
166
+ character: z.number().int().positive().describe("The character offset (1-based, as shown in editors)")
166
167
  }),
167
- execute: async ({ operation, filePath, line, character, query }) => {
168
+ execute: async ({ operation, filePath, line, character }) => {
168
169
  if (!config.servers || Object.keys(config.servers).length === 0) {
169
170
  return 'Error [lsp]: No LSP servers configured. Provide server configuration via createLsp({ servers: { ".ts": { command: "typescript-language-server", args: ["--stdio"] } } })';
170
171
  }
@@ -177,7 +178,7 @@ function createLsp(config = {}) {
177
178
  try {
178
179
  return await executeLspOperation(
179
180
  serverConfig,
180
- { operation, filePath, line, character, query, cwd: config.cwd ?? process.cwd() },
181
+ { operation, filePath, line: line - 1, character: character - 1, cwd: config.cwd ?? process.cwd() },
181
182
  timeoutMs
182
183
  );
183
184
  } catch (error) {
@@ -15,10 +15,10 @@ function createEdit(config = {}) {
15
15
  return _ai.tool.call(void 0, {
16
16
  description: "Perform an exact string replacement in a file. Locates old_string in the file and replaces it with new_string. Supports curly-quote fallback matching. When replace_all is false (default), old_string must appear exactly once.",
17
17
  inputSchema: _zod.z.object({
18
- file_path: _zod.z.string().describe("Path to the file to edit"),
18
+ file_path: _zod.z.string().describe("The absolute path to the file to modify"),
19
19
  old_string: _zod.z.string().describe("The exact string to find and replace"),
20
20
  new_string: _zod.z.string().describe("The replacement string"),
21
- replace_all: _zod.z.boolean().optional().default(false).describe("Replace all occurrences (default: false)")
21
+ replace_all: _zod.z.boolean().default(false).optional().describe("Replace all occurrences (default: false)")
22
22
  }),
23
23
  execute: async ({ file_path, old_string, new_string, replace_all }) => {
24
24
  try {
@@ -0,0 +1,75 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }
2
+
3
+
4
+
5
+ var _chunkL5JH4I77cjs = require('./chunk-L5JH4I77.cjs');
6
+
7
+ // src/task-update/index.ts
8
+ var _ai = require('ai');
9
+ var _zod = require('zod');
10
+ var _path = require('path');
11
+ function createTaskUpdate(config = {}) {
12
+ const cwd = _nullishCoalesce(config.cwd, () => ( process.cwd()));
13
+ const tasksFile = _nullishCoalesce(config.tasksFile, () => ( _path.join.call(void 0, cwd, ".agentool", "tasks.json")));
14
+ return _ai.tool.call(void 0, {
15
+ description: "Update a task by its ID. Can change status, subject, description, owner, metadata, and dependency relationships.",
16
+ inputSchema: _zod.z.object({
17
+ taskId: _zod.z.string().describe("The ID of the task to update"),
18
+ subject: _zod.z.string().optional().describe("New subject for the task"),
19
+ description: _zod.z.string().optional().describe("New description"),
20
+ status: _zod.z.enum(["pending", "in_progress", "completed", "deleted"]).optional().describe("New status for the task"),
21
+ owner: _zod.z.string().optional().describe("New owner for the task"),
22
+ activeForm: _zod.z.string().optional().describe("Present continuous form shown in spinner when in_progress"),
23
+ addBlocks: _zod.z.array(_zod.z.string()).optional().describe("Task IDs that this task blocks"),
24
+ addBlockedBy: _zod.z.array(_zod.z.string()).optional().describe("Task IDs that block this task"),
25
+ metadata: _zod.z.record(_zod.z.string(), _zod.z.unknown()).optional().describe("Metadata keys to merge. Set key to null to delete.")
26
+ }),
27
+ execute: async (input) => {
28
+ try {
29
+ const tasks = await _chunkL5JH4I77cjs.loadTasks.call(void 0, tasksFile);
30
+ const idx = tasks.findIndex((t) => t.id === input.taskId);
31
+ if (idx === -1) return `Error [task-update]: Task "${input.taskId}" not found.`;
32
+ const entry = tasks[idx];
33
+ if (input.subject !== void 0) entry.subject = input.subject;
34
+ if (input.description !== void 0) entry.description = input.description;
35
+ if (input.status !== void 0) entry.status = input.status;
36
+ if (input.owner !== void 0) entry.owner = input.owner;
37
+ if (input.activeForm !== void 0) entry.activeForm = input.activeForm;
38
+ if (input.addBlocks) {
39
+ for (const id of input.addBlocks) {
40
+ if (!entry.blocks.includes(id)) entry.blocks.push(id);
41
+ }
42
+ }
43
+ if (input.addBlockedBy) {
44
+ for (const id of input.addBlockedBy) {
45
+ if (!entry.blockedBy.includes(id)) entry.blockedBy.push(id);
46
+ }
47
+ }
48
+ if (input.metadata) {
49
+ if (!entry.metadata) entry.metadata = {};
50
+ for (const [key, value] of Object.entries(input.metadata)) {
51
+ if (value === null) {
52
+ delete entry.metadata[key];
53
+ } else {
54
+ entry.metadata[key] = value;
55
+ }
56
+ }
57
+ }
58
+ entry.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
59
+ tasks[idx] = entry;
60
+ await _chunkL5JH4I77cjs.saveTasks.call(void 0, tasksFile, tasks);
61
+ return `Updated task ${input.taskId}.
62
+ ${_chunkL5JH4I77cjs.formatTask.call(void 0, entry)}`;
63
+ } catch (error) {
64
+ const msg = error instanceof Error ? error.message : String(error);
65
+ return `Error [task-update]: ${msg}`;
66
+ }
67
+ }
68
+ });
69
+ }
70
+ var taskUpdate = createTaskUpdate();
71
+
72
+
73
+
74
+
75
+ exports.createTaskUpdate = createTaskUpdate; exports.taskUpdate = taskUpdate;
@@ -1,10 +1,10 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
3
 
4
- var _chunkMXFW3XY6cjs = require('../chunk-MXFW3XY6.cjs');
4
+ var _chunkZBLQV6UOcjs = require('../chunk-ZBLQV6UO.cjs');
5
5
  require('../chunk-5NW4OGRI.cjs');
6
6
  require('../chunk-QZ5GS6HW.cjs');
7
7
 
8
8
 
9
9
 
10
- exports.createEdit = _chunkMXFW3XY6cjs.createEdit; exports.edit = _chunkMXFW3XY6cjs.edit;
10
+ exports.createEdit = _chunkZBLQV6UOcjs.createEdit; exports.edit = _chunkZBLQV6UOcjs.edit;
@@ -29,7 +29,7 @@ declare function createEdit(config?: BaseToolConfig): ai.Tool<{
29
29
  file_path: string;
30
30
  old_string: string;
31
31
  new_string: string;
32
- replace_all: boolean;
32
+ replace_all?: boolean | undefined;
33
33
  }, string>;
34
34
  /**
35
35
  * Default edit tool instance using the current working directory.
@@ -47,7 +47,7 @@ declare const edit: ai.Tool<{
47
47
  file_path: string;
48
48
  old_string: string;
49
49
  new_string: string;
50
- replace_all: boolean;
50
+ replace_all?: boolean | undefined;
51
51
  }, string>;
52
52
 
53
53
  export { type EditConfig, createEdit, edit };
@@ -29,7 +29,7 @@ declare function createEdit(config?: BaseToolConfig): ai.Tool<{
29
29
  file_path: string;
30
30
  old_string: string;
31
31
  new_string: string;
32
- replace_all: boolean;
32
+ replace_all?: boolean | undefined;
33
33
  }, string>;
34
34
  /**
35
35
  * Default edit tool instance using the current working directory.
@@ -47,7 +47,7 @@ declare const edit: ai.Tool<{
47
47
  file_path: string;
48
48
  old_string: string;
49
49
  new_string: string;
50
- replace_all: boolean;
50
+ replace_all?: boolean | undefined;
51
51
  }, string>;
52
52
 
53
53
  export { type EditConfig, createEdit, edit };
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createEdit,
3
3
  edit
4
- } from "../chunk-S6QEY7UY.js";
4
+ } from "../chunk-P6Z5XFDS.js";
5
5
  import "../chunk-G3ITTPGX.js";
6
6
  import "../chunk-I3ONDY7P.js";
7
7
  export {
@@ -1,10 +1,10 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
3
 
4
- var _chunkQEJV2KZ4cjs = require('../chunk-QEJV2KZ4.cjs');
4
+ var _chunkHNP7JDQCcjs = require('../chunk-HNP7JDQC.cjs');
5
5
  require('../chunk-MIYA7TNR.cjs');
6
6
  require('../chunk-QZ5GS6HW.cjs');
7
7
 
8
8
 
9
9
 
10
- exports.createGrep = _chunkQEJV2KZ4cjs.createGrep; exports.grep = _chunkQEJV2KZ4cjs.grep;
10
+ exports.createGrep = _chunkHNP7JDQCcjs.createGrep; exports.grep = _chunkHNP7JDQCcjs.grep;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  createGrep,
3
3
  grep
4
- } from "../chunk-XKG2A3EW.js";
4
+ } from "../chunk-UDIG7332.js";
5
5
  import "../chunk-MJCAXASI.js";
6
6
  import "../chunk-I3ONDY7P.js";
7
7
  export {