agentool 0.0.1 → 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 (147) hide show
  1. package/README.md +738 -52
  2. package/dist/ask-user/index.cjs +8 -0
  3. package/dist/ask-user/index.d.cts +68 -0
  4. package/dist/ask-user/index.d.ts +68 -0
  5. package/dist/ask-user/index.js +8 -0
  6. package/dist/bash/index.cjs +8 -0
  7. package/dist/bash/index.d.cts +63 -0
  8. package/dist/bash/index.d.ts +63 -0
  9. package/dist/bash/index.js +8 -0
  10. package/dist/chunk-3EPGFWZV.cjs +30 -0
  11. package/dist/chunk-3VO6NETR.cjs +79 -0
  12. package/dist/chunk-44AFQ2B7.js +30 -0
  13. package/dist/chunk-4HIATLKI.js +112 -0
  14. package/dist/chunk-4HXAKPQH.cjs +36 -0
  15. package/dist/chunk-4YI2H55A.js +142 -0
  16. package/dist/chunk-56CL4JCW.cjs +53 -0
  17. package/dist/chunk-5NW4OGRI.cjs +99 -0
  18. package/dist/chunk-5O55DKOB.cjs +112 -0
  19. package/dist/chunk-5TDZF4IM.cjs +197 -0
  20. package/dist/chunk-6DJSWTWQ.cjs +40 -0
  21. package/dist/chunk-6PQLFDGT.js +117 -0
  22. package/dist/chunk-ACGW44YT.js +47 -0
  23. package/dist/chunk-CAEVLIQB.cjs +117 -0
  24. package/dist/chunk-CGTPF6IS.js +90 -0
  25. package/dist/chunk-E6NBEYZD.js +51 -0
  26. package/dist/chunk-EA3YV7ZG.js +79 -0
  27. package/dist/chunk-ECYT46FP.js +40 -0
  28. package/dist/chunk-FV2R5FFQ.cjs +102 -0
  29. package/dist/chunk-FW3UJ622.cjs +59 -0
  30. package/dist/chunk-G3ITTPGX.js +99 -0
  31. package/dist/chunk-HDKXSKMO.js +30 -0
  32. package/dist/chunk-HNP7JDQC.cjs +159 -0
  33. package/dist/chunk-HNUL2CID.cjs +34 -0
  34. package/dist/chunk-HZAQRHBT.js +99 -0
  35. package/dist/chunk-I3ONDY7P.js +46 -0
  36. package/dist/chunk-I6KFFQPV.cjs +58 -0
  37. package/dist/chunk-IEX4NOVN.cjs +48 -0
  38. package/dist/chunk-IRRNYFI5.js +48 -0
  39. package/dist/chunk-K77GC2QI.js +59 -0
  40. package/dist/chunk-L5JH4I77.cjs +51 -0
  41. package/dist/chunk-LK6SQH2G.cjs +30 -0
  42. package/dist/chunk-LPV5CN2K.js +58 -0
  43. package/dist/chunk-LTE5NG4D.js +53 -0
  44. package/dist/chunk-MF7CJVIZ.js +40 -0
  45. package/dist/chunk-MIYA7TNR.cjs +123 -0
  46. package/dist/chunk-MJCAXASI.js +123 -0
  47. package/dist/chunk-OM2UFTGS.cjs +47 -0
  48. package/dist/chunk-ONBH74ZV.cjs +90 -0
  49. package/dist/chunk-OXLQ7QVL.cjs +40 -0
  50. package/dist/chunk-P6Z5XFDS.js +73 -0
  51. package/dist/chunk-QZ5GS6HW.cjs +46 -0
  52. package/dist/chunk-S7IVHOA6.js +75 -0
  53. package/dist/chunk-SUSAPI5W.cjs +142 -0
  54. package/dist/chunk-TMW3XKKJ.js +34 -0
  55. package/dist/chunk-UDIG7332.js +159 -0
  56. package/dist/chunk-VLNDEVKS.js +102 -0
  57. package/dist/chunk-VXZ4RKJI.js +36 -0
  58. package/dist/chunk-XAQGZ374.js +197 -0
  59. package/dist/chunk-YPPPGGLA.cjs +99 -0
  60. package/dist/chunk-ZBLQV6UO.cjs +73 -0
  61. package/dist/chunk-ZFQZWXOI.cjs +75 -0
  62. package/dist/context-compaction/index.cjs +8 -0
  63. package/dist/context-compaction/index.d.cts +77 -0
  64. package/dist/context-compaction/index.d.ts +77 -0
  65. package/dist/context-compaction/index.js +8 -0
  66. package/dist/diff/index.cjs +9 -0
  67. package/dist/diff/index.d.cts +72 -0
  68. package/dist/diff/index.d.ts +72 -0
  69. package/dist/diff/index.js +9 -0
  70. package/dist/edit/index.cjs +10 -0
  71. package/dist/edit/index.d.cts +53 -0
  72. package/dist/edit/index.d.ts +53 -0
  73. package/dist/edit/index.js +10 -0
  74. package/dist/glob/index.cjs +10 -0
  75. package/dist/glob/index.d.cts +47 -0
  76. package/dist/glob/index.d.ts +47 -0
  77. package/dist/glob/index.js +10 -0
  78. package/dist/grep/index.cjs +10 -0
  79. package/dist/grep/index.d.cts +50 -0
  80. package/dist/grep/index.d.ts +50 -0
  81. package/dist/grep/index.js +10 -0
  82. package/dist/http-request/index.cjs +8 -0
  83. package/dist/http-request/index.d.cts +60 -0
  84. package/dist/http-request/index.d.ts +60 -0
  85. package/dist/http-request/index.js +8 -0
  86. package/dist/index.cjs +133 -0
  87. package/dist/index.d.cts +23 -0
  88. package/dist/index.d.ts +23 -0
  89. package/dist/index.js +133 -0
  90. package/dist/lsp/index.cjs +10 -0
  91. package/dist/lsp/index.d.cts +35 -0
  92. package/dist/lsp/index.d.ts +35 -0
  93. package/dist/lsp/index.js +10 -0
  94. package/dist/memory/index.cjs +9 -0
  95. package/dist/memory/index.d.cts +63 -0
  96. package/dist/memory/index.d.ts +63 -0
  97. package/dist/memory/index.js +9 -0
  98. package/dist/multi-edit/index.cjs +11 -0
  99. package/dist/multi-edit/index.d.cts +72 -0
  100. package/dist/multi-edit/index.d.ts +72 -0
  101. package/dist/multi-edit/index.js +11 -0
  102. package/dist/read/index.cjs +10 -0
  103. package/dist/read/index.d.cts +67 -0
  104. package/dist/read/index.d.ts +67 -0
  105. package/dist/read/index.js +10 -0
  106. package/dist/sleep/index.cjs +8 -0
  107. package/dist/sleep/index.d.cts +60 -0
  108. package/dist/sleep/index.d.ts +60 -0
  109. package/dist/sleep/index.js +8 -0
  110. package/dist/task-create/index.cjs +9 -0
  111. package/dist/task-create/index.d.cts +19 -0
  112. package/dist/task-create/index.d.ts +19 -0
  113. package/dist/task-create/index.js +9 -0
  114. package/dist/task-get/index.cjs +9 -0
  115. package/dist/task-get/index.d.cts +15 -0
  116. package/dist/task-get/index.d.ts +15 -0
  117. package/dist/task-get/index.js +9 -0
  118. package/dist/task-list/index.cjs +9 -0
  119. package/dist/task-list/index.d.cts +11 -0
  120. package/dist/task-list/index.d.ts +11 -0
  121. package/dist/task-list/index.js +9 -0
  122. package/dist/task-update/index.cjs +9 -0
  123. package/dist/task-update/index.d.cts +31 -0
  124. package/dist/task-update/index.d.ts +31 -0
  125. package/dist/task-update/index.js +9 -0
  126. package/dist/tool-search/index.cjs +8 -0
  127. package/dist/tool-search/index.d.cts +18 -0
  128. package/dist/tool-search/index.d.ts +18 -0
  129. package/dist/tool-search/index.js +8 -0
  130. package/dist/types-3QPDuCXN.d.cts +45 -0
  131. package/dist/types-3QPDuCXN.d.ts +45 -0
  132. package/dist/web-fetch/index.cjs +8 -0
  133. package/dist/web-fetch/index.d.cts +54 -0
  134. package/dist/web-fetch/index.d.ts +54 -0
  135. package/dist/web-fetch/index.js +8 -0
  136. package/dist/web-search/index.cjs +8 -0
  137. package/dist/web-search/index.d.cts +21 -0
  138. package/dist/web-search/index.d.ts +21 -0
  139. package/dist/web-search/index.js +8 -0
  140. package/dist/write/index.cjs +10 -0
  141. package/dist/write/index.d.cts +47 -0
  142. package/dist/write/index.d.ts +47 -0
  143. package/dist/write/index.js +10 -0
  144. package/package.json +170 -20
  145. package/dist/core/index.d.ts +0 -20
  146. package/dist/core/index.js +0 -1
  147. package/dist/core/index.js.map +0 -1
