fourmis-agents-sdk 0.3.0 → 0.4.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/dist/agent-loop.d.ts +21 -3
- package/dist/agent-loop.d.ts.map +1 -1
- package/dist/agent-loop.js +294 -90
- package/dist/agents/index.js +2798 -1857
- package/dist/agents/task-manager.js +15 -0
- package/dist/agents/tools.d.ts.map +1 -1
- package/dist/agents/tools.js +2798 -1857
- package/dist/agents/types.d.ts +4 -0
- package/dist/agents/types.d.ts.map +1 -1
- package/dist/api.d.ts +8 -5
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +2394 -886
- package/dist/auth/gemini-oauth.js +15 -0
- package/dist/auth/login-openai.js +15 -0
- package/dist/auth/openai-oauth.js +15 -0
- package/dist/hooks.d.ts +19 -1
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +42 -2
- package/dist/index.d.ts +10 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2407 -887
- package/dist/mcp/client.d.ts +7 -0
- package/dist/mcp/client.d.ts.map +1 -1
- package/dist/mcp/client.js +146 -12
- package/dist/mcp/index.js +146 -12
- package/dist/mcp/server.js +15 -0
- package/dist/mcp/types.d.ts +19 -1
- package/dist/mcp/types.d.ts.map +1 -1
- package/dist/memory/index.js +15 -0
- package/dist/memory/memory-handler.js +15 -0
- package/dist/permissions.d.ts.map +1 -1
- package/dist/permissions.js +22 -3
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js +56 -2
- package/dist/providers/gemini.js +15 -0
- package/dist/providers/openai.js +15 -0
- package/dist/providers/registry.js +56 -2
- package/dist/providers/types.d.ts +4 -1
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/query.d.ts +21 -2
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +84 -1
- package/dist/settings.js +15 -0
- package/dist/skills/frontmatter.d.ts +15 -0
- package/dist/skills/frontmatter.d.ts.map +1 -0
- package/dist/skills/frontmatter.js +66 -0
- package/dist/skills/index.d.ts +8 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +326 -0
- package/dist/skills/skills.d.ts +94 -0
- package/dist/skills/skills.d.ts.map +1 -0
- package/dist/skills/skills.js +324 -0
- package/dist/tools/ask-user-question.d.ts +7 -0
- package/dist/tools/ask-user-question.d.ts.map +1 -0
- package/dist/tools/ask-user-question.js +63 -0
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +62 -2
- package/dist/tools/config.d.ts +7 -0
- package/dist/tools/config.d.ts.map +1 -0
- package/dist/tools/config.js +129 -0
- package/dist/tools/edit.js +15 -0
- package/dist/tools/exit-plan-mode.d.ts +7 -0
- package/dist/tools/exit-plan-mode.d.ts.map +1 -0
- package/dist/tools/exit-plan-mode.js +49 -0
- package/dist/tools/glob.js +15 -0
- package/dist/tools/grep.js +15 -0
- package/dist/tools/index.d.ts +7 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +521 -9
- package/dist/tools/mcp-resources.js +15 -0
- package/dist/tools/notebook-edit.d.ts +7 -0
- package/dist/tools/notebook-edit.d.ts.map +1 -0
- package/dist/tools/notebook-edit.js +98 -0
- package/dist/tools/presets.d.ts +2 -1
- package/dist/tools/presets.d.ts.map +1 -1
- package/dist/tools/presets.js +37 -4
- package/dist/tools/read.d.ts.map +1 -1
- package/dist/tools/read.js +27 -1
- package/dist/tools/registry.d.ts +2 -0
- package/dist/tools/registry.d.ts.map +1 -1
- package/dist/tools/registry.js +25 -0
- package/dist/tools/todo-write.d.ts +7 -0
- package/dist/tools/todo-write.d.ts.map +1 -0
- package/dist/tools/todo-write.js +84 -0
- package/dist/tools/web-fetch.d.ts +6 -0
- package/dist/tools/web-fetch.d.ts.map +1 -0
- package/dist/tools/web-fetch.js +100 -0
- package/dist/tools/web-search.d.ts +7 -0
- package/dist/tools/web-search.d.ts.map +1 -0
- package/dist/tools/web-search.js +93 -0
- package/dist/tools/write.js +15 -0
- package/dist/types.d.ts +360 -42
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +15 -0
- package/dist/utils/cost.js +15 -0
- package/dist/utils/session-store.d.ts +1 -1
- package/dist/utils/session-store.d.ts.map +1 -1
- package/dist/utils/session-store.js +64 -2
- package/dist/utils/system-prompt.d.ts +4 -0
- package/dist/utils/system-prompt.d.ts.map +1 -1
- package/dist/utils/system-prompt.js +326 -6
- package/package.json +4 -2
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
8
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
10
|
+
for (let key of __getOwnPropNames(mod))
|
|
11
|
+
if (!__hasOwnProp.call(to, key))
|
|
12
|
+
__defProp(to, key, {
|
|
13
|
+
get: () => mod[key],
|
|
14
|
+
enumerable: true
|
|
15
|
+
});
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __export = (target, all) => {
|
|
19
|
+
for (var name in all)
|
|
20
|
+
__defProp(target, name, {
|
|
21
|
+
get: all[name],
|
|
22
|
+
enumerable: true,
|
|
23
|
+
configurable: true,
|
|
24
|
+
set: (newValue) => all[name] = () => newValue
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
28
|
+
var __require = import.meta.require;
|
|
29
|
+
|
|
30
|
+
// src/skills/frontmatter.ts
|
|
31
|
+
import { parse } from "yaml";
|
|
32
|
+
function normalizeNewlines(value) {
|
|
33
|
+
return value.replace(/\r\n/g, `
|
|
34
|
+
`).replace(/\r/g, `
|
|
35
|
+
`);
|
|
36
|
+
}
|
|
37
|
+
function extractFrontmatter(content) {
|
|
38
|
+
const normalized = normalizeNewlines(content);
|
|
39
|
+
if (!normalized.startsWith("---")) {
|
|
40
|
+
return { yamlString: null, body: normalized };
|
|
41
|
+
}
|
|
42
|
+
const endIndex = normalized.indexOf(`
|
|
43
|
+
---`, 3);
|
|
44
|
+
if (endIndex === -1) {
|
|
45
|
+
return { yamlString: null, body: normalized };
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
yamlString: normalized.slice(4, endIndex),
|
|
49
|
+
body: normalized.slice(endIndex + 4).trim()
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
function parseFrontmatter(content) {
|
|
53
|
+
const { yamlString, body } = extractFrontmatter(content);
|
|
54
|
+
if (!yamlString) {
|
|
55
|
+
return { frontmatter: {}, body };
|
|
56
|
+
}
|
|
57
|
+
const parsed = parse(yamlString);
|
|
58
|
+
return { frontmatter: parsed ?? {}, body };
|
|
59
|
+
}
|
|
60
|
+
function stripFrontmatter(content) {
|
|
61
|
+
return parseFrontmatter(content).body;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// src/skills/skills.ts
|
|
65
|
+
import { existsSync, readdirSync, readFileSync, realpathSync, statSync } from "fs";
|
|
66
|
+
import { homedir } from "os";
|
|
67
|
+
import { basename, dirname, isAbsolute, join, resolve } from "path";
|
|
68
|
+
var MAX_NAME_LENGTH = 64;
|
|
69
|
+
var MAX_DESCRIPTION_LENGTH = 1024;
|
|
70
|
+
var MAX_COMPATIBILITY_LENGTH = 500;
|
|
71
|
+
var CONFIG_DIR_NAME = ".claude";
|
|
72
|
+
function shouldIgnore(name) {
|
|
73
|
+
return name.startsWith(".") || name === "node_modules";
|
|
74
|
+
}
|
|
75
|
+
function validateName(name, parentDirName) {
|
|
76
|
+
const errors = [];
|
|
77
|
+
if (name !== parentDirName) {
|
|
78
|
+
errors.push(`name "${name}" does not match parent directory "${parentDirName}"`);
|
|
79
|
+
}
|
|
80
|
+
if (name.length > MAX_NAME_LENGTH) {
|
|
81
|
+
errors.push(`name exceeds ${MAX_NAME_LENGTH} characters (${name.length})`);
|
|
82
|
+
}
|
|
83
|
+
if (!/^[a-z0-9-]+$/.test(name)) {
|
|
84
|
+
errors.push(`name contains invalid characters (must be lowercase a-z, 0-9, hyphens only)`);
|
|
85
|
+
}
|
|
86
|
+
if (name.startsWith("-") || name.endsWith("-")) {
|
|
87
|
+
errors.push(`name must not start or end with a hyphen`);
|
|
88
|
+
}
|
|
89
|
+
if (name.includes("--")) {
|
|
90
|
+
errors.push(`name must not contain consecutive hyphens`);
|
|
91
|
+
}
|
|
92
|
+
return errors;
|
|
93
|
+
}
|
|
94
|
+
function validateDescription(description) {
|
|
95
|
+
const errors = [];
|
|
96
|
+
if (!description || description.trim() === "") {
|
|
97
|
+
errors.push("description is required");
|
|
98
|
+
} else if (description.length > MAX_DESCRIPTION_LENGTH) {
|
|
99
|
+
errors.push(`description exceeds ${MAX_DESCRIPTION_LENGTH} characters (${description.length})`);
|
|
100
|
+
}
|
|
101
|
+
return errors;
|
|
102
|
+
}
|
|
103
|
+
function validateCompatibility(compatibility) {
|
|
104
|
+
if (!compatibility)
|
|
105
|
+
return [];
|
|
106
|
+
if (compatibility.length > MAX_COMPATIBILITY_LENGTH) {
|
|
107
|
+
return [`compatibility exceeds ${MAX_COMPATIBILITY_LENGTH} characters (${compatibility.length})`];
|
|
108
|
+
}
|
|
109
|
+
return [];
|
|
110
|
+
}
|
|
111
|
+
function loadSkillsFromDir(options) {
|
|
112
|
+
return loadSkillsFromDirInternal(options.dir, options.source, true);
|
|
113
|
+
}
|
|
114
|
+
function loadSkillsFromDirInternal(dir, source, includeRootFiles) {
|
|
115
|
+
const skills = [];
|
|
116
|
+
const diagnostics = [];
|
|
117
|
+
if (!existsSync(dir)) {
|
|
118
|
+
return { skills, diagnostics };
|
|
119
|
+
}
|
|
120
|
+
try {
|
|
121
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
122
|
+
for (const entry of entries) {
|
|
123
|
+
if (shouldIgnore(entry.name)) {
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
const fullPath = join(dir, entry.name);
|
|
127
|
+
let isDirectory = entry.isDirectory();
|
|
128
|
+
let isFile = entry.isFile();
|
|
129
|
+
if (entry.isSymbolicLink()) {
|
|
130
|
+
try {
|
|
131
|
+
const stats = statSync(fullPath);
|
|
132
|
+
isDirectory = stats.isDirectory();
|
|
133
|
+
isFile = stats.isFile();
|
|
134
|
+
} catch {
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (isDirectory) {
|
|
139
|
+
const subResult = loadSkillsFromDirInternal(fullPath, source, false);
|
|
140
|
+
skills.push(...subResult.skills);
|
|
141
|
+
diagnostics.push(...subResult.diagnostics);
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
if (!isFile)
|
|
145
|
+
continue;
|
|
146
|
+
const isRootMd = includeRootFiles && entry.name.endsWith(".md");
|
|
147
|
+
const isSkillMd = !includeRootFiles && entry.name === "SKILL.md";
|
|
148
|
+
if (!isRootMd && !isSkillMd)
|
|
149
|
+
continue;
|
|
150
|
+
const result = loadSkillFromFile(fullPath, source);
|
|
151
|
+
if (result.skill) {
|
|
152
|
+
skills.push(result.skill);
|
|
153
|
+
}
|
|
154
|
+
diagnostics.push(...result.diagnostics);
|
|
155
|
+
}
|
|
156
|
+
} catch {}
|
|
157
|
+
return { skills, diagnostics };
|
|
158
|
+
}
|
|
159
|
+
function loadSkillFromFile(filePath, source) {
|
|
160
|
+
const diagnostics = [];
|
|
161
|
+
try {
|
|
162
|
+
const rawContent = readFileSync(filePath, "utf-8");
|
|
163
|
+
const { frontmatter } = parseFrontmatter(rawContent);
|
|
164
|
+
const skillDir = dirname(filePath);
|
|
165
|
+
const parentDirName = basename(skillDir);
|
|
166
|
+
const descErrors = validateDescription(frontmatter.description);
|
|
167
|
+
for (const error of descErrors) {
|
|
168
|
+
diagnostics.push({ type: "warning", message: error, path: filePath });
|
|
169
|
+
}
|
|
170
|
+
const name = frontmatter.name || parentDirName;
|
|
171
|
+
const nameErrors = validateName(name, parentDirName);
|
|
172
|
+
for (const error of nameErrors) {
|
|
173
|
+
diagnostics.push({ type: "warning", message: error, path: filePath });
|
|
174
|
+
}
|
|
175
|
+
const compatErrors = validateCompatibility(frontmatter.compatibility);
|
|
176
|
+
for (const error of compatErrors) {
|
|
177
|
+
diagnostics.push({ type: "warning", message: error, path: filePath });
|
|
178
|
+
}
|
|
179
|
+
if (!frontmatter.description || frontmatter.description.trim() === "") {
|
|
180
|
+
return { skill: null, diagnostics };
|
|
181
|
+
}
|
|
182
|
+
const allowedToolsRaw = frontmatter["allowed-tools"];
|
|
183
|
+
const allowedTools = allowedToolsRaw ? allowedToolsRaw.split(/\s+/).filter(Boolean) : undefined;
|
|
184
|
+
return {
|
|
185
|
+
skill: {
|
|
186
|
+
name,
|
|
187
|
+
description: frontmatter.description,
|
|
188
|
+
filePath,
|
|
189
|
+
baseDir: skillDir,
|
|
190
|
+
source,
|
|
191
|
+
disableModelInvocation: frontmatter["disable-model-invocation"] === true,
|
|
192
|
+
license: frontmatter.license,
|
|
193
|
+
compatibility: frontmatter.compatibility,
|
|
194
|
+
metadata: frontmatter.metadata,
|
|
195
|
+
allowedTools
|
|
196
|
+
},
|
|
197
|
+
diagnostics
|
|
198
|
+
};
|
|
199
|
+
} catch (error) {
|
|
200
|
+
const message = error instanceof Error ? error.message : "failed to parse skill file";
|
|
201
|
+
diagnostics.push({ type: "warning", message, path: filePath });
|
|
202
|
+
return { skill: null, diagnostics };
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
function normalizePath(input) {
|
|
206
|
+
const trimmed = input.trim();
|
|
207
|
+
if (trimmed === "~")
|
|
208
|
+
return homedir();
|
|
209
|
+
if (trimmed.startsWith("~/"))
|
|
210
|
+
return join(homedir(), trimmed.slice(2));
|
|
211
|
+
if (trimmed.startsWith("~"))
|
|
212
|
+
return join(homedir(), trimmed.slice(1));
|
|
213
|
+
return trimmed;
|
|
214
|
+
}
|
|
215
|
+
function resolveSkillPath(p, cwd) {
|
|
216
|
+
const normalized = normalizePath(p);
|
|
217
|
+
return isAbsolute(normalized) ? normalized : resolve(cwd, normalized);
|
|
218
|
+
}
|
|
219
|
+
function loadSkills(options = {}) {
|
|
220
|
+
const { cwd = process.cwd(), skillPaths = [], includeDefaults = true } = options;
|
|
221
|
+
const skillMap = new Map;
|
|
222
|
+
const realPathSet = new Set;
|
|
223
|
+
const allDiagnostics = [];
|
|
224
|
+
const collisionDiagnostics = [];
|
|
225
|
+
function addSkills(result) {
|
|
226
|
+
allDiagnostics.push(...result.diagnostics);
|
|
227
|
+
for (const skill of result.skills) {
|
|
228
|
+
let realPath;
|
|
229
|
+
try {
|
|
230
|
+
realPath = realpathSync(skill.filePath);
|
|
231
|
+
} catch {
|
|
232
|
+
realPath = skill.filePath;
|
|
233
|
+
}
|
|
234
|
+
if (realPathSet.has(realPath))
|
|
235
|
+
continue;
|
|
236
|
+
const existing = skillMap.get(skill.name);
|
|
237
|
+
if (existing) {
|
|
238
|
+
collisionDiagnostics.push({
|
|
239
|
+
type: "collision",
|
|
240
|
+
message: `name "${skill.name}" collision`,
|
|
241
|
+
path: skill.filePath,
|
|
242
|
+
collision: {
|
|
243
|
+
resourceType: "skill",
|
|
244
|
+
name: skill.name,
|
|
245
|
+
winnerPath: existing.filePath,
|
|
246
|
+
loserPath: skill.filePath
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
} else {
|
|
250
|
+
skillMap.set(skill.name, skill);
|
|
251
|
+
realPathSet.add(realPath);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
if (includeDefaults) {
|
|
256
|
+
const userSkillsDir = join(homedir(), CONFIG_DIR_NAME, "skills");
|
|
257
|
+
const projectSkillsDir = resolve(cwd, CONFIG_DIR_NAME, "skills");
|
|
258
|
+
addSkills(loadSkillsFromDirInternal(userSkillsDir, "user", true));
|
|
259
|
+
addSkills(loadSkillsFromDirInternal(projectSkillsDir, "project", true));
|
|
260
|
+
}
|
|
261
|
+
for (const rawPath of skillPaths) {
|
|
262
|
+
const resolvedPath = resolveSkillPath(rawPath, cwd);
|
|
263
|
+
if (!existsSync(resolvedPath)) {
|
|
264
|
+
allDiagnostics.push({ type: "warning", message: "skill path does not exist", path: resolvedPath });
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
try {
|
|
268
|
+
const stats = statSync(resolvedPath);
|
|
269
|
+
if (stats.isDirectory()) {
|
|
270
|
+
addSkills(loadSkillsFromDirInternal(resolvedPath, "path", true));
|
|
271
|
+
} else if (stats.isFile() && resolvedPath.endsWith(".md")) {
|
|
272
|
+
const result = loadSkillFromFile(resolvedPath, "path");
|
|
273
|
+
if (result.skill) {
|
|
274
|
+
addSkills({ skills: [result.skill], diagnostics: result.diagnostics });
|
|
275
|
+
} else {
|
|
276
|
+
allDiagnostics.push(...result.diagnostics);
|
|
277
|
+
}
|
|
278
|
+
} else {
|
|
279
|
+
allDiagnostics.push({ type: "warning", message: "skill path is not a markdown file", path: resolvedPath });
|
|
280
|
+
}
|
|
281
|
+
} catch (error) {
|
|
282
|
+
const message = error instanceof Error ? error.message : "failed to read skill path";
|
|
283
|
+
allDiagnostics.push({ type: "warning", message, path: resolvedPath });
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
return {
|
|
287
|
+
skills: Array.from(skillMap.values()),
|
|
288
|
+
diagnostics: [...allDiagnostics, ...collisionDiagnostics]
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
function escapeXml(str) {
|
|
292
|
+
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
293
|
+
}
|
|
294
|
+
function formatSkillsForPrompt(skills) {
|
|
295
|
+
const visibleSkills = skills.filter((s) => !s.disableModelInvocation);
|
|
296
|
+
if (visibleSkills.length === 0) {
|
|
297
|
+
return "";
|
|
298
|
+
}
|
|
299
|
+
const lines = [
|
|
300
|
+
"The following skills provide specialized instructions for specific tasks.",
|
|
301
|
+
"Use the read tool to load a skill's file when the task matches its description.",
|
|
302
|
+
"When a skill file references a relative path, resolve it against the skill directory (parent of SKILL.md / dirname of the path) and use that absolute path in tool commands.",
|
|
303
|
+
"",
|
|
304
|
+
"<available_skills>"
|
|
305
|
+
];
|
|
306
|
+
for (const skill of visibleSkills) {
|
|
307
|
+
lines.push(" <skill>");
|
|
308
|
+
lines.push(` <name>${escapeXml(skill.name)}</name>`);
|
|
309
|
+
lines.push(` <description>${escapeXml(skill.description)}</description>`);
|
|
310
|
+
lines.push(` <location>${escapeXml(skill.filePath)}</location>`);
|
|
311
|
+
if (skill.allowedTools?.length) {
|
|
312
|
+
lines.push(` <allowed-tools>${escapeXml(skill.allowedTools.join(" "))}</allowed-tools>`);
|
|
313
|
+
}
|
|
314
|
+
lines.push(" </skill>");
|
|
315
|
+
}
|
|
316
|
+
lines.push("</available_skills>");
|
|
317
|
+
return lines.join(`
|
|
318
|
+
`);
|
|
319
|
+
}
|
|
320
|
+
export {
|
|
321
|
+
loadSkillsFromDir,
|
|
322
|
+
loadSkills,
|
|
323
|
+
formatSkillsForPrompt
|
|
324
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AskUserQuestion tool.
|
|
3
|
+
* In this in-process runtime, direct interactive prompting is not available.
|
|
4
|
+
*/
|
|
5
|
+
import type { ToolImplementation } from "./registry.js";
|
|
6
|
+
export declare const AskUserQuestionTool: ToolImplementation;
|
|
7
|
+
//# sourceMappingURL=ask-user-question.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ask-user-question.d.ts","sourceRoot":"","sources":["../../src/tools/ask-user-question.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAc,MAAM,eAAe,CAAC;AAEpE,eAAO,MAAM,mBAAmB,EAAE,kBAuCjC,CAAC"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
8
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
10
|
+
for (let key of __getOwnPropNames(mod))
|
|
11
|
+
if (!__hasOwnProp.call(to, key))
|
|
12
|
+
__defProp(to, key, {
|
|
13
|
+
get: () => mod[key],
|
|
14
|
+
enumerable: true
|
|
15
|
+
});
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __export = (target, all) => {
|
|
19
|
+
for (var name in all)
|
|
20
|
+
__defProp(target, name, {
|
|
21
|
+
get: all[name],
|
|
22
|
+
enumerable: true,
|
|
23
|
+
configurable: true,
|
|
24
|
+
set: (newValue) => all[name] = () => newValue
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
28
|
+
var __require = import.meta.require;
|
|
29
|
+
|
|
30
|
+
// src/tools/ask-user-question.ts
|
|
31
|
+
var AskUserQuestionTool = {
|
|
32
|
+
name: "AskUserQuestion",
|
|
33
|
+
description: "Ask the user a clarifying question and wait for their response.",
|
|
34
|
+
inputSchema: {
|
|
35
|
+
type: "object",
|
|
36
|
+
properties: {
|
|
37
|
+
question: {
|
|
38
|
+
type: "string",
|
|
39
|
+
description: "Question to ask the user."
|
|
40
|
+
},
|
|
41
|
+
options: {
|
|
42
|
+
type: "array",
|
|
43
|
+
items: { type: "string" },
|
|
44
|
+
description: "Optional fixed choices."
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
required: ["question"]
|
|
48
|
+
},
|
|
49
|
+
async execute(input) {
|
|
50
|
+
const { question, options } = input ?? {};
|
|
51
|
+
if (!question) {
|
|
52
|
+
return { content: "Error: question is required", isError: true };
|
|
53
|
+
}
|
|
54
|
+
const choices = Array.isArray(options) && options.length > 0 ? ` Choices: ${options.join(" | ")}` : "";
|
|
55
|
+
return {
|
|
56
|
+
content: `User interaction is not available in this runtime. Unanswered question: ${question}.${choices}`,
|
|
57
|
+
isError: true
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
export {
|
|
62
|
+
AskUserQuestionTool
|
|
63
|
+
};
|
package/dist/tools/bash.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAA2B,MAAM,eAAe,CAAC;AAMjF,eAAO,MAAM,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAA2B,MAAM,eAAe,CAAC;AAMjF,eAAO,MAAM,QAAQ,EAAE,kBAoItB,CAAC"}
|
package/dist/tools/bash.js
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
// @bun
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
2
4
|
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
8
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
10
|
+
for (let key of __getOwnPropNames(mod))
|
|
11
|
+
if (!__hasOwnProp.call(to, key))
|
|
12
|
+
__defProp(to, key, {
|
|
13
|
+
get: () => mod[key],
|
|
14
|
+
enumerable: true
|
|
15
|
+
});
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
3
18
|
var __export = (target, all) => {
|
|
4
19
|
for (var name in all)
|
|
5
20
|
__defProp(target, name, {
|
|
@@ -33,17 +48,58 @@ var BashTool = {
|
|
|
33
48
|
timeout: {
|
|
34
49
|
type: "number",
|
|
35
50
|
description: "Timeout in milliseconds (max 600000)"
|
|
51
|
+
},
|
|
52
|
+
run_in_background: {
|
|
53
|
+
type: "boolean",
|
|
54
|
+
description: "Run command asynchronously and return immediately."
|
|
55
|
+
},
|
|
56
|
+
dangerouslyDisableSandbox: {
|
|
57
|
+
type: "boolean",
|
|
58
|
+
description: "If true, explicitly request unsandboxed execution."
|
|
59
|
+
},
|
|
60
|
+
_simulatedSedEdit: {
|
|
61
|
+
type: "object",
|
|
62
|
+
properties: {
|
|
63
|
+
filePath: { type: "string" },
|
|
64
|
+
newContent: { type: "string" }
|
|
65
|
+
},
|
|
66
|
+
description: "Internal field for precomputed edit previews."
|
|
36
67
|
}
|
|
37
68
|
},
|
|
38
69
|
required: ["command"]
|
|
39
70
|
},
|
|
40
71
|
async execute(input, ctx) {
|
|
41
|
-
const {
|
|
72
|
+
const {
|
|
73
|
+
command,
|
|
74
|
+
timeout: timeoutMs,
|
|
75
|
+
run_in_background,
|
|
76
|
+
description,
|
|
77
|
+
dangerouslyDisableSandbox,
|
|
78
|
+
_simulatedSedEdit
|
|
79
|
+
} = input;
|
|
42
80
|
if (!command || typeof command !== "string") {
|
|
43
81
|
return { content: "Error: command is required", isError: true };
|
|
44
82
|
}
|
|
45
83
|
const timeout = Math.min(timeoutMs ?? DEFAULT_TIMEOUT, MAX_TIMEOUT);
|
|
46
84
|
try {
|
|
85
|
+
if (run_in_background) {
|
|
86
|
+
const proc2 = Bun.spawn(["bash", "-c", command], {
|
|
87
|
+
cwd: ctx.cwd,
|
|
88
|
+
stdout: "ignore",
|
|
89
|
+
stderr: "ignore",
|
|
90
|
+
stdin: "ignore",
|
|
91
|
+
env: { ...process.env, ...ctx.env }
|
|
92
|
+
});
|
|
93
|
+
return {
|
|
94
|
+
content: `Background command started (pid ${proc2.pid ?? "unknown"}).`,
|
|
95
|
+
metadata: {
|
|
96
|
+
pid: proc2.pid ?? null,
|
|
97
|
+
run_in_background: true,
|
|
98
|
+
dangerouslyDisableSandbox: dangerouslyDisableSandbox === true,
|
|
99
|
+
hasSimulatedSedEdit: !!_simulatedSedEdit
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
}
|
|
47
103
|
const proc = Bun.spawn(["bash", "-c", command], {
|
|
48
104
|
cwd: ctx.cwd,
|
|
49
105
|
stdout: "pipe",
|
|
@@ -75,7 +131,11 @@ var BashTool = {
|
|
|
75
131
|
return {
|
|
76
132
|
content: output,
|
|
77
133
|
isError: exitCode !== 0 ? true : undefined,
|
|
78
|
-
metadata: {
|
|
134
|
+
metadata: {
|
|
135
|
+
exitCode,
|
|
136
|
+
dangerouslyDisableSandbox: dangerouslyDisableSandbox === true,
|
|
137
|
+
hasSimulatedSedEdit: !!_simulatedSedEdit
|
|
138
|
+
}
|
|
79
139
|
};
|
|
80
140
|
} catch (err) {
|
|
81
141
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/tools/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,kBAAkB,EAA2B,MAAM,eAAe,CAAC;AAmCjF,eAAO,MAAM,UAAU,EAAE,kBA4ExB,CAAC"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
8
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
10
|
+
for (let key of __getOwnPropNames(mod))
|
|
11
|
+
if (!__hasOwnProp.call(to, key))
|
|
12
|
+
__defProp(to, key, {
|
|
13
|
+
get: () => mod[key],
|
|
14
|
+
enumerable: true
|
|
15
|
+
});
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __export = (target, all) => {
|
|
19
|
+
for (var name in all)
|
|
20
|
+
__defProp(target, name, {
|
|
21
|
+
get: all[name],
|
|
22
|
+
enumerable: true,
|
|
23
|
+
configurable: true,
|
|
24
|
+
set: (newValue) => all[name] = () => newValue
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
28
|
+
var __require = import.meta.require;
|
|
29
|
+
|
|
30
|
+
// src/tools/config.ts
|
|
31
|
+
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
32
|
+
import { join, dirname } from "path";
|
|
33
|
+
function scopePath(cwd, scope) {
|
|
34
|
+
if (scope === "project")
|
|
35
|
+
return join(cwd, ".claude", "settings.json");
|
|
36
|
+
return join(cwd, ".claude", "settings.local.json");
|
|
37
|
+
}
|
|
38
|
+
function setByPath(obj, keyPath, value) {
|
|
39
|
+
const keys = keyPath.split(".").filter(Boolean);
|
|
40
|
+
if (keys.length === 0)
|
|
41
|
+
return;
|
|
42
|
+
let current = obj;
|
|
43
|
+
for (let i = 0;i < keys.length - 1; i++) {
|
|
44
|
+
const key = keys[i];
|
|
45
|
+
const next = current[key];
|
|
46
|
+
if (!next || typeof next !== "object" || Array.isArray(next)) {
|
|
47
|
+
current[key] = {};
|
|
48
|
+
}
|
|
49
|
+
current = current[key];
|
|
50
|
+
}
|
|
51
|
+
current[keys[keys.length - 1]] = value;
|
|
52
|
+
}
|
|
53
|
+
function getByPath(obj, keyPath) {
|
|
54
|
+
const keys = keyPath.split(".").filter(Boolean);
|
|
55
|
+
let current = obj;
|
|
56
|
+
for (const key of keys) {
|
|
57
|
+
if (!current || typeof current !== "object" || Array.isArray(current))
|
|
58
|
+
return;
|
|
59
|
+
current = current[key];
|
|
60
|
+
}
|
|
61
|
+
return current;
|
|
62
|
+
}
|
|
63
|
+
var ConfigTool = {
|
|
64
|
+
name: "Config",
|
|
65
|
+
description: "Read or update .claude settings values.",
|
|
66
|
+
inputSchema: {
|
|
67
|
+
type: "object",
|
|
68
|
+
properties: {
|
|
69
|
+
action: {
|
|
70
|
+
type: "string",
|
|
71
|
+
enum: ["get", "set", "list"]
|
|
72
|
+
},
|
|
73
|
+
key: {
|
|
74
|
+
type: "string",
|
|
75
|
+
description: "Dot-path key (for get/set)."
|
|
76
|
+
},
|
|
77
|
+
value: {
|
|
78
|
+
description: "Value for set action."
|
|
79
|
+
},
|
|
80
|
+
scope: {
|
|
81
|
+
type: "string",
|
|
82
|
+
enum: ["local", "project"]
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
required: ["action"]
|
|
86
|
+
},
|
|
87
|
+
async execute(input, ctx) {
|
|
88
|
+
const {
|
|
89
|
+
action,
|
|
90
|
+
key,
|
|
91
|
+
value,
|
|
92
|
+
scope = "local"
|
|
93
|
+
} = input ?? {};
|
|
94
|
+
if (!action) {
|
|
95
|
+
return { content: "Error: action is required", isError: true };
|
|
96
|
+
}
|
|
97
|
+
const filePath = scopePath(ctx.cwd, scope);
|
|
98
|
+
let data = {};
|
|
99
|
+
try {
|
|
100
|
+
const raw = await readFile(filePath, "utf-8");
|
|
101
|
+
data = JSON.parse(raw);
|
|
102
|
+
} catch {
|
|
103
|
+
data = {};
|
|
104
|
+
}
|
|
105
|
+
if (action === "list") {
|
|
106
|
+
return { content: JSON.stringify(data, null, 2) };
|
|
107
|
+
}
|
|
108
|
+
if (!key) {
|
|
109
|
+
return { content: "Error: key is required for get/set", isError: true };
|
|
110
|
+
}
|
|
111
|
+
if (action === "get") {
|
|
112
|
+
const out = getByPath(data, key);
|
|
113
|
+
return { content: out === undefined ? "undefined" : JSON.stringify(out, null, 2) };
|
|
114
|
+
}
|
|
115
|
+
setByPath(data, key, value);
|
|
116
|
+
try {
|
|
117
|
+
await mkdir(dirname(filePath), { recursive: true });
|
|
118
|
+
await writeFile(filePath, JSON.stringify(data, null, 2) + `
|
|
119
|
+
`, "utf-8");
|
|
120
|
+
return { content: `Updated ${key} in ${filePath}` };
|
|
121
|
+
} catch (err) {
|
|
122
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
123
|
+
return { content: `Error writing config: ${message}`, isError: true };
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
export {
|
|
128
|
+
ConfigTool
|
|
129
|
+
};
|
package/dist/tools/edit.js
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
// @bun
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
2
4
|
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __toESM = (mod, isNodeMode, target) => {
|
|
8
|
+
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
|
+
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
10
|
+
for (let key of __getOwnPropNames(mod))
|
|
11
|
+
if (!__hasOwnProp.call(to, key))
|
|
12
|
+
__defProp(to, key, {
|
|
13
|
+
get: () => mod[key],
|
|
14
|
+
enumerable: true
|
|
15
|
+
});
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
3
18
|
var __export = (target, all) => {
|
|
4
19
|
for (var name in all)
|
|
5
20
|
__defProp(target, name, {
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ExitPlanMode tool.
|
|
3
|
+
* Signals the runtime to leave plan mode and return to default permissions.
|
|
4
|
+
*/
|
|
5
|
+
import type { ToolImplementation } from "./registry.js";
|
|
6
|
+
export declare const ExitPlanModeTool: ToolImplementation;
|
|
7
|
+
//# sourceMappingURL=exit-plan-mode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exit-plan-mode.d.ts","sourceRoot":"","sources":["../../src/tools/exit-plan-mode.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAc,MAAM,eAAe,CAAC;AAEpE,eAAO,MAAM,gBAAgB,EAAE,kBAgB9B,CAAC"}
|