fourmis-agents-sdk 0.2.6 → 0.3.1
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 +3 -0
- package/dist/agent-loop.d.ts.map +1 -1
- package/dist/agent-loop.js +23 -9
- package/dist/agents/index.js +40 -12
- package/dist/agents/tools.js +40 -12
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +658 -28
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +666 -28
- package/dist/memory/index.d.ts +42 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +319 -0
- package/dist/memory/memory-handler.d.ts +49 -0
- package/dist/memory/memory-handler.d.ts.map +1 -0
- package/dist/memory/memory-handler.js +233 -0
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js +17 -3
- package/dist/providers/registry.js +17 -3
- package/dist/providers/types.d.ts +6 -0
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/skills/frontmatter.d.ts +15 -0
- package/dist/skills/frontmatter.d.ts.map +1 -0
- package/dist/skills/frontmatter.js +51 -0
- package/dist/skills/index.d.ts +8 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +289 -0
- package/dist/skills/skills.d.ts +78 -0
- package/dist/skills/skills.d.ts.map +1 -0
- package/dist/skills/skills.js +287 -0
- package/dist/types.d.ts +23 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/system-prompt.d.ts +2 -0
- package/dist/utils/system-prompt.d.ts.map +1 -1
- package/dist/utils/system-prompt.js +279 -3
- package/package.json +3 -2
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __export = (target, all) => {
|
|
4
|
+
for (var name in all)
|
|
5
|
+
__defProp(target, name, {
|
|
6
|
+
get: all[name],
|
|
7
|
+
enumerable: true,
|
|
8
|
+
configurable: true,
|
|
9
|
+
set: (newValue) => all[name] = () => newValue
|
|
10
|
+
});
|
|
11
|
+
};
|
|
12
|
+
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
13
|
+
var __require = import.meta.require;
|
|
14
|
+
|
|
15
|
+
// src/skills/frontmatter.ts
|
|
16
|
+
import { parse } from "yaml";
|
|
17
|
+
function normalizeNewlines(value) {
|
|
18
|
+
return value.replace(/\r\n/g, `
|
|
19
|
+
`).replace(/\r/g, `
|
|
20
|
+
`);
|
|
21
|
+
}
|
|
22
|
+
function extractFrontmatter(content) {
|
|
23
|
+
const normalized = normalizeNewlines(content);
|
|
24
|
+
if (!normalized.startsWith("---")) {
|
|
25
|
+
return { yamlString: null, body: normalized };
|
|
26
|
+
}
|
|
27
|
+
const endIndex = normalized.indexOf(`
|
|
28
|
+
---`, 3);
|
|
29
|
+
if (endIndex === -1) {
|
|
30
|
+
return { yamlString: null, body: normalized };
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
yamlString: normalized.slice(4, endIndex),
|
|
34
|
+
body: normalized.slice(endIndex + 4).trim()
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function parseFrontmatter(content) {
|
|
38
|
+
const { yamlString, body } = extractFrontmatter(content);
|
|
39
|
+
if (!yamlString) {
|
|
40
|
+
return { frontmatter: {}, body };
|
|
41
|
+
}
|
|
42
|
+
const parsed = parse(yamlString);
|
|
43
|
+
return { frontmatter: parsed ?? {}, body };
|
|
44
|
+
}
|
|
45
|
+
function stripFrontmatter(content) {
|
|
46
|
+
return parseFrontmatter(content).body;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// src/skills/skills.ts
|
|
50
|
+
import { existsSync, readdirSync, readFileSync, realpathSync, statSync } from "fs";
|
|
51
|
+
import { homedir } from "os";
|
|
52
|
+
import { basename, dirname, isAbsolute, join, resolve } from "path";
|
|
53
|
+
var MAX_NAME_LENGTH = 64;
|
|
54
|
+
var MAX_DESCRIPTION_LENGTH = 1024;
|
|
55
|
+
var CONFIG_DIR_NAME = ".claude";
|
|
56
|
+
function shouldIgnore(name) {
|
|
57
|
+
return name.startsWith(".") || name === "node_modules";
|
|
58
|
+
}
|
|
59
|
+
function validateName(name, parentDirName) {
|
|
60
|
+
const errors = [];
|
|
61
|
+
if (name !== parentDirName) {
|
|
62
|
+
errors.push(`name "${name}" does not match parent directory "${parentDirName}"`);
|
|
63
|
+
}
|
|
64
|
+
if (name.length > MAX_NAME_LENGTH) {
|
|
65
|
+
errors.push(`name exceeds ${MAX_NAME_LENGTH} characters (${name.length})`);
|
|
66
|
+
}
|
|
67
|
+
if (!/^[a-z0-9-]+$/.test(name)) {
|
|
68
|
+
errors.push(`name contains invalid characters (must be lowercase a-z, 0-9, hyphens only)`);
|
|
69
|
+
}
|
|
70
|
+
if (name.startsWith("-") || name.endsWith("-")) {
|
|
71
|
+
errors.push(`name must not start or end with a hyphen`);
|
|
72
|
+
}
|
|
73
|
+
if (name.includes("--")) {
|
|
74
|
+
errors.push(`name must not contain consecutive hyphens`);
|
|
75
|
+
}
|
|
76
|
+
return errors;
|
|
77
|
+
}
|
|
78
|
+
function validateDescription(description) {
|
|
79
|
+
const errors = [];
|
|
80
|
+
if (!description || description.trim() === "") {
|
|
81
|
+
errors.push("description is required");
|
|
82
|
+
} else if (description.length > MAX_DESCRIPTION_LENGTH) {
|
|
83
|
+
errors.push(`description exceeds ${MAX_DESCRIPTION_LENGTH} characters (${description.length})`);
|
|
84
|
+
}
|
|
85
|
+
return errors;
|
|
86
|
+
}
|
|
87
|
+
function loadSkillsFromDir(options) {
|
|
88
|
+
return loadSkillsFromDirInternal(options.dir, options.source, true);
|
|
89
|
+
}
|
|
90
|
+
function loadSkillsFromDirInternal(dir, source, includeRootFiles) {
|
|
91
|
+
const skills = [];
|
|
92
|
+
const diagnostics = [];
|
|
93
|
+
if (!existsSync(dir)) {
|
|
94
|
+
return { skills, diagnostics };
|
|
95
|
+
}
|
|
96
|
+
try {
|
|
97
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
98
|
+
for (const entry of entries) {
|
|
99
|
+
if (shouldIgnore(entry.name)) {
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
const fullPath = join(dir, entry.name);
|
|
103
|
+
let isDirectory = entry.isDirectory();
|
|
104
|
+
let isFile = entry.isFile();
|
|
105
|
+
if (entry.isSymbolicLink()) {
|
|
106
|
+
try {
|
|
107
|
+
const stats = statSync(fullPath);
|
|
108
|
+
isDirectory = stats.isDirectory();
|
|
109
|
+
isFile = stats.isFile();
|
|
110
|
+
} catch {
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (isDirectory) {
|
|
115
|
+
const subResult = loadSkillsFromDirInternal(fullPath, source, false);
|
|
116
|
+
skills.push(...subResult.skills);
|
|
117
|
+
diagnostics.push(...subResult.diagnostics);
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
if (!isFile)
|
|
121
|
+
continue;
|
|
122
|
+
const isRootMd = includeRootFiles && entry.name.endsWith(".md");
|
|
123
|
+
const isSkillMd = !includeRootFiles && entry.name === "SKILL.md";
|
|
124
|
+
if (!isRootMd && !isSkillMd)
|
|
125
|
+
continue;
|
|
126
|
+
const result = loadSkillFromFile(fullPath, source);
|
|
127
|
+
if (result.skill) {
|
|
128
|
+
skills.push(result.skill);
|
|
129
|
+
}
|
|
130
|
+
diagnostics.push(...result.diagnostics);
|
|
131
|
+
}
|
|
132
|
+
} catch {}
|
|
133
|
+
return { skills, diagnostics };
|
|
134
|
+
}
|
|
135
|
+
function loadSkillFromFile(filePath, source) {
|
|
136
|
+
const diagnostics = [];
|
|
137
|
+
try {
|
|
138
|
+
const rawContent = readFileSync(filePath, "utf-8");
|
|
139
|
+
const { frontmatter } = parseFrontmatter(rawContent);
|
|
140
|
+
const skillDir = dirname(filePath);
|
|
141
|
+
const parentDirName = basename(skillDir);
|
|
142
|
+
const descErrors = validateDescription(frontmatter.description);
|
|
143
|
+
for (const error of descErrors) {
|
|
144
|
+
diagnostics.push({ type: "warning", message: error, path: filePath });
|
|
145
|
+
}
|
|
146
|
+
const name = frontmatter.name || parentDirName;
|
|
147
|
+
const nameErrors = validateName(name, parentDirName);
|
|
148
|
+
for (const error of nameErrors) {
|
|
149
|
+
diagnostics.push({ type: "warning", message: error, path: filePath });
|
|
150
|
+
}
|
|
151
|
+
if (!frontmatter.description || frontmatter.description.trim() === "") {
|
|
152
|
+
return { skill: null, diagnostics };
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
skill: {
|
|
156
|
+
name,
|
|
157
|
+
description: frontmatter.description,
|
|
158
|
+
filePath,
|
|
159
|
+
baseDir: skillDir,
|
|
160
|
+
source,
|
|
161
|
+
disableModelInvocation: frontmatter["disable-model-invocation"] === true
|
|
162
|
+
},
|
|
163
|
+
diagnostics
|
|
164
|
+
};
|
|
165
|
+
} catch (error) {
|
|
166
|
+
const message = error instanceof Error ? error.message : "failed to parse skill file";
|
|
167
|
+
diagnostics.push({ type: "warning", message, path: filePath });
|
|
168
|
+
return { skill: null, diagnostics };
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
function normalizePath(input) {
|
|
172
|
+
const trimmed = input.trim();
|
|
173
|
+
if (trimmed === "~")
|
|
174
|
+
return homedir();
|
|
175
|
+
if (trimmed.startsWith("~/"))
|
|
176
|
+
return join(homedir(), trimmed.slice(2));
|
|
177
|
+
if (trimmed.startsWith("~"))
|
|
178
|
+
return join(homedir(), trimmed.slice(1));
|
|
179
|
+
return trimmed;
|
|
180
|
+
}
|
|
181
|
+
function resolveSkillPath(p, cwd) {
|
|
182
|
+
const normalized = normalizePath(p);
|
|
183
|
+
return isAbsolute(normalized) ? normalized : resolve(cwd, normalized);
|
|
184
|
+
}
|
|
185
|
+
function loadSkills(options = {}) {
|
|
186
|
+
const { cwd = process.cwd(), skillPaths = [], includeDefaults = true } = options;
|
|
187
|
+
const skillMap = new Map;
|
|
188
|
+
const realPathSet = new Set;
|
|
189
|
+
const allDiagnostics = [];
|
|
190
|
+
const collisionDiagnostics = [];
|
|
191
|
+
function addSkills(result) {
|
|
192
|
+
allDiagnostics.push(...result.diagnostics);
|
|
193
|
+
for (const skill of result.skills) {
|
|
194
|
+
let realPath;
|
|
195
|
+
try {
|
|
196
|
+
realPath = realpathSync(skill.filePath);
|
|
197
|
+
} catch {
|
|
198
|
+
realPath = skill.filePath;
|
|
199
|
+
}
|
|
200
|
+
if (realPathSet.has(realPath))
|
|
201
|
+
continue;
|
|
202
|
+
const existing = skillMap.get(skill.name);
|
|
203
|
+
if (existing) {
|
|
204
|
+
collisionDiagnostics.push({
|
|
205
|
+
type: "collision",
|
|
206
|
+
message: `name "${skill.name}" collision`,
|
|
207
|
+
path: skill.filePath,
|
|
208
|
+
collision: {
|
|
209
|
+
resourceType: "skill",
|
|
210
|
+
name: skill.name,
|
|
211
|
+
winnerPath: existing.filePath,
|
|
212
|
+
loserPath: skill.filePath
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
} else {
|
|
216
|
+
skillMap.set(skill.name, skill);
|
|
217
|
+
realPathSet.add(realPath);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
if (includeDefaults) {
|
|
222
|
+
const userSkillsDir = join(homedir(), CONFIG_DIR_NAME, "skills");
|
|
223
|
+
const projectSkillsDir = resolve(cwd, CONFIG_DIR_NAME, "skills");
|
|
224
|
+
addSkills(loadSkillsFromDirInternal(userSkillsDir, "user", true));
|
|
225
|
+
addSkills(loadSkillsFromDirInternal(projectSkillsDir, "project", true));
|
|
226
|
+
}
|
|
227
|
+
for (const rawPath of skillPaths) {
|
|
228
|
+
const resolvedPath = resolveSkillPath(rawPath, cwd);
|
|
229
|
+
if (!existsSync(resolvedPath)) {
|
|
230
|
+
allDiagnostics.push({ type: "warning", message: "skill path does not exist", path: resolvedPath });
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
try {
|
|
234
|
+
const stats = statSync(resolvedPath);
|
|
235
|
+
if (stats.isDirectory()) {
|
|
236
|
+
addSkills(loadSkillsFromDirInternal(resolvedPath, "path", true));
|
|
237
|
+
} else if (stats.isFile() && resolvedPath.endsWith(".md")) {
|
|
238
|
+
const result = loadSkillFromFile(resolvedPath, "path");
|
|
239
|
+
if (result.skill) {
|
|
240
|
+
addSkills({ skills: [result.skill], diagnostics: result.diagnostics });
|
|
241
|
+
} else {
|
|
242
|
+
allDiagnostics.push(...result.diagnostics);
|
|
243
|
+
}
|
|
244
|
+
} else {
|
|
245
|
+
allDiagnostics.push({ type: "warning", message: "skill path is not a markdown file", path: resolvedPath });
|
|
246
|
+
}
|
|
247
|
+
} catch (error) {
|
|
248
|
+
const message = error instanceof Error ? error.message : "failed to read skill path";
|
|
249
|
+
allDiagnostics.push({ type: "warning", message, path: resolvedPath });
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return {
|
|
253
|
+
skills: Array.from(skillMap.values()),
|
|
254
|
+
diagnostics: [...allDiagnostics, ...collisionDiagnostics]
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
function escapeXml(str) {
|
|
258
|
+
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
259
|
+
}
|
|
260
|
+
function formatSkillsForPrompt(skills) {
|
|
261
|
+
const visibleSkills = skills.filter((s) => !s.disableModelInvocation);
|
|
262
|
+
if (visibleSkills.length === 0) {
|
|
263
|
+
return "";
|
|
264
|
+
}
|
|
265
|
+
const lines = [
|
|
266
|
+
"The following skills provide specialized instructions for specific tasks.",
|
|
267
|
+
"Use the read tool to load a skill's file when the task matches its description.",
|
|
268
|
+
"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.",
|
|
269
|
+
"",
|
|
270
|
+
"<available_skills>"
|
|
271
|
+
];
|
|
272
|
+
for (const skill of visibleSkills) {
|
|
273
|
+
lines.push(" <skill>");
|
|
274
|
+
lines.push(` <name>${escapeXml(skill.name)}</name>`);
|
|
275
|
+
lines.push(` <description>${escapeXml(skill.description)}</description>`);
|
|
276
|
+
lines.push(` <location>${escapeXml(skill.filePath)}</location>`);
|
|
277
|
+
lines.push(" </skill>");
|
|
278
|
+
}
|
|
279
|
+
lines.push("</available_skills>");
|
|
280
|
+
return lines.join(`
|
|
281
|
+
`);
|
|
282
|
+
}
|
|
283
|
+
export {
|
|
284
|
+
loadSkillsFromDir,
|
|
285
|
+
loadSkills,
|
|
286
|
+
formatSkillsForPrompt
|
|
287
|
+
};
|
package/dist/types.d.ts
CHANGED
|
@@ -193,6 +193,29 @@ export type QueryOptions = {
|
|
|
193
193
|
hooks?: Partial<Record<import("./hooks.ts").HookEvent, import("./hooks.ts").HookCallbackMatcher[]>>;
|
|
194
194
|
mcpServers?: Record<string, import("./mcp/types.ts").McpServerConfig>;
|
|
195
195
|
agents?: Record<string, import("./agents/types.ts").AgentDefinition>;
|
|
196
|
+
/**
|
|
197
|
+
* Paths to skill files or directories to load.
|
|
198
|
+
* Skills are SKILL.md files with YAML frontmatter (name, description).
|
|
199
|
+
* They get injected into the system prompt as available capabilities.
|
|
200
|
+
*
|
|
201
|
+
* By default, also scans ~/.claude/skills/ and .claude/skills/.
|
|
202
|
+
* Set `includeDefaultSkills: false` to disable default locations.
|
|
203
|
+
*
|
|
204
|
+
* Matches the Claude SDK's skill loading behavior.
|
|
205
|
+
*/
|
|
206
|
+
skillPaths?: string[];
|
|
207
|
+
/**
|
|
208
|
+
* Whether to include default skill directories (~/.claude/skills, .claude/skills).
|
|
209
|
+
* Default: true
|
|
210
|
+
*/
|
|
211
|
+
includeDefaultSkills?: boolean;
|
|
212
|
+
/**
|
|
213
|
+
* Absolute path to the memory directory.
|
|
214
|
+
* When set, enables the memory tool for the agent.
|
|
215
|
+
* For Anthropic: uses native memory_20250818 tool type.
|
|
216
|
+
* For OpenAI/Gemini: registers a standard function tool.
|
|
217
|
+
*/
|
|
218
|
+
memoryPath?: string;
|
|
196
219
|
debug?: boolean;
|
|
197
220
|
signal?: AbortSignal;
|
|
198
221
|
env?: Record<string, string>;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* System prompt builder — assembles the system prompt that makes the agent effective.
|
|
3
3
|
*/
|
|
4
|
+
import type { Skill } from "../skills/index.js";
|
|
4
5
|
export type SystemPromptContext = {
|
|
5
6
|
tools: string[];
|
|
6
7
|
cwd?: string;
|
|
7
8
|
permissionMode?: string;
|
|
8
9
|
customPrompt?: string;
|
|
10
|
+
skills?: Skill[];
|
|
9
11
|
};
|
|
10
12
|
export declare function buildSystemPrompt(context: SystemPromptContext): string;
|
|
11
13
|
//# sourceMappingURL=system-prompt.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../../src/utils/system-prompt.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../../src/utils/system-prompt.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AA6DhD,MAAM,MAAM,mBAAmB,GAAG;IAChC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;CAClB,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,CAsCtE"}
|
|
@@ -12,9 +12,277 @@ var __export = (target, all) => {
|
|
|
12
12
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
13
13
|
var __require = import.meta.require;
|
|
14
14
|
|
|
15
|
+
// src/skills/frontmatter.ts
|
|
16
|
+
import { parse } from "yaml";
|
|
17
|
+
function normalizeNewlines(value) {
|
|
18
|
+
return value.replace(/\r\n/g, `
|
|
19
|
+
`).replace(/\r/g, `
|
|
20
|
+
`);
|
|
21
|
+
}
|
|
22
|
+
function extractFrontmatter(content) {
|
|
23
|
+
const normalized = normalizeNewlines(content);
|
|
24
|
+
if (!normalized.startsWith("---")) {
|
|
25
|
+
return { yamlString: null, body: normalized };
|
|
26
|
+
}
|
|
27
|
+
const endIndex = normalized.indexOf(`
|
|
28
|
+
---`, 3);
|
|
29
|
+
if (endIndex === -1) {
|
|
30
|
+
return { yamlString: null, body: normalized };
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
yamlString: normalized.slice(4, endIndex),
|
|
34
|
+
body: normalized.slice(endIndex + 4).trim()
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function parseFrontmatter(content) {
|
|
38
|
+
const { yamlString, body } = extractFrontmatter(content);
|
|
39
|
+
if (!yamlString) {
|
|
40
|
+
return { frontmatter: {}, body };
|
|
41
|
+
}
|
|
42
|
+
const parsed = parse(yamlString);
|
|
43
|
+
return { frontmatter: parsed ?? {}, body };
|
|
44
|
+
}
|
|
45
|
+
function stripFrontmatter(content) {
|
|
46
|
+
return parseFrontmatter(content).body;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// src/skills/skills.ts
|
|
50
|
+
import { existsSync, readdirSync, readFileSync, realpathSync, statSync } from "fs";
|
|
51
|
+
import { homedir } from "os";
|
|
52
|
+
import { basename, dirname, isAbsolute, join, resolve } from "path";
|
|
53
|
+
var MAX_NAME_LENGTH = 64;
|
|
54
|
+
var MAX_DESCRIPTION_LENGTH = 1024;
|
|
55
|
+
var CONFIG_DIR_NAME = ".claude";
|
|
56
|
+
function shouldIgnore(name) {
|
|
57
|
+
return name.startsWith(".") || name === "node_modules";
|
|
58
|
+
}
|
|
59
|
+
function validateName(name, parentDirName) {
|
|
60
|
+
const errors = [];
|
|
61
|
+
if (name !== parentDirName) {
|
|
62
|
+
errors.push(`name "${name}" does not match parent directory "${parentDirName}"`);
|
|
63
|
+
}
|
|
64
|
+
if (name.length > MAX_NAME_LENGTH) {
|
|
65
|
+
errors.push(`name exceeds ${MAX_NAME_LENGTH} characters (${name.length})`);
|
|
66
|
+
}
|
|
67
|
+
if (!/^[a-z0-9-]+$/.test(name)) {
|
|
68
|
+
errors.push(`name contains invalid characters (must be lowercase a-z, 0-9, hyphens only)`);
|
|
69
|
+
}
|
|
70
|
+
if (name.startsWith("-") || name.endsWith("-")) {
|
|
71
|
+
errors.push(`name must not start or end with a hyphen`);
|
|
72
|
+
}
|
|
73
|
+
if (name.includes("--")) {
|
|
74
|
+
errors.push(`name must not contain consecutive hyphens`);
|
|
75
|
+
}
|
|
76
|
+
return errors;
|
|
77
|
+
}
|
|
78
|
+
function validateDescription(description) {
|
|
79
|
+
const errors = [];
|
|
80
|
+
if (!description || description.trim() === "") {
|
|
81
|
+
errors.push("description is required");
|
|
82
|
+
} else if (description.length > MAX_DESCRIPTION_LENGTH) {
|
|
83
|
+
errors.push(`description exceeds ${MAX_DESCRIPTION_LENGTH} characters (${description.length})`);
|
|
84
|
+
}
|
|
85
|
+
return errors;
|
|
86
|
+
}
|
|
87
|
+
function loadSkillsFromDir(options) {
|
|
88
|
+
return loadSkillsFromDirInternal(options.dir, options.source, true);
|
|
89
|
+
}
|
|
90
|
+
function loadSkillsFromDirInternal(dir, source, includeRootFiles) {
|
|
91
|
+
const skills = [];
|
|
92
|
+
const diagnostics = [];
|
|
93
|
+
if (!existsSync(dir)) {
|
|
94
|
+
return { skills, diagnostics };
|
|
95
|
+
}
|
|
96
|
+
try {
|
|
97
|
+
const entries = readdirSync(dir, { withFileTypes: true });
|
|
98
|
+
for (const entry of entries) {
|
|
99
|
+
if (shouldIgnore(entry.name)) {
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
const fullPath = join(dir, entry.name);
|
|
103
|
+
let isDirectory = entry.isDirectory();
|
|
104
|
+
let isFile = entry.isFile();
|
|
105
|
+
if (entry.isSymbolicLink()) {
|
|
106
|
+
try {
|
|
107
|
+
const stats = statSync(fullPath);
|
|
108
|
+
isDirectory = stats.isDirectory();
|
|
109
|
+
isFile = stats.isFile();
|
|
110
|
+
} catch {
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (isDirectory) {
|
|
115
|
+
const subResult = loadSkillsFromDirInternal(fullPath, source, false);
|
|
116
|
+
skills.push(...subResult.skills);
|
|
117
|
+
diagnostics.push(...subResult.diagnostics);
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
if (!isFile)
|
|
121
|
+
continue;
|
|
122
|
+
const isRootMd = includeRootFiles && entry.name.endsWith(".md");
|
|
123
|
+
const isSkillMd = !includeRootFiles && entry.name === "SKILL.md";
|
|
124
|
+
if (!isRootMd && !isSkillMd)
|
|
125
|
+
continue;
|
|
126
|
+
const result = loadSkillFromFile(fullPath, source);
|
|
127
|
+
if (result.skill) {
|
|
128
|
+
skills.push(result.skill);
|
|
129
|
+
}
|
|
130
|
+
diagnostics.push(...result.diagnostics);
|
|
131
|
+
}
|
|
132
|
+
} catch {}
|
|
133
|
+
return { skills, diagnostics };
|
|
134
|
+
}
|
|
135
|
+
function loadSkillFromFile(filePath, source) {
|
|
136
|
+
const diagnostics = [];
|
|
137
|
+
try {
|
|
138
|
+
const rawContent = readFileSync(filePath, "utf-8");
|
|
139
|
+
const { frontmatter } = parseFrontmatter(rawContent);
|
|
140
|
+
const skillDir = dirname(filePath);
|
|
141
|
+
const parentDirName = basename(skillDir);
|
|
142
|
+
const descErrors = validateDescription(frontmatter.description);
|
|
143
|
+
for (const error of descErrors) {
|
|
144
|
+
diagnostics.push({ type: "warning", message: error, path: filePath });
|
|
145
|
+
}
|
|
146
|
+
const name = frontmatter.name || parentDirName;
|
|
147
|
+
const nameErrors = validateName(name, parentDirName);
|
|
148
|
+
for (const error of nameErrors) {
|
|
149
|
+
diagnostics.push({ type: "warning", message: error, path: filePath });
|
|
150
|
+
}
|
|
151
|
+
if (!frontmatter.description || frontmatter.description.trim() === "") {
|
|
152
|
+
return { skill: null, diagnostics };
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
skill: {
|
|
156
|
+
name,
|
|
157
|
+
description: frontmatter.description,
|
|
158
|
+
filePath,
|
|
159
|
+
baseDir: skillDir,
|
|
160
|
+
source,
|
|
161
|
+
disableModelInvocation: frontmatter["disable-model-invocation"] === true
|
|
162
|
+
},
|
|
163
|
+
diagnostics
|
|
164
|
+
};
|
|
165
|
+
} catch (error) {
|
|
166
|
+
const message = error instanceof Error ? error.message : "failed to parse skill file";
|
|
167
|
+
diagnostics.push({ type: "warning", message, path: filePath });
|
|
168
|
+
return { skill: null, diagnostics };
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
function normalizePath(input) {
|
|
172
|
+
const trimmed = input.trim();
|
|
173
|
+
if (trimmed === "~")
|
|
174
|
+
return homedir();
|
|
175
|
+
if (trimmed.startsWith("~/"))
|
|
176
|
+
return join(homedir(), trimmed.slice(2));
|
|
177
|
+
if (trimmed.startsWith("~"))
|
|
178
|
+
return join(homedir(), trimmed.slice(1));
|
|
179
|
+
return trimmed;
|
|
180
|
+
}
|
|
181
|
+
function resolveSkillPath(p, cwd) {
|
|
182
|
+
const normalized = normalizePath(p);
|
|
183
|
+
return isAbsolute(normalized) ? normalized : resolve(cwd, normalized);
|
|
184
|
+
}
|
|
185
|
+
function loadSkills(options = {}) {
|
|
186
|
+
const { cwd = process.cwd(), skillPaths = [], includeDefaults = true } = options;
|
|
187
|
+
const skillMap = new Map;
|
|
188
|
+
const realPathSet = new Set;
|
|
189
|
+
const allDiagnostics = [];
|
|
190
|
+
const collisionDiagnostics = [];
|
|
191
|
+
function addSkills(result) {
|
|
192
|
+
allDiagnostics.push(...result.diagnostics);
|
|
193
|
+
for (const skill of result.skills) {
|
|
194
|
+
let realPath;
|
|
195
|
+
try {
|
|
196
|
+
realPath = realpathSync(skill.filePath);
|
|
197
|
+
} catch {
|
|
198
|
+
realPath = skill.filePath;
|
|
199
|
+
}
|
|
200
|
+
if (realPathSet.has(realPath))
|
|
201
|
+
continue;
|
|
202
|
+
const existing = skillMap.get(skill.name);
|
|
203
|
+
if (existing) {
|
|
204
|
+
collisionDiagnostics.push({
|
|
205
|
+
type: "collision",
|
|
206
|
+
message: `name "${skill.name}" collision`,
|
|
207
|
+
path: skill.filePath,
|
|
208
|
+
collision: {
|
|
209
|
+
resourceType: "skill",
|
|
210
|
+
name: skill.name,
|
|
211
|
+
winnerPath: existing.filePath,
|
|
212
|
+
loserPath: skill.filePath
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
} else {
|
|
216
|
+
skillMap.set(skill.name, skill);
|
|
217
|
+
realPathSet.add(realPath);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
if (includeDefaults) {
|
|
222
|
+
const userSkillsDir = join(homedir(), CONFIG_DIR_NAME, "skills");
|
|
223
|
+
const projectSkillsDir = resolve(cwd, CONFIG_DIR_NAME, "skills");
|
|
224
|
+
addSkills(loadSkillsFromDirInternal(userSkillsDir, "user", true));
|
|
225
|
+
addSkills(loadSkillsFromDirInternal(projectSkillsDir, "project", true));
|
|
226
|
+
}
|
|
227
|
+
for (const rawPath of skillPaths) {
|
|
228
|
+
const resolvedPath = resolveSkillPath(rawPath, cwd);
|
|
229
|
+
if (!existsSync(resolvedPath)) {
|
|
230
|
+
allDiagnostics.push({ type: "warning", message: "skill path does not exist", path: resolvedPath });
|
|
231
|
+
continue;
|
|
232
|
+
}
|
|
233
|
+
try {
|
|
234
|
+
const stats = statSync(resolvedPath);
|
|
235
|
+
if (stats.isDirectory()) {
|
|
236
|
+
addSkills(loadSkillsFromDirInternal(resolvedPath, "path", true));
|
|
237
|
+
} else if (stats.isFile() && resolvedPath.endsWith(".md")) {
|
|
238
|
+
const result = loadSkillFromFile(resolvedPath, "path");
|
|
239
|
+
if (result.skill) {
|
|
240
|
+
addSkills({ skills: [result.skill], diagnostics: result.diagnostics });
|
|
241
|
+
} else {
|
|
242
|
+
allDiagnostics.push(...result.diagnostics);
|
|
243
|
+
}
|
|
244
|
+
} else {
|
|
245
|
+
allDiagnostics.push({ type: "warning", message: "skill path is not a markdown file", path: resolvedPath });
|
|
246
|
+
}
|
|
247
|
+
} catch (error) {
|
|
248
|
+
const message = error instanceof Error ? error.message : "failed to read skill path";
|
|
249
|
+
allDiagnostics.push({ type: "warning", message, path: resolvedPath });
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return {
|
|
253
|
+
skills: Array.from(skillMap.values()),
|
|
254
|
+
diagnostics: [...allDiagnostics, ...collisionDiagnostics]
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
function escapeXml(str) {
|
|
258
|
+
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
259
|
+
}
|
|
260
|
+
function formatSkillsForPrompt(skills) {
|
|
261
|
+
const visibleSkills = skills.filter((s) => !s.disableModelInvocation);
|
|
262
|
+
if (visibleSkills.length === 0) {
|
|
263
|
+
return "";
|
|
264
|
+
}
|
|
265
|
+
const lines = [
|
|
266
|
+
"The following skills provide specialized instructions for specific tasks.",
|
|
267
|
+
"Use the read tool to load a skill's file when the task matches its description.",
|
|
268
|
+
"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.",
|
|
269
|
+
"",
|
|
270
|
+
"<available_skills>"
|
|
271
|
+
];
|
|
272
|
+
for (const skill of visibleSkills) {
|
|
273
|
+
lines.push(" <skill>");
|
|
274
|
+
lines.push(` <name>${escapeXml(skill.name)}</name>`);
|
|
275
|
+
lines.push(` <description>${escapeXml(skill.description)}</description>`);
|
|
276
|
+
lines.push(` <location>${escapeXml(skill.filePath)}</location>`);
|
|
277
|
+
lines.push(" </skill>");
|
|
278
|
+
}
|
|
279
|
+
lines.push("</available_skills>");
|
|
280
|
+
return lines.join(`
|
|
281
|
+
`);
|
|
282
|
+
}
|
|
15
283
|
// src/utils/system-prompt.ts
|
|
16
|
-
import { readFileSync } from "fs";
|
|
17
|
-
import { join } from "path";
|
|
284
|
+
import { readFileSync as readFileSync2 } from "fs";
|
|
285
|
+
import { join as join2 } from "path";
|
|
18
286
|
var CORE_IDENTITY = `You are an AI coding agent. You help users with software engineering tasks by reading, writing, and modifying code. You have access to tools that let you interact with the filesystem and execute commands.
|
|
19
287
|
|
|
20
288
|
You are highly capable and can help users complete complex tasks that would otherwise be too difficult or time-consuming.`;
|
|
@@ -85,6 +353,14 @@ Working directory: ${context.cwd}`);
|
|
|
85
353
|
${instructions}`);
|
|
86
354
|
}
|
|
87
355
|
}
|
|
356
|
+
if (context.skills && context.skills.length > 0) {
|
|
357
|
+
const skillsPrompt = formatSkillsForPrompt(context.skills);
|
|
358
|
+
if (skillsPrompt) {
|
|
359
|
+
sections.push(`# Skills
|
|
360
|
+
|
|
361
|
+
${skillsPrompt}`);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
88
364
|
if (context.customPrompt) {
|
|
89
365
|
sections.push(context.customPrompt);
|
|
90
366
|
}
|
|
@@ -95,7 +371,7 @@ ${instructions}`);
|
|
|
95
371
|
function readProjectInstructions(cwd) {
|
|
96
372
|
for (const name of ["CLAUDE.md", "AGENTS.md"]) {
|
|
97
373
|
try {
|
|
98
|
-
const content =
|
|
374
|
+
const content = readFileSync2(join2(cwd, name), "utf-8").trim();
|
|
99
375
|
if (content)
|
|
100
376
|
return content;
|
|
101
377
|
} catch {}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fourmis-agents-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Multi-provider AI agent SDK with direct API access and in-process tool execution",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -61,10 +61,11 @@
|
|
|
61
61
|
"test:integration": "bun test tests/integration.test.ts"
|
|
62
62
|
},
|
|
63
63
|
"dependencies": {
|
|
64
|
-
"@anthropic-ai/sdk": "^0.
|
|
64
|
+
"@anthropic-ai/sdk": "^0.74.0",
|
|
65
65
|
"@google/genai": "^1.40.0",
|
|
66
66
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
67
67
|
"openai": "^6.21.0",
|
|
68
|
+
"yaml": "^2.8.2",
|
|
68
69
|
"zod": "^3.24.0"
|
|
69
70
|
},
|
|
70
71
|
"devDependencies": {
|