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.
- package/README.md +738 -52
- package/dist/ask-user/index.cjs +8 -0
- package/dist/ask-user/index.d.cts +68 -0
- package/dist/ask-user/index.d.ts +68 -0
- package/dist/ask-user/index.js +8 -0
- package/dist/bash/index.cjs +8 -0
- package/dist/bash/index.d.cts +63 -0
- package/dist/bash/index.d.ts +63 -0
- package/dist/bash/index.js +8 -0
- package/dist/chunk-3EPGFWZV.cjs +30 -0
- package/dist/chunk-3VO6NETR.cjs +79 -0
- package/dist/chunk-44AFQ2B7.js +30 -0
- package/dist/chunk-4HIATLKI.js +112 -0
- package/dist/chunk-4HXAKPQH.cjs +36 -0
- package/dist/chunk-4YI2H55A.js +142 -0
- package/dist/chunk-56CL4JCW.cjs +53 -0
- package/dist/chunk-5NW4OGRI.cjs +99 -0
- package/dist/chunk-5O55DKOB.cjs +112 -0
- package/dist/chunk-5TDZF4IM.cjs +197 -0
- package/dist/chunk-6DJSWTWQ.cjs +40 -0
- package/dist/chunk-6PQLFDGT.js +117 -0
- package/dist/chunk-ACGW44YT.js +47 -0
- package/dist/chunk-CAEVLIQB.cjs +117 -0
- package/dist/chunk-CGTPF6IS.js +90 -0
- package/dist/chunk-E6NBEYZD.js +51 -0
- package/dist/chunk-EA3YV7ZG.js +79 -0
- package/dist/chunk-ECYT46FP.js +40 -0
- package/dist/chunk-FV2R5FFQ.cjs +102 -0
- package/dist/chunk-FW3UJ622.cjs +59 -0
- package/dist/chunk-G3ITTPGX.js +99 -0
- package/dist/chunk-HDKXSKMO.js +30 -0
- package/dist/chunk-HNP7JDQC.cjs +159 -0
- package/dist/chunk-HNUL2CID.cjs +34 -0
- package/dist/chunk-HZAQRHBT.js +99 -0
- package/dist/chunk-I3ONDY7P.js +46 -0
- package/dist/chunk-I6KFFQPV.cjs +58 -0
- package/dist/chunk-IEX4NOVN.cjs +48 -0
- package/dist/chunk-IRRNYFI5.js +48 -0
- package/dist/chunk-K77GC2QI.js +59 -0
- package/dist/chunk-L5JH4I77.cjs +51 -0
- package/dist/chunk-LK6SQH2G.cjs +30 -0
- package/dist/chunk-LPV5CN2K.js +58 -0
- package/dist/chunk-LTE5NG4D.js +53 -0
- package/dist/chunk-MF7CJVIZ.js +40 -0
- package/dist/chunk-MIYA7TNR.cjs +123 -0
- package/dist/chunk-MJCAXASI.js +123 -0
- package/dist/chunk-OM2UFTGS.cjs +47 -0
- package/dist/chunk-ONBH74ZV.cjs +90 -0
- package/dist/chunk-OXLQ7QVL.cjs +40 -0
- package/dist/chunk-P6Z5XFDS.js +73 -0
- package/dist/chunk-QZ5GS6HW.cjs +46 -0
- package/dist/chunk-S7IVHOA6.js +75 -0
- package/dist/chunk-SUSAPI5W.cjs +142 -0
- package/dist/chunk-TMW3XKKJ.js +34 -0
- package/dist/chunk-UDIG7332.js +159 -0
- package/dist/chunk-VLNDEVKS.js +102 -0
- package/dist/chunk-VXZ4RKJI.js +36 -0
- package/dist/chunk-XAQGZ374.js +197 -0
- package/dist/chunk-YPPPGGLA.cjs +99 -0
- package/dist/chunk-ZBLQV6UO.cjs +73 -0
- package/dist/chunk-ZFQZWXOI.cjs +75 -0
- package/dist/context-compaction/index.cjs +8 -0
- package/dist/context-compaction/index.d.cts +77 -0
- package/dist/context-compaction/index.d.ts +77 -0
- package/dist/context-compaction/index.js +8 -0
- package/dist/diff/index.cjs +9 -0
- package/dist/diff/index.d.cts +72 -0
- package/dist/diff/index.d.ts +72 -0
- package/dist/diff/index.js +9 -0
- package/dist/edit/index.cjs +10 -0
- package/dist/edit/index.d.cts +53 -0
- package/dist/edit/index.d.ts +53 -0
- package/dist/edit/index.js +10 -0
- package/dist/glob/index.cjs +10 -0
- package/dist/glob/index.d.cts +47 -0
- package/dist/glob/index.d.ts +47 -0
- package/dist/glob/index.js +10 -0
- package/dist/grep/index.cjs +10 -0
- package/dist/grep/index.d.cts +50 -0
- package/dist/grep/index.d.ts +50 -0
- package/dist/grep/index.js +10 -0
- package/dist/http-request/index.cjs +8 -0
- package/dist/http-request/index.d.cts +60 -0
- package/dist/http-request/index.d.ts +60 -0
- package/dist/http-request/index.js +8 -0
- package/dist/index.cjs +133 -0
- package/dist/index.d.cts +23 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +133 -0
- package/dist/lsp/index.cjs +10 -0
- package/dist/lsp/index.d.cts +35 -0
- package/dist/lsp/index.d.ts +35 -0
- package/dist/lsp/index.js +10 -0
- package/dist/memory/index.cjs +9 -0
- package/dist/memory/index.d.cts +63 -0
- package/dist/memory/index.d.ts +63 -0
- package/dist/memory/index.js +9 -0
- package/dist/multi-edit/index.cjs +11 -0
- package/dist/multi-edit/index.d.cts +72 -0
- package/dist/multi-edit/index.d.ts +72 -0
- package/dist/multi-edit/index.js +11 -0
- package/dist/read/index.cjs +10 -0
- package/dist/read/index.d.cts +67 -0
- package/dist/read/index.d.ts +67 -0
- package/dist/read/index.js +10 -0
- package/dist/sleep/index.cjs +8 -0
- package/dist/sleep/index.d.cts +60 -0
- package/dist/sleep/index.d.ts +60 -0
- package/dist/sleep/index.js +8 -0
- package/dist/task-create/index.cjs +9 -0
- package/dist/task-create/index.d.cts +19 -0
- package/dist/task-create/index.d.ts +19 -0
- package/dist/task-create/index.js +9 -0
- package/dist/task-get/index.cjs +9 -0
- package/dist/task-get/index.d.cts +15 -0
- package/dist/task-get/index.d.ts +15 -0
- package/dist/task-get/index.js +9 -0
- package/dist/task-list/index.cjs +9 -0
- package/dist/task-list/index.d.cts +11 -0
- package/dist/task-list/index.d.ts +11 -0
- package/dist/task-list/index.js +9 -0
- package/dist/task-update/index.cjs +9 -0
- package/dist/task-update/index.d.cts +31 -0
- package/dist/task-update/index.d.ts +31 -0
- package/dist/task-update/index.js +9 -0
- package/dist/tool-search/index.cjs +8 -0
- package/dist/tool-search/index.d.cts +18 -0
- package/dist/tool-search/index.d.ts +18 -0
- package/dist/tool-search/index.js +8 -0
- package/dist/types-3QPDuCXN.d.cts +45 -0
- package/dist/types-3QPDuCXN.d.ts +45 -0
- package/dist/web-fetch/index.cjs +8 -0
- package/dist/web-fetch/index.d.cts +54 -0
- package/dist/web-fetch/index.d.ts +54 -0
- package/dist/web-fetch/index.js +8 -0
- package/dist/web-search/index.cjs +8 -0
- package/dist/web-search/index.d.cts +21 -0
- package/dist/web-search/index.d.ts +21 -0
- package/dist/web-search/index.js +8 -0
- package/dist/write/index.cjs +10 -0
- package/dist/write/index.d.cts +47 -0
- package/dist/write/index.d.ts +47 -0
- package/dist/write/index.js +10 -0
- package/package.json +170 -20
- package/dist/core/index.d.ts +0 -20
- package/dist/core/index.js +0 -1
- package/dist/core/index.js.map +0 -1
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }// src/context-compaction/index.ts
|
|
2
|
+
var _ai = require('ai');
|
|
3
|
+
var _zod = require('zod');
|
|
4
|
+
var parametersSchema = _zod.z.object({
|
|
5
|
+
messages: _zod.z.array(
|
|
6
|
+
_zod.z.object({
|
|
7
|
+
role: _zod.z.string().describe("Message role (system, user, assistant)"),
|
|
8
|
+
content: _zod.z.string().describe("Message content")
|
|
9
|
+
})
|
|
10
|
+
).describe("The conversation messages to compact"),
|
|
11
|
+
maxTokens: _zod.z.number().optional().describe(
|
|
12
|
+
"Target maximum tokens (default: config.maxTokens or 4096)"
|
|
13
|
+
)
|
|
14
|
+
});
|
|
15
|
+
function createContextCompaction(config = {}) {
|
|
16
|
+
return _ai.tool.call(void 0, {
|
|
17
|
+
description: "Compact conversation history by summarizing older messages to reduce context size. Requires a summarize function in config. Returns compacted messages where total chars < maxTokens * 4.",
|
|
18
|
+
inputSchema: _ai.zodSchema.call(void 0, parametersSchema),
|
|
19
|
+
execute: async ({
|
|
20
|
+
messages,
|
|
21
|
+
maxTokens: inputMaxTokens
|
|
22
|
+
}) => {
|
|
23
|
+
const maxTokens = _nullishCoalesce(_nullishCoalesce(inputMaxTokens, () => ( config.maxTokens)), () => ( 4096));
|
|
24
|
+
const charBudget = maxTokens * 4;
|
|
25
|
+
const totalChars = messages.reduce(
|
|
26
|
+
(sum, m) => sum + m.content.length,
|
|
27
|
+
0
|
|
28
|
+
);
|
|
29
|
+
if (totalChars <= charBudget) {
|
|
30
|
+
return JSON.stringify({
|
|
31
|
+
compacted: false,
|
|
32
|
+
messages,
|
|
33
|
+
reason: "Already within token budget"
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
if (!config.summarize) {
|
|
37
|
+
return "Error [context-compaction]: No summarize function configured. Provide a summarize callback in the tool config.";
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
const summary = await config.summarize(messages);
|
|
41
|
+
const compactedMessages = [{ role: "system", content: summary }];
|
|
42
|
+
return JSON.stringify({
|
|
43
|
+
compacted: true,
|
|
44
|
+
messages: compactedMessages,
|
|
45
|
+
originalCount: messages.length
|
|
46
|
+
});
|
|
47
|
+
} catch (error) {
|
|
48
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
49
|
+
return `Error [context-compaction]: Summarization failed: ${msg}`;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
var contextCompaction = createContextCompaction();
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
exports.createContextCompaction = createContextCompaction; exports.contextCompaction = contextCompaction;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
// src/shared/edit-helpers.ts
|
|
2
|
+
var LEFT_SINGLE_CURLY_QUOTE = "\u2018";
|
|
3
|
+
var RIGHT_SINGLE_CURLY_QUOTE = "\u2019";
|
|
4
|
+
var LEFT_DOUBLE_CURLY_QUOTE = "\u201C";
|
|
5
|
+
var RIGHT_DOUBLE_CURLY_QUOTE = "\u201D";
|
|
6
|
+
function normalizeQuotes(str) {
|
|
7
|
+
return str.replaceAll(LEFT_SINGLE_CURLY_QUOTE, "'").replaceAll(RIGHT_SINGLE_CURLY_QUOTE, "'").replaceAll(LEFT_DOUBLE_CURLY_QUOTE, '"').replaceAll(RIGHT_DOUBLE_CURLY_QUOTE, '"');
|
|
8
|
+
}
|
|
9
|
+
function findActualString(fileContent, searchString) {
|
|
10
|
+
if (fileContent.includes(searchString)) {
|
|
11
|
+
return searchString;
|
|
12
|
+
}
|
|
13
|
+
const normalizedSearch = normalizeQuotes(searchString);
|
|
14
|
+
const normalizedFile = normalizeQuotes(fileContent);
|
|
15
|
+
const searchIndex = normalizedFile.indexOf(normalizedSearch);
|
|
16
|
+
if (searchIndex !== -1) {
|
|
17
|
+
return fileContent.substring(
|
|
18
|
+
searchIndex,
|
|
19
|
+
searchIndex + searchString.length
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
function preserveQuoteStyle(oldString, actualOldString, newString) {
|
|
25
|
+
if (oldString === actualOldString) {
|
|
26
|
+
return newString;
|
|
27
|
+
}
|
|
28
|
+
const hasDoubleQuotes = actualOldString.includes(LEFT_DOUBLE_CURLY_QUOTE) || actualOldString.includes(RIGHT_DOUBLE_CURLY_QUOTE);
|
|
29
|
+
const hasSingleQuotes = actualOldString.includes(LEFT_SINGLE_CURLY_QUOTE) || actualOldString.includes(RIGHT_SINGLE_CURLY_QUOTE);
|
|
30
|
+
if (!hasDoubleQuotes && !hasSingleQuotes) {
|
|
31
|
+
return newString;
|
|
32
|
+
}
|
|
33
|
+
let result = newString;
|
|
34
|
+
if (hasDoubleQuotes) {
|
|
35
|
+
result = applyCurlyDoubleQuotes(result);
|
|
36
|
+
}
|
|
37
|
+
if (hasSingleQuotes) {
|
|
38
|
+
result = applyCurlySingleQuotes(result);
|
|
39
|
+
}
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
function applyEditToFile(originalContent, oldString, newString, replaceAll = false) {
|
|
43
|
+
const f = replaceAll ? (content, search, replace) => content.replaceAll(search, () => replace) : (content, search, replace) => content.replace(search, () => replace);
|
|
44
|
+
if (newString !== "") {
|
|
45
|
+
return f(originalContent, oldString, newString);
|
|
46
|
+
}
|
|
47
|
+
const stripTrailingNewline = !oldString.endsWith("\n") && originalContent.includes(oldString + "\n");
|
|
48
|
+
return stripTrailingNewline ? f(originalContent, oldString + "\n", newString) : f(originalContent, oldString, newString);
|
|
49
|
+
}
|
|
50
|
+
function isOpeningContext(chars, index) {
|
|
51
|
+
if (index === 0) {
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
const prev = chars[index - 1];
|
|
55
|
+
return prev === " " || prev === " " || prev === "\n" || prev === "\r" || prev === "(" || prev === "[" || prev === "{" || prev === "\u2014" || // em dash
|
|
56
|
+
prev === "\u2013";
|
|
57
|
+
}
|
|
58
|
+
function applyCurlyDoubleQuotes(str) {
|
|
59
|
+
const chars = [...str];
|
|
60
|
+
const result = [];
|
|
61
|
+
for (let i = 0; i < chars.length; i++) {
|
|
62
|
+
if (chars[i] === '"') {
|
|
63
|
+
result.push(
|
|
64
|
+
isOpeningContext(chars, i) ? LEFT_DOUBLE_CURLY_QUOTE : RIGHT_DOUBLE_CURLY_QUOTE
|
|
65
|
+
);
|
|
66
|
+
} else {
|
|
67
|
+
result.push(chars[i]);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return result.join("");
|
|
71
|
+
}
|
|
72
|
+
function applyCurlySingleQuotes(str) {
|
|
73
|
+
const chars = [...str];
|
|
74
|
+
const result = [];
|
|
75
|
+
for (let i = 0; i < chars.length; i++) {
|
|
76
|
+
if (chars[i] === "'") {
|
|
77
|
+
const prev = i > 0 ? chars[i - 1] : void 0;
|
|
78
|
+
const next = i < chars.length - 1 ? chars[i + 1] : void 0;
|
|
79
|
+
const prevIsLetter = prev !== void 0 && new RegExp("\\p{L}", "u").test(prev);
|
|
80
|
+
const nextIsLetter = next !== void 0 && new RegExp("\\p{L}", "u").test(next);
|
|
81
|
+
if (prevIsLetter && nextIsLetter) {
|
|
82
|
+
result.push(RIGHT_SINGLE_CURLY_QUOTE);
|
|
83
|
+
} else {
|
|
84
|
+
result.push(
|
|
85
|
+
isOpeningContext(chars, i) ? LEFT_SINGLE_CURLY_QUOTE : RIGHT_SINGLE_CURLY_QUOTE
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
} else {
|
|
89
|
+
result.push(chars[i]);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return result.join("");
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export {
|
|
96
|
+
findActualString,
|
|
97
|
+
preserveQuoteStyle,
|
|
98
|
+
applyEditToFile
|
|
99
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// src/ask-user/index.ts
|
|
2
|
+
import { tool } from "ai";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
function createAskUser(config = {}) {
|
|
5
|
+
return tool({
|
|
6
|
+
description: "Ask the user a question and wait for their response. Use this when you need clarification, confirmation, or additional information from the user before proceeding.",
|
|
7
|
+
inputSchema: z.object({
|
|
8
|
+
question: z.string().describe("The question to ask the user"),
|
|
9
|
+
options: z.array(z.string()).optional().describe("Optional list of suggested response options")
|
|
10
|
+
}),
|
|
11
|
+
execute: async ({ question, options }) => {
|
|
12
|
+
if (!config.onQuestion) {
|
|
13
|
+
return "Error [ask-user]: No onQuestion callback configured. Provide an onQuestion function in the tool config to enable user interaction.";
|
|
14
|
+
}
|
|
15
|
+
try {
|
|
16
|
+
const response = await config.onQuestion(question, options);
|
|
17
|
+
return response;
|
|
18
|
+
} catch (error) {
|
|
19
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
20
|
+
return `Error [ask-user]: Failed to get user response: ${msg}`;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
var askUser = createAskUser();
|
|
26
|
+
|
|
27
|
+
export {
|
|
28
|
+
createAskUser,
|
|
29
|
+
askUser
|
|
30
|
+
};
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }
|
|
2
|
+
|
|
3
|
+
var _chunkMIYA7TNRcjs = require('./chunk-MIYA7TNR.cjs');
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
var _chunkQZ5GS6HWcjs = require('./chunk-QZ5GS6HW.cjs');
|
|
8
|
+
|
|
9
|
+
// src/grep/index.ts
|
|
10
|
+
var _promises = require('fs/promises');
|
|
11
|
+
var _ai = require('ai');
|
|
12
|
+
var _zod = require('zod');
|
|
13
|
+
var VCS_DIRS = [".git", ".svn", ".hg", ".bzr", ".jj", ".sl"];
|
|
14
|
+
var DEFAULT_HEAD_LIMIT = 250;
|
|
15
|
+
function applyHeadLimit(items, limit, offset = 0) {
|
|
16
|
+
if (limit === 0) return { items: items.slice(offset), appliedLimit: void 0 };
|
|
17
|
+
const cap = _nullishCoalesce(limit, () => ( DEFAULT_HEAD_LIMIT));
|
|
18
|
+
const sliced = items.slice(offset, offset + cap);
|
|
19
|
+
const truncated = items.length - offset > cap;
|
|
20
|
+
return { items: sliced, appliedLimit: truncated ? cap : void 0 };
|
|
21
|
+
}
|
|
22
|
+
function truncationSuffix(appliedLimit, offset) {
|
|
23
|
+
const parts = [];
|
|
24
|
+
if (appliedLimit !== void 0) parts.push(`limit: ${appliedLimit}`);
|
|
25
|
+
if (offset > 0) parts.push(`offset: ${offset}`);
|
|
26
|
+
return parts.length > 0 ? `
|
|
27
|
+
|
|
28
|
+
[Results truncated. ${parts.join(", ")}]` : "";
|
|
29
|
+
}
|
|
30
|
+
function relativizeLine(line, baseCwd, last = false) {
|
|
31
|
+
const idx = last ? line.lastIndexOf(":") : line.indexOf(":");
|
|
32
|
+
if (idx > 0) {
|
|
33
|
+
return _chunkQZ5GS6HWcjs.toRelativePath.call(void 0, line.substring(0, idx), baseCwd) + line.substring(idx);
|
|
34
|
+
}
|
|
35
|
+
return line;
|
|
36
|
+
}
|
|
37
|
+
function parseGlobPatterns(globFilter) {
|
|
38
|
+
const patterns = [];
|
|
39
|
+
for (const raw of globFilter.split(/\s+/)) {
|
|
40
|
+
if (raw.includes("{") && raw.includes("}")) {
|
|
41
|
+
patterns.push(raw);
|
|
42
|
+
} else {
|
|
43
|
+
patterns.push(...raw.split(",").filter(Boolean));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return patterns;
|
|
47
|
+
}
|
|
48
|
+
function createGrep(config = {}) {
|
|
49
|
+
const cwd = _nullishCoalesce(config.cwd, () => ( process.cwd()));
|
|
50
|
+
return _ai.tool.call(void 0, {
|
|
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
|
+
inputSchema: _zod.z.object({
|
|
53
|
+
pattern: _zod.z.string().describe("The regular expression pattern to search for in file contents"),
|
|
54
|
+
path: _zod.z.string().optional().describe("File or directory to search in (rg PATH). Defaults to current working directory."),
|
|
55
|
+
glob: _zod.z.string().optional().describe('Glob pattern to filter files (e.g. "*.js", "*.{ts,tsx}") - maps to rg --glob'),
|
|
56
|
+
output_mode: _zod.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": _zod.z.number().optional().describe('Number of lines to show before each match (rg -B). Requires output_mode: "content", ignored otherwise.'),
|
|
58
|
+
"-A": _zod.z.number().optional().describe('Number of lines to show after each match (rg -A). Requires output_mode: "content", ignored otherwise.'),
|
|
59
|
+
"-C": _zod.z.number().optional().describe("Alias for context."),
|
|
60
|
+
context: _zod.z.number().optional().describe('Number of lines to show before and after each match (rg -C). Requires output_mode: "content", ignored otherwise.'),
|
|
61
|
+
"-n": _zod.z.boolean().optional().describe('Show line numbers in output (rg -n). Requires output_mode: "content", ignored otherwise. Defaults to true.'),
|
|
62
|
+
"-i": _zod.z.boolean().optional().describe("Case insensitive search (rg -i)"),
|
|
63
|
+
type: _zod.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: _zod.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: _zod.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: _zod.z.boolean().optional().describe("Enable multiline mode where . matches newlines and patterns can span lines (rg -U --multiline-dotall). Default: false.")
|
|
67
|
+
}),
|
|
68
|
+
execute: async (input) => {
|
|
69
|
+
try {
|
|
70
|
+
const {
|
|
71
|
+
pattern,
|
|
72
|
+
path,
|
|
73
|
+
glob: globFilter,
|
|
74
|
+
type: typeFilter,
|
|
75
|
+
output_mode: outputMode = "files_with_matches",
|
|
76
|
+
"-B": ctxBefore,
|
|
77
|
+
"-A": ctxAfter,
|
|
78
|
+
"-C": ctxC,
|
|
79
|
+
context: ctxAlias,
|
|
80
|
+
"-n": showLineNumbers = true,
|
|
81
|
+
"-i": caseInsensitive = false,
|
|
82
|
+
head_limit: headLimit,
|
|
83
|
+
offset = 0,
|
|
84
|
+
multiline = false
|
|
85
|
+
} = input;
|
|
86
|
+
const absolutePath = path ? _chunkQZ5GS6HWcjs.expandPath.call(void 0, path, cwd) : cwd;
|
|
87
|
+
const args = ["--hidden"];
|
|
88
|
+
for (const dir of VCS_DIRS) args.push("--glob", `!${dir}`);
|
|
89
|
+
args.push("--max-columns", "500");
|
|
90
|
+
if (multiline) args.push("-U", "--multiline-dotall");
|
|
91
|
+
if (caseInsensitive) args.push("-i");
|
|
92
|
+
if (outputMode === "files_with_matches") args.push("-l");
|
|
93
|
+
else if (outputMode === "count") args.push("-c");
|
|
94
|
+
if (showLineNumbers && outputMode === "content") args.push("-n");
|
|
95
|
+
if (outputMode === "content") {
|
|
96
|
+
if (ctxAlias !== void 0) args.push("-C", ctxAlias.toString());
|
|
97
|
+
else if (ctxC !== void 0) args.push("-C", ctxC.toString());
|
|
98
|
+
else {
|
|
99
|
+
if (ctxBefore !== void 0) args.push("-B", ctxBefore.toString());
|
|
100
|
+
if (ctxAfter !== void 0) args.push("-A", ctxAfter.toString());
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (pattern.startsWith("-")) args.push("-e", pattern);
|
|
104
|
+
else args.push(pattern);
|
|
105
|
+
if (typeFilter) args.push("--type", typeFilter);
|
|
106
|
+
if (globFilter) {
|
|
107
|
+
for (const gp of parseGlobPatterns(globFilter)) args.push("--glob", gp);
|
|
108
|
+
}
|
|
109
|
+
const results = await _chunkMIYA7TNRcjs.executeRipgrep.call(void 0, args, absolutePath);
|
|
110
|
+
if (results.length === 0) return "No matches found";
|
|
111
|
+
if (outputMode === "content") {
|
|
112
|
+
const { items: items2, appliedLimit: appliedLimit2 } = applyHeadLimit(results, headLimit, offset);
|
|
113
|
+
const lines = items2.map((l) => relativizeLine(l, cwd));
|
|
114
|
+
return lines.join("\n") + truncationSuffix(appliedLimit2, offset);
|
|
115
|
+
}
|
|
116
|
+
if (outputMode === "count") {
|
|
117
|
+
const { items: items2, appliedLimit: appliedLimit2 } = applyHeadLimit(results, headLimit, offset);
|
|
118
|
+
const lines = items2.map((l) => relativizeLine(l, cwd, true));
|
|
119
|
+
let totalMatches = 0;
|
|
120
|
+
let fileCount = 0;
|
|
121
|
+
for (const line of lines) {
|
|
122
|
+
const idx = line.lastIndexOf(":");
|
|
123
|
+
if (idx > 0) {
|
|
124
|
+
const n = parseInt(line.substring(idx + 1), 10);
|
|
125
|
+
if (!isNaN(n)) {
|
|
126
|
+
totalMatches += n;
|
|
127
|
+
fileCount += 1;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return lines.join("\n") + `
|
|
132
|
+
|
|
133
|
+
Total: ${totalMatches} matches in ${fileCount} files` + truncationSuffix(appliedLimit2, offset);
|
|
134
|
+
}
|
|
135
|
+
const stats = await Promise.allSettled(results.map((f) => _promises.stat.call(void 0, f)));
|
|
136
|
+
const sorted = results.map((fp, i) => {
|
|
137
|
+
const r = stats[i];
|
|
138
|
+
const mt = r.status === "fulfilled" ? _nullishCoalesce(r.value.mtimeMs, () => ( 0)) : 0;
|
|
139
|
+
return [fp, mt];
|
|
140
|
+
}).sort((a, b) => {
|
|
141
|
+
const d = b[1] - a[1];
|
|
142
|
+
return d !== 0 ? d : a[0].localeCompare(b[0]);
|
|
143
|
+
}).map((e) => e[0]);
|
|
144
|
+
const { items, appliedLimit } = applyHeadLimit(sorted, headLimit, offset);
|
|
145
|
+
const relative = items.map((f) => _chunkQZ5GS6HWcjs.toRelativePath.call(void 0, f, cwd));
|
|
146
|
+
return relative.join("\n") + truncationSuffix(appliedLimit, offset);
|
|
147
|
+
} catch (error) {
|
|
148
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
149
|
+
return `Error [grep]: Failed to search: ${msg}`;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
var grep = createGrep();
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
exports.createGrep = createGrep; exports.grep = grep;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
var _chunkL5JH4I77cjs = require('./chunk-L5JH4I77.cjs');
|
|
5
|
+
|
|
6
|
+
// src/task-list/index.ts
|
|
7
|
+
var _ai = require('ai');
|
|
8
|
+
var _zod = require('zod');
|
|
9
|
+
var _path = require('path');
|
|
10
|
+
function createTaskList(config = {}) {
|
|
11
|
+
const cwd = _nullishCoalesce(config.cwd, () => ( process.cwd()));
|
|
12
|
+
const tasksFile = _nullishCoalesce(config.tasksFile, () => ( _path.join.call(void 0, cwd, ".agentool", "tasks.json")));
|
|
13
|
+
return _ai.tool.call(void 0, {
|
|
14
|
+
description: "List all tasks with their status, owner, and dependencies.",
|
|
15
|
+
inputSchema: _zod.z.object({}),
|
|
16
|
+
execute: async () => {
|
|
17
|
+
try {
|
|
18
|
+
const tasks = await _chunkL5JH4I77cjs.loadTasks.call(void 0, tasksFile);
|
|
19
|
+
const visible = tasks.filter((t) => t.status !== "deleted");
|
|
20
|
+
if (visible.length === 0) return "No tasks found.";
|
|
21
|
+
return visible.map(_chunkL5JH4I77cjs.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
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
exports.createTaskList = createTaskList; exports.taskList = taskList;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import {
|
|
2
|
+
executeRipgrep
|
|
3
|
+
} from "./chunk-MJCAXASI.js";
|
|
4
|
+
import {
|
|
5
|
+
expandPath
|
|
6
|
+
} from "./chunk-I3ONDY7P.js";
|
|
7
|
+
|
|
8
|
+
// src/glob/index.ts
|
|
9
|
+
import { tool } from "ai";
|
|
10
|
+
import { z } from "zod";
|
|
11
|
+
|
|
12
|
+
// src/shared/glob.ts
|
|
13
|
+
import { isAbsolute, join, basename, dirname, sep } from "path";
|
|
14
|
+
function extractGlobBaseDirectory(pattern) {
|
|
15
|
+
const globChars = /[*?[{]/;
|
|
16
|
+
const match = pattern.match(globChars);
|
|
17
|
+
if (!match || match.index === void 0) {
|
|
18
|
+
const dir = dirname(pattern);
|
|
19
|
+
const file = basename(pattern);
|
|
20
|
+
return { baseDir: dir, relativePattern: file };
|
|
21
|
+
}
|
|
22
|
+
const staticPrefix = pattern.slice(0, match.index);
|
|
23
|
+
const lastSepIndex = Math.max(
|
|
24
|
+
staticPrefix.lastIndexOf("/"),
|
|
25
|
+
staticPrefix.lastIndexOf(sep)
|
|
26
|
+
);
|
|
27
|
+
if (lastSepIndex === -1) {
|
|
28
|
+
return { baseDir: "", relativePattern: pattern };
|
|
29
|
+
}
|
|
30
|
+
let baseDir = staticPrefix.slice(0, lastSepIndex);
|
|
31
|
+
const relativePattern = pattern.slice(lastSepIndex + 1);
|
|
32
|
+
if (baseDir === "" && lastSepIndex === 0) {
|
|
33
|
+
baseDir = "/";
|
|
34
|
+
}
|
|
35
|
+
return { baseDir, relativePattern };
|
|
36
|
+
}
|
|
37
|
+
async function glob(pattern, cwd, options) {
|
|
38
|
+
const limit = options?.limit ?? 100;
|
|
39
|
+
const offset = options?.offset ?? 0;
|
|
40
|
+
let searchDir = cwd;
|
|
41
|
+
let searchPattern = pattern;
|
|
42
|
+
if (isAbsolute(pattern)) {
|
|
43
|
+
const { baseDir, relativePattern } = extractGlobBaseDirectory(pattern);
|
|
44
|
+
if (baseDir) {
|
|
45
|
+
searchDir = baseDir;
|
|
46
|
+
searchPattern = relativePattern;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const args = [
|
|
50
|
+
"--files",
|
|
51
|
+
"--glob",
|
|
52
|
+
searchPattern,
|
|
53
|
+
"--sort=modified",
|
|
54
|
+
"--hidden",
|
|
55
|
+
"--no-ignore"
|
|
56
|
+
];
|
|
57
|
+
const allPaths = await executeRipgrep(args, searchDir, {
|
|
58
|
+
signal: options?.signal
|
|
59
|
+
});
|
|
60
|
+
const absolutePaths = allPaths.map(
|
|
61
|
+
(p) => isAbsolute(p) ? p : join(searchDir, p)
|
|
62
|
+
);
|
|
63
|
+
const truncated = absolutePaths.length > offset + limit;
|
|
64
|
+
const files = absolutePaths.slice(offset, offset + limit);
|
|
65
|
+
return { files, truncated };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// src/glob/index.ts
|
|
69
|
+
function createGlob(config = {}) {
|
|
70
|
+
const cwd = config.cwd ?? process.cwd();
|
|
71
|
+
return tool({
|
|
72
|
+
description: 'Find files matching a glob pattern. Returns absolute file paths sorted by modification time (newest first). Supports patterns like "**/*.ts", "src/**/*.js", or "*.json".',
|
|
73
|
+
inputSchema: z.object({
|
|
74
|
+
pattern: z.string().describe("Glob pattern to match files against"),
|
|
75
|
+
path: z.string().optional().describe("Directory to search in. Defaults to the working directory.")
|
|
76
|
+
}),
|
|
77
|
+
execute: async ({ pattern, path }) => {
|
|
78
|
+
try {
|
|
79
|
+
const searchDir = path ? expandPath(path, cwd) : cwd;
|
|
80
|
+
const { files, truncated } = await glob(pattern, searchDir);
|
|
81
|
+
if (files.length === 0) {
|
|
82
|
+
return "No files found";
|
|
83
|
+
}
|
|
84
|
+
const header = truncated ? `Found ${files.length}+ files (results truncated)` : `Found ${files.length} files`;
|
|
85
|
+
return `${header}
|
|
86
|
+
${files.join("\n")}`;
|
|
87
|
+
} catch (error) {
|
|
88
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
89
|
+
return `Error [glob]: Failed to search for files: ${message}`;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
var glob2 = createGlob();
|
|
95
|
+
|
|
96
|
+
export {
|
|
97
|
+
createGlob,
|
|
98
|
+
glob2 as glob
|
|
99
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// src/shared/path.ts
|
|
2
|
+
import { homedir } from "os";
|
|
3
|
+
import { isAbsolute, join, normalize, relative, resolve } from "path";
|
|
4
|
+
function expandPath(inputPath, baseDir) {
|
|
5
|
+
const actualBaseDir = baseDir ?? process.cwd();
|
|
6
|
+
if (typeof inputPath !== "string") {
|
|
7
|
+
throw new TypeError(
|
|
8
|
+
`Path must be a string, received ${typeof inputPath}`
|
|
9
|
+
);
|
|
10
|
+
}
|
|
11
|
+
if (typeof actualBaseDir !== "string") {
|
|
12
|
+
throw new TypeError(
|
|
13
|
+
`Base directory must be a string, received ${typeof actualBaseDir}`
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
if (inputPath.includes("\0") || actualBaseDir.includes("\0")) {
|
|
17
|
+
throw new Error("Path contains null bytes");
|
|
18
|
+
}
|
|
19
|
+
const trimmed = inputPath.trim();
|
|
20
|
+
if (!trimmed) {
|
|
21
|
+
return normalize(actualBaseDir);
|
|
22
|
+
}
|
|
23
|
+
if (trimmed === "~") {
|
|
24
|
+
return homedir();
|
|
25
|
+
}
|
|
26
|
+
if (trimmed.startsWith("~/")) {
|
|
27
|
+
return join(homedir(), trimmed.slice(2));
|
|
28
|
+
}
|
|
29
|
+
if (isAbsolute(trimmed)) {
|
|
30
|
+
return normalize(trimmed);
|
|
31
|
+
}
|
|
32
|
+
return resolve(actualBaseDir, trimmed);
|
|
33
|
+
}
|
|
34
|
+
function toRelativePath(absolutePath, baseDir) {
|
|
35
|
+
const rel = relative(baseDir ?? process.cwd(), absolutePath);
|
|
36
|
+
return rel.startsWith("..") ? absolutePath : rel;
|
|
37
|
+
}
|
|
38
|
+
function containsPathTraversal(inputPath) {
|
|
39
|
+
return /(?:^|[\\/])\.\.(?:[\\/]|$)/.test(inputPath);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export {
|
|
43
|
+
expandPath,
|
|
44
|
+
toRelativePath,
|
|
45
|
+
containsPathTraversal
|
|
46
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }// src/http-request/index.ts
|
|
2
|
+
var _ai = require('ai');
|
|
3
|
+
var _zod = require('zod');
|
|
4
|
+
function createHttpRequest(config = {}) {
|
|
5
|
+
return _ai.tool.call(void 0, {
|
|
6
|
+
description: "Make an HTTP request to a URL. Returns the response status, headers, and body. Use this for API interactions, webhook calls, and service health checks. Unlike web-fetch, this returns raw response data without markdown conversion.",
|
|
7
|
+
inputSchema: _zod.z.object({
|
|
8
|
+
method: _zod.z.enum(["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD"]).describe("HTTP method"),
|
|
9
|
+
url: _zod.z.string().describe("The URL to send the request to"),
|
|
10
|
+
headers: _zod.z.record(_zod.z.string()).optional().describe("Request headers as key-value pairs"),
|
|
11
|
+
body: _zod.z.string().optional().describe("Request body (for POST, PUT, PATCH)"),
|
|
12
|
+
timeout: _zod.z.number().optional().describe("Request timeout in milliseconds (default: 30000)")
|
|
13
|
+
}),
|
|
14
|
+
execute: async ({ method, url, headers, body, timeout }) => {
|
|
15
|
+
try {
|
|
16
|
+
const timeoutMs = _nullishCoalesce(_nullishCoalesce(timeout, () => ( config.timeout)), () => ( 3e4));
|
|
17
|
+
const controller = new AbortController();
|
|
18
|
+
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
19
|
+
const mergedHeaders = { ...config.defaultHeaders, ...headers };
|
|
20
|
+
const response = await fetch(url, {
|
|
21
|
+
method,
|
|
22
|
+
headers: mergedHeaders,
|
|
23
|
+
body: ["POST", "PUT", "PATCH"].includes(method) ? body : void 0,
|
|
24
|
+
signal: controller.signal
|
|
25
|
+
});
|
|
26
|
+
clearTimeout(timeoutId);
|
|
27
|
+
const responseBody = await response.text();
|
|
28
|
+
const responseHeaders = {};
|
|
29
|
+
response.headers.forEach((value, key) => {
|
|
30
|
+
responseHeaders[key] = value;
|
|
31
|
+
});
|
|
32
|
+
return JSON.stringify(
|
|
33
|
+
{
|
|
34
|
+
status: response.status,
|
|
35
|
+
statusText: response.statusText,
|
|
36
|
+
headers: responseHeaders,
|
|
37
|
+
body: responseBody
|
|
38
|
+
},
|
|
39
|
+
null,
|
|
40
|
+
2
|
|
41
|
+
);
|
|
42
|
+
} catch (error) {
|
|
43
|
+
const effectiveTimeout = _nullishCoalesce(_nullishCoalesce(timeout, () => ( config.timeout)), () => ( 3e4));
|
|
44
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
45
|
+
return `Error [http-request]: Request timed out after ${effectiveTimeout}ms for ${method} ${url}. Try increasing the timeout or verify the server is responsive.`;
|
|
46
|
+
}
|
|
47
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
48
|
+
return `Error [http-request]: ${method} ${url} failed: ${msg}. Verify the URL is correct and the server is reachable.`;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
var httpRequest = createHttpRequest();
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
exports.createHttpRequest = createHttpRequest; exports.httpRequest = httpRequest;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }// src/tool-search/index.ts
|
|
2
|
+
var _ai = require('ai');
|
|
3
|
+
var _zod = require('zod');
|
|
4
|
+
function createToolSearch(config = {}) {
|
|
5
|
+
return _ai.tool.call(void 0, {
|
|
6
|
+
description: "Search for available tools by name or keyword. Returns matching tool names and descriptions.",
|
|
7
|
+
inputSchema: _zod.z.object({
|
|
8
|
+
query: _zod.z.string().describe("Query to find tools by name or keyword"),
|
|
9
|
+
max_results: _zod.z.number().optional().default(5).describe("Max results to return")
|
|
10
|
+
}),
|
|
11
|
+
execute: async ({ query, max_results }) => {
|
|
12
|
+
try {
|
|
13
|
+
const registry = _nullishCoalesce(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
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
exports.createToolSearch = createToolSearch; exports.toolSearch = toolSearch;
|