@@ -0,0 +1,117 @@
1
+ // src/shared/file.ts
2
+ import { createReadStream } from "fs";
3
+ import { mkdir, readFile, stat, writeFile } from "fs/promises";
4
+ import { dirname } from "path";
5
+ var FAST_PATH_MAX_SIZE = 10 * 1024 * 1024;
6
+ function addLineNumbers({
7
+ content,
8
+ startLine
9
+ }) {
10
+ if (!content) {
11
+ return "";
12
+ }
13
+ const lines = content.split(/\r?\n/);
14
+ return lines.map((line, index) => `${index + startLine} ${line}`).join("\n");
15
+ }
16
+ async function writeTextContent(filePath, content) {
17
+ await mkdir(dirname(filePath), { recursive: true });
18
+ await writeFile(filePath, content, { encoding: "utf-8" });
19
+ }
20
+ async function pathExists(path) {
21
+ try {
22
+ await stat(path);
23
+ return true;
24
+ } catch {
25
+ return false;
26
+ }
27
+ }
28
+ async function readFileInRange(filePath, offset = 0, maxLines) {
29
+ const stats = await stat(filePath);
30
+ if (stats.isDirectory()) {
31
+ throw new Error(
32
+ `EISDIR: illegal operation on a directory, read '${filePath}'`
33
+ );
34
+ }
35
+ if (stats.isFile() && stats.size < FAST_PATH_MAX_SIZE) {
36
+ const raw = await readFile(filePath, { encoding: "utf-8" });
37
+ return readFileInRangeFast(raw, offset, maxLines);
38
+ }
39
+ return readFileInRangeStreaming(filePath, offset, maxLines);
40
+ }
41
+ function readFileInRangeFast(raw, offset, maxLines) {
42
+ const text = raw.charCodeAt(0) === 65279 ? raw.slice(1) : raw;
43
+ const allLines = text.replace(/\r/g, "").split("\n");
44
+ const totalLines = allLines.length;
45
+ const endLine = maxLines !== void 0 ? offset + maxLines : totalLines;
46
+ const selected = allLines.slice(offset, endLine);
47
+ return {
48
+ content: selected.join("\n"),
49
+ lineCount: selected.length,
50
+ totalLines
51
+ };
52
+ }
53
+ function readFileInRangeStreaming(filePath, offset, maxLines) {
54
+ return new Promise((resolve, reject) => {
55
+ const endLine = maxLines !== void 0 ? offset + maxLines : Infinity;
56
+ const selectedLines = [];
57
+ let currentLineIndex = 0;
58
+ let partial = "";
59
+ let isFirstChunk = true;
60
+ const stream = createReadStream(filePath, {
61
+ encoding: "utf8",
62
+ highWaterMark: 512 * 1024
63
+ });
64
+ stream.on("data", (raw) => {
65
+ let chunk = String(raw);
66
+ if (isFirstChunk) {
67
+ isFirstChunk = false;
68
+ if (chunk.charCodeAt(0) === 65279) {
69
+ chunk = chunk.slice(1);
70
+ }
71
+ }
72
+ const data = partial.length > 0 ? partial + chunk : chunk;
73
+ partial = "";
74
+ let startPos = 0;
75
+ let newlinePos;
76
+ while ((newlinePos = data.indexOf("\n", startPos)) !== -1) {
77
+ if (currentLineIndex >= offset && currentLineIndex < endLine) {
78
+ let line = data.slice(startPos, newlinePos);
79
+ if (line.endsWith("\r")) {
80
+ line = line.slice(0, -1);
81
+ }
82
+ selectedLines.push(line);
83
+ }
84
+ currentLineIndex++;
85
+ startPos = newlinePos + 1;
86
+ }
87
+ if (startPos < data.length) {
88
+ if (currentLineIndex >= offset && currentLineIndex < endLine) {
89
+ partial = data.slice(startPos);
90
+ }
91
+ }
92
+ });
93
+ stream.once("end", () => {
94
+ if (partial.length > 0 && currentLineIndex >= offset && currentLineIndex < endLine) {
95
+ let line = partial;
96
+ if (line.endsWith("\r")) {
97
+ line = line.slice(0, -1);
98
+ }
99
+ selectedLines.push(line);
100
+ }
101
+ currentLineIndex++;
102
+ resolve({
103
+ content: selectedLines.join("\n"),
104
+ lineCount: selectedLines.length,
105
+ totalLines: currentLineIndex
106
+ });
107
+ });
108
+ stream.once("error", reject);
109
+ });
110
+ }
111
+
112
+ export {
113
+ addLineNumbers,
114
+ writeTextContent,
115
+ pathExists,
116
+ readFileInRange
117
+ };
@@ -0,0 +1,47 @@
1
+ import {
2
+ addLineNumbers,
3
+ readFileInRange
4
+ } from "./chunk-6PQLFDGT.js";
5
+ import {
6
+ expandPath
7
+ } from "./chunk-I3ONDY7P.js";
8
+
9
+ // src/read/index.ts
10
+ import { tool } from "ai";
11
+ import { z } from "zod";
12
+ function createRead(config = {}) {
13
+ const cwd = config.cwd ?? process.cwd();
14
+ const defaultMaxLines = config.maxLines ?? 2e3;
15
+ return tool({
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
+ inputSchema: z.object({
18
+ file_path: z.string().describe("The absolute path to the file to read"),
19
+ offset: z.number().int().nonnegative().optional().describe("The line number to start reading from (default: 0)"),
20
+ limit: z.number().int().positive().optional().describe("The number of lines to read (default: 2000)")
21
+ }),
22
+ execute: async ({ file_path, offset, limit }) => {
23
+ try {
24
+ const absolutePath = expandPath(file_path, cwd);
25
+ const result = await readFileInRange(
26
+ absolutePath,
27
+ offset ?? 0,
28
+ limit ?? defaultMaxLines
29
+ );
30
+ const numbered = addLineNumbers({
31
+ content: result.content,
32
+ startLine: (offset ?? 0) + 1
33
+ });
34
+ return numbered;
35
+ } catch (error) {
36
+ const msg = error instanceof Error ? error.message : String(error);
37
+ return `Error [read]: ${msg}`;
38
+ }
39
+ }
40
+ });
41
+ }
42
+ var read = createRead();
43
+
44
+ export {
45
+ createRead,
46
+ read
47
+ };
@@ -0,0 +1,117 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/shared/file.ts
2
+ var _fs = require('fs');
3
+ var _promises = require('fs/promises');
4
+ var _path = require('path');
5
+ var FAST_PATH_MAX_SIZE = 10 * 1024 * 1024;
6
+ function addLineNumbers({
7
+ content,
8
+ startLine
9
+ }) {
10
+ if (!content) {
11
+ return "";
12
+ }
13
+ const lines = content.split(/\r?\n/);
14
+ return lines.map((line, index) => `${index + startLine} ${line}`).join("\n");
15
+ }
16
+ async function writeTextContent(filePath, content) {
17
+ await _promises.mkdir.call(void 0, _path.dirname.call(void 0, filePath), { recursive: true });
18
+ await _promises.writeFile.call(void 0, filePath, content, { encoding: "utf-8" });
19
+ }
20
+ async function pathExists(path) {
21
+ try {
22
+ await _promises.stat.call(void 0, path);
23
+ return true;
24
+ } catch (e) {
25
+ return false;
26
+ }
27
+ }
28
+ async function readFileInRange(filePath, offset = 0, maxLines) {
29
+ const stats = await _promises.stat.call(void 0, filePath);
30
+ if (stats.isDirectory()) {
31
+ throw new Error(
32
+ `EISDIR: illegal operation on a directory, read '${filePath}'`
33
+ );
34
+ }
35
+ if (stats.isFile() && stats.size < FAST_PATH_MAX_SIZE) {
36
+ const raw = await _promises.readFile.call(void 0, filePath, { encoding: "utf-8" });
37
+ return readFileInRangeFast(raw, offset, maxLines);
38
+ }
39
+ return readFileInRangeStreaming(filePath, offset, maxLines);
40
+ }
41
+ function readFileInRangeFast(raw, offset, maxLines) {
42
+ const text = raw.charCodeAt(0) === 65279 ? raw.slice(1) : raw;
43
+ const allLines = text.replace(/\r/g, "").split("\n");
44
+ const totalLines = allLines.length;
45
+ const endLine = maxLines !== void 0 ? offset + maxLines : totalLines;
46
+ const selected = allLines.slice(offset, endLine);
47
+ return {
48
+ content: selected.join("\n"),
49
+ lineCount: selected.length,
50
+ totalLines
51
+ };
52
+ }
53
+ function readFileInRangeStreaming(filePath, offset, maxLines) {
54
+ return new Promise((resolve, reject) => {
55
+ const endLine = maxLines !== void 0 ? offset + maxLines : Infinity;
56
+ const selectedLines = [];
57
+ let currentLineIndex = 0;
58
+ let partial = "";
59
+ let isFirstChunk = true;
60
+ const stream = _fs.createReadStream.call(void 0, filePath, {
61
+ encoding: "utf8",
62
+ highWaterMark: 512 * 1024
63
+ });
64
+ stream.on("data", (raw) => {
65
+ let chunk = String(raw);
66
+ if (isFirstChunk) {
67
+ isFirstChunk = false;
68
+ if (chunk.charCodeAt(0) === 65279) {
69
+ chunk = chunk.slice(1);
70
+ }
71
+ }
72
+ const data = partial.length > 0 ? partial + chunk : chunk;
73
+ partial = "";
74
+ let startPos = 0;
75
+ let newlinePos;
76
+ while ((newlinePos = data.indexOf("\n", startPos)) !== -1) {
77
+ if (currentLineIndex >= offset && currentLineIndex < endLine) {
78
+ let line = data.slice(startPos, newlinePos);
79
+ if (line.endsWith("\r")) {
80
+ line = line.slice(0, -1);
81
+ }
82
+ selectedLines.push(line);
83
+ }
84
+ currentLineIndex++;
85
+ startPos = newlinePos + 1;
86
+ }
87
+ if (startPos < data.length) {
88
+ if (currentLineIndex >= offset && currentLineIndex < endLine) {
89
+ partial = data.slice(startPos);
90
+ }
91
+ }
92
+ });
93
+ stream.once("end", () => {
94
+ if (partial.length > 0 && currentLineIndex >= offset && currentLineIndex < endLine) {
95
+ let line = partial;
96
+ if (line.endsWith("\r")) {
97
+ line = line.slice(0, -1);
98
+ }
99
+ selectedLines.push(line);
100
+ }
101
+ currentLineIndex++;
102
+ resolve({
103
+ content: selectedLines.join("\n"),
104
+ lineCount: selectedLines.length,
105
+ totalLines: currentLineIndex
106
+ });
107
+ });
108
+ stream.once("error", reject);
109
+ });
110
+ }
111
+
112
+
113
+
114
+
115
+
116
+
117
+ exports.addLineNumbers = addLineNumbers; exports.writeTextContent = writeTextContent; exports.pathExists = pathExists; exports.readFileInRange = readFileInRange;
@@ -0,0 +1,90 @@
1
+ import {
2
+ expandPath
3
+ } from "./chunk-I3ONDY7P.js";
4
+
5
+ // src/diff/index.ts
6
+ import { readFile as readFile2 } from "fs/promises";
7
+ import { tool } from "ai";
8
+ import { z } from "zod";
9
+
10
+ // src/shared/diff.ts
11
+ import { readFile } from "fs/promises";
12
+ import { createTwoFilesPatch } from "diff";
13
+ function diffStrings(oldContent, newContent, options) {
14
+ if (oldContent === newContent) {
15
+ return "No differences found.";
16
+ }
17
+ const context = options?.context ?? 3;
18
+ const oldLabel = options?.oldLabel ?? "a";
19
+ const newLabel = options?.newLabel ?? "b";
20
+ return createTwoFilesPatch(
21
+ oldLabel,
22
+ newLabel,
23
+ oldContent,
24
+ newContent,
25
+ void 0,
26
+ void 0,
27
+ { context }
28
+ );
29
+ }
30
+ async function diffFiles(oldFilePath, newFilePath, options) {
31
+ const [oldContent, newContent] = await Promise.all([
32
+ readFile(oldFilePath, "utf-8"),
33
+ readFile(newFilePath, "utf-8")
34
+ ]);
35
+ return diffStrings(oldContent, newContent, {
36
+ ...options,
37
+ oldLabel: oldFilePath,
38
+ newLabel: newFilePath
39
+ });
40
+ }
41
+
42
+ // src/diff/index.ts
43
+ function createDiff(config = {}) {
44
+ const cwd = config.cwd ?? process.cwd();
45
+ return tool({
46
+ description: "Generate a unified diff between two files or two strings. Provide file_path + other_file_path to compare files, or old_content + new_content to compare strings. You can also provide file_path with old_content or new_content to compare a file against provided content.",
47
+ inputSchema: z.object({
48
+ file_path: z.string().optional().describe("Path to the first file (absolute or relative to cwd)"),
49
+ other_file_path: z.string().optional().describe("Path to the second file (absolute or relative to cwd)"),
50
+ old_content: z.string().optional().describe("The original content string"),
51
+ new_content: z.string().optional().describe("The modified content string")
52
+ }),
53
+ execute: async ({ file_path, other_file_path, old_content, new_content }) => {
54
+ try {
55
+ if (file_path && other_file_path) {
56
+ const resolvedOld = expandPath(file_path, cwd);
57
+ const resolvedNew = expandPath(other_file_path, cwd);
58
+ return await diffFiles(resolvedOld, resolvedNew);
59
+ }
60
+ if (old_content !== void 0 && new_content !== void 0 && !file_path) {
61
+ return diffStrings(old_content, new_content);
62
+ }
63
+ if (file_path && (old_content !== void 0 || new_content !== void 0)) {
64
+ const resolvedPath = expandPath(file_path, cwd);
65
+ const fileContent = await readFile2(resolvedPath, "utf-8");
66
+ if (old_content !== void 0) {
67
+ return diffStrings(old_content, fileContent, {
68
+ oldLabel: "provided",
69
+ newLabel: resolvedPath
70
+ });
71
+ }
72
+ return diffStrings(fileContent, new_content, {
73
+ oldLabel: resolvedPath,
74
+ newLabel: "provided"
75
+ });
76
+ }
77
+ return "Error [diff]: Insufficient parameters. Provide either: (1) file_path + other_file_path, (2) old_content + new_content, or (3) file_path + old_content/new_content.";
78
+ } catch (error) {
79
+ const msg = error instanceof Error ? error.message : String(error);
80
+ return `Error [diff]: ${msg}`;
81
+ }
82
+ }
83
+ });
84
+ }
85
+ var diff = createDiff();
86
+
87
+ export {
88
+ createDiff,
89
+ diff
90
+ };
@@ -0,0 +1,51 @@
1
+ // src/shared/task-store.ts
2
+ import { mkdir, readFile, writeFile } from "fs/promises";
3
+ import { dirname } from "path";
4
+ import { randomBytes } from "crypto";
5
+ function generateId() {
6
+ return randomBytes(4).toString("hex");
7
+ }
8
+ async function loadTasks(filePath) {
9
+ try {
10
+ const data = await readFile(filePath, "utf-8");
11
+ return JSON.parse(data);
12
+ } catch {
13
+ return [];
14
+ }
15
+ }
16
+ async function saveTasks(filePath, tasks) {
17
+ await mkdir(dirname(filePath), { recursive: true });
18
+ await writeFile(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
+ export {
46
+ generateId,
47
+ loadTasks,
48
+ saveTasks,
49
+ formatTask,
50
+ formatTaskSummary
51
+ };
@@ -0,0 +1,79 @@
1
+ import {
2
+ applyEditToFile,
3
+ findActualString,
4
+ preserveQuoteStyle
5
+ } from "./chunk-G3ITTPGX.js";
6
+ import {
7
+ writeTextContent
8
+ } from "./chunk-6PQLFDGT.js";
9
+ import {
10
+ expandPath
11
+ } from "./chunk-I3ONDY7P.js";
12
+
13
+ // src/multi-edit/index.ts
14
+ import { readFile } from "fs/promises";
15
+ import { tool } from "ai";
16
+ import { z } from "zod";
17
+ function countOccurrences(text, search) {
18
+ if (search.length === 0) return 0;
19
+ let count = 0;
20
+ let pos = 0;
21
+ while ((pos = text.indexOf(search, pos)) !== -1) {
22
+ count++;
23
+ pos += search.length;
24
+ }
25
+ return count;
26
+ }
27
+ function createMultiEdit(config = {}) {
28
+ const cwd = config.cwd ?? process.cwd();
29
+ return tool({
30
+ description: "Atomically apply multiple text edits to a single file. All edits succeed together or none are applied (rollback on failure). Each edit replaces one occurrence of old_string with new_string. Edits are applied sequentially in the order provided.",
31
+ inputSchema: z.object({
32
+ file_path: z.string().describe("Path to the file to edit (absolute or relative to cwd)"),
33
+ edits: z.array(
34
+ z.object({
35
+ old_string: z.string().describe("The exact string to find and replace"),
36
+ new_string: z.string().describe("The replacement string")
37
+ })
38
+ ).describe("Ordered list of edits to apply atomically")
39
+ }),
40
+ execute: async ({ file_path, edits }) => {
41
+ try {
42
+ if (edits.length === 0) {
43
+ return "No edits provided. File unchanged.";
44
+ }
45
+ const resolvedPath = expandPath(file_path, cwd);
46
+ const originalContent = await readFile(resolvedPath, "utf-8");
47
+ let content = originalContent;
48
+ for (let i = 0; i < edits.length; i++) {
49
+ const edit = edits[i];
50
+ const actualOldString = findActualString(content, edit.old_string);
51
+ if (actualOldString === null) {
52
+ return `Error [multi-edit]: Edit ${i + 1}/${edits.length} failed \u2014 old_string not found in file. No edits were applied. File: ${resolvedPath}`;
53
+ }
54
+ const occurrences = countOccurrences(content, actualOldString);
55
+ if (occurrences > 1) {
56
+ return `Error [multi-edit]: Edit ${i + 1}/${edits.length} failed \u2014 old_string matches ${occurrences} locations (must be unique). No edits were applied. File: ${resolvedPath}`;
57
+ }
58
+ const styledNewString = preserveQuoteStyle(
59
+ edit.old_string,
60
+ actualOldString,
61
+ edit.new_string
62
+ );
63
+ content = applyEditToFile(content, actualOldString, styledNewString);
64
+ }
65
+ await writeTextContent(resolvedPath, content);
66
+ return `Successfully applied ${edits.length} edit${edits.length === 1 ? "" : "s"} to ${resolvedPath}`;
67
+ } catch (error) {
68
+ const msg = error instanceof Error ? error.message : String(error);
69
+ return `Error [multi-edit]: ${msg}`;
70
+ }
71
+ }
72
+ });
73
+ }
74
+ var multiEdit = createMultiEdit();
75
+
76
+ export {
77
+ createMultiEdit,
78
+ multiEdit
79
+ };
@@ -0,0 +1,40 @@
1
+ import {
2
+ pathExists,
3
+ writeTextContent
4
+ } from "./chunk-6PQLFDGT.js";
5
+ import {
6
+ expandPath
7
+ } from "./chunk-I3ONDY7P.js";
8
+
9
+ // src/write/index.ts
10
+ import { tool } from "ai";
11
+ import { z } from "zod";
12
+ function createWrite(config = {}) {
13
+ const cwd = config.cwd ?? process.cwd();
14
+ return tool({
15
+ description: "Write text content to a file, creating parent directories as needed. If the file exists it is overwritten. Use this to create new files or replace existing file contents.",
16
+ inputSchema: z.object({
17
+ file_path: z.string().describe("The absolute path to the file to write (must be absolute, not relative)"),
18
+ content: z.string().describe("Text content to write to the file")
19
+ }),
20
+ execute: async ({ file_path, content }) => {
21
+ try {
22
+ const absolutePath = expandPath(file_path, cwd);
23
+ const existed = await pathExists(absolutePath);
24
+ await writeTextContent(absolutePath, content);
25
+ const bytes = Buffer.byteLength(content, "utf-8");
26
+ const verb = existed ? "Updated" : "Created";
27
+ return `${verb} file: ${absolutePath} (${bytes} bytes)`;
28
+ } catch (error) {
29
+ const message = error instanceof Error ? error.message : String(error);
30
+ return `Error [write]: Failed to write file: ${message}`;
31
+ }
32
+ }
33
+ });
34
+ }
35
+ var write = createWrite();
36
+
37
+ export {
38
+ createWrite,
39
+ write
40
+ };
@@ -0,0 +1,102 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }
2
+
3
+ var _chunkQZ5GS6HWcjs = require('./chunk-QZ5GS6HW.cjs');
4
+
5
+ // src/memory/index.ts
6
+ var _ai = require('ai');
7
+ var _zod = require('zod');
8
+ var _promises = require('fs/promises');
9
+ var _path = require('path');
10
+ function sanitizeKey(key) {
11
+ if (!key || key.trim() === "") {
12
+ return { err: "Error [memory]: Key must not be empty." };
13
+ }
14
+ if (_chunkQZ5GS6HWcjs.containsPathTraversal.call(void 0, key)) {
15
+ return { err: "Error [memory]: Key contains path traversal and was rejected." };
16
+ }
17
+ const cleaned = key.replace(/^\.+/, "");
18
+ if (cleaned === "") {
19
+ return { err: "Error [memory]: Key must not be empty after stripping leading dots." };
20
+ }
21
+ return { ok: cleaned };
22
+ }
23
+ function createMemory(config = {}) {
24
+ const cwd = _nullishCoalesce(config.cwd, () => ( process.cwd()));
25
+ const memoryDir = _nullishCoalesce(config.memoryDir, () => ( _path.join.call(void 0, cwd, ".agentool", "memory")));
26
+ return _ai.tool.call(void 0, {
27
+ description: "File-based key-value memory store. Use this to persist notes, context, or any text data across conversations. Supports write, read, list, and delete operations.",
28
+ inputSchema: _zod.z.object({
29
+ action: _zod.z.enum(["read", "write", "list", "delete"]).describe(
30
+ "The operation to perform: read, write, list, or delete"
31
+ ),
32
+ key: _zod.z.string().optional().describe(
33
+ "The memory key (required for read, write, delete)"
34
+ ),
35
+ content: _zod.z.string().optional().describe(
36
+ "The content to store (required for write)"
37
+ )
38
+ }),
39
+ execute: async ({ action, key, content }) => {
40
+ try {
41
+ if (action === "list") {
42
+ return await listKeys(memoryDir);
43
+ }
44
+ const result = sanitizeKey(key);
45
+ if ("err" in result) return result.err;
46
+ const safeKey = result.ok;
47
+ switch (action) {
48
+ case "write":
49
+ return await writeEntry(memoryDir, safeKey, content);
50
+ case "read":
51
+ return await readEntry(memoryDir, safeKey);
52
+ case "delete":
53
+ return await deleteEntry(memoryDir, safeKey);
54
+ default:
55
+ return `Error [memory]: Unknown action "${String(action)}".`;
56
+ }
57
+ } catch (error) {
58
+ const msg = error instanceof Error ? error.message : String(error);
59
+ return `Error [memory]: ${msg}`;
60
+ }
61
+ }
62
+ });
63
+ }
64
+ async function writeEntry(dir, key, content) {
65
+ if (!content && content !== "") {
66
+ return "Error [memory]: Content is required for write action.";
67
+ }
68
+ await _promises.mkdir.call(void 0, dir, { recursive: true });
69
+ await _promises.writeFile.call(void 0, _path.join.call(void 0, dir, `${key}.md`), content, "utf-8");
70
+ return `Saved memory "${key}".`;
71
+ }
72
+ async function readEntry(dir, key) {
73
+ try {
74
+ return await _promises.readFile.call(void 0, _path.join.call(void 0, dir, `${key}.md`), "utf-8");
75
+ } catch (e) {
76
+ return `Error [memory]: Key "${key}" not found.`;
77
+ }
78
+ }
79
+ async function listKeys(dir) {
80
+ try {
81
+ const files = await _promises.readdir.call(void 0, dir);
82
+ const keys = files.filter((f) => f.endsWith(".md")).map((f) => f.slice(0, -3));
83
+ if (keys.length === 0) return "No memory entries found.";
84
+ return keys.join("\n");
85
+ } catch (e2) {
86
+ return "No memory entries found.";
87
+ }
88
+ }
89
+ async function deleteEntry(dir, key) {
90
+ try {
91
+ await _promises.unlink.call(void 0, _path.join.call(void 0, dir, `${key}.md`));
92
+ return `Deleted memory "${key}".`;
93
+ } catch (e3) {
94
+ return `Error [memory]: Key "${key}" not found.`;
95
+ }
96
+ }
97
+ var memory = createMemory();
98
+
99
+
100
+
101
+
102
+ exports.createMemory = createMemory; exports.memory = memory;