developer-ai 1.0.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 +241 -0
- package/bin/developer-ai.js +2 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +219 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/index.d.ts +7 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +82 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/schema.d.ts +115 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +29 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/constants.d.ts +8 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +8 -0
- package/dist/constants.js.map +1 -0
- package/dist/core/agent.d.ts +38 -0
- package/dist/core/agent.d.ts.map +1 -0
- package/dist/core/agent.js +155 -0
- package/dist/core/agent.js.map +1 -0
- package/dist/core/system-prompt.d.ts +6 -0
- package/dist/core/system-prompt.d.ts.map +1 -0
- package/dist/core/system-prompt.js +44 -0
- package/dist/core/system-prompt.js.map +1 -0
- package/dist/core/types.d.ts +42 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +6 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/client.d.ts +13 -0
- package/dist/mcp/client.d.ts.map +1 -0
- package/dist/mcp/client.js +202 -0
- package/dist/mcp/client.js.map +1 -0
- package/dist/providers/ollama.d.ts +13 -0
- package/dist/providers/ollama.d.ts.map +1 -0
- package/dist/providers/ollama.js +60 -0
- package/dist/providers/ollama.js.map +1 -0
- package/dist/providers/openai.d.ts +9 -0
- package/dist/providers/openai.d.ts.map +1 -0
- package/dist/providers/openai.js +40 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/skills/loader.d.ts +25 -0
- package/dist/skills/loader.d.ts.map +1 -0
- package/dist/skills/loader.js +93 -0
- package/dist/skills/loader.js.map +1 -0
- package/dist/tests/tools.test.d.ts +2 -0
- package/dist/tests/tools.test.d.ts.map +1 -0
- package/dist/tests/tools.test.js +170 -0
- package/dist/tests/tools.test.js.map +1 -0
- package/dist/tools/index.d.ts +5 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +19 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/list-files.d.ts +3 -0
- package/dist/tools/list-files.d.ts.map +1 -0
- package/dist/tools/list-files.js +60 -0
- package/dist/tools/list-files.js.map +1 -0
- package/dist/tools/read-file.d.ts +3 -0
- package/dist/tools/read-file.d.ts.map +1 -0
- package/dist/tools/read-file.js +46 -0
- package/dist/tools/read-file.js.map +1 -0
- package/dist/tools/registry.d.ts +24 -0
- package/dist/tools/registry.d.ts.map +1 -0
- package/dist/tools/registry.js +37 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/run-command.d.ts +3 -0
- package/dist/tools/run-command.d.ts.map +1 -0
- package/dist/tools/run-command.js +114 -0
- package/dist/tools/run-command.js.map +1 -0
- package/dist/tools/search-text.d.ts +3 -0
- package/dist/tools/search-text.d.ts.map +1 -0
- package/dist/tools/search-text.js +103 -0
- package/dist/tools/search-text.js.map +1 -0
- package/dist/tools/utils.d.ts +6 -0
- package/dist/tools/utils.d.ts.map +1 -0
- package/dist/tools/utils.js +14 -0
- package/dist/tools/utils.js.map +1 -0
- package/dist/tools/web-search.d.ts +3 -0
- package/dist/tools/web-search.d.ts.map +1 -0
- package/dist/tools/web-search.js +80 -0
- package/dist/tools/web-search.js.map +1 -0
- package/dist/tools/write-file.d.ts +3 -0
- package/dist/tools/write-file.d.ts.map +1 -0
- package/dist/tools/write-file.js +66 -0
- package/dist/tools/write-file.js.map +1 -0
- package/package.json +54 -0
- package/skills/accessibility/SKILL.md +496 -0
- package/skills/api-design/SKILL.md +419 -0
- package/skills/code-review/SKILL.md +267 -0
- package/skills/debugging/SKILL.md +332 -0
- package/skills/documentation/SKILL.md +496 -0
- package/skills/error-handling/SKILL.md +504 -0
- package/skills/git-workflow/SKILL.md +448 -0
- package/skills/human-like-coding/SKILL.md +400 -0
- package/skills/performance-optimization/SKILL.md +412 -0
- package/skills/prompt-engineering/SKILL.md +362 -0
- package/skills/refactoring/SKILL.md +457 -0
- package/skills/security-audit/SKILL.md +453 -0
- package/skills/testing-strategy/SKILL.md +501 -0
- package/skills/webapp-testing/SKILL.md +309 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { glob } from 'glob';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
const schema = z.object({
|
|
6
|
+
query: z.string(),
|
|
7
|
+
globs: z.array(z.string()).optional(),
|
|
8
|
+
});
|
|
9
|
+
export const searchTextTool = {
|
|
10
|
+
name: 'search_text',
|
|
11
|
+
description: 'Search for text across workspace files using a string or regex pattern. ' +
|
|
12
|
+
'Returns matching lines with file paths and line numbers.',
|
|
13
|
+
schema,
|
|
14
|
+
jsonSchema: {
|
|
15
|
+
type: 'object',
|
|
16
|
+
properties: {
|
|
17
|
+
query: {
|
|
18
|
+
type: 'string',
|
|
19
|
+
description: 'Search string or regex pattern',
|
|
20
|
+
},
|
|
21
|
+
globs: {
|
|
22
|
+
type: 'array',
|
|
23
|
+
items: { type: 'string' },
|
|
24
|
+
description: 'Optional glob patterns to filter which files to search',
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
required: ['query'],
|
|
28
|
+
},
|
|
29
|
+
async execute(input, ctx) {
|
|
30
|
+
const { query, globs } = schema.parse(input);
|
|
31
|
+
try {
|
|
32
|
+
const patterns = globs ?? ['**/*'];
|
|
33
|
+
const allFiles = [];
|
|
34
|
+
for (const p of patterns) {
|
|
35
|
+
const found = await glob(p, {
|
|
36
|
+
cwd: ctx.workspaceDir,
|
|
37
|
+
nodir: true,
|
|
38
|
+
ignore: [
|
|
39
|
+
'node_modules/**',
|
|
40
|
+
'.git/**',
|
|
41
|
+
'dist/**',
|
|
42
|
+
'*.lock',
|
|
43
|
+
'*.png',
|
|
44
|
+
'*.jpg',
|
|
45
|
+
'*.gif',
|
|
46
|
+
'*.ico',
|
|
47
|
+
'*.woff*',
|
|
48
|
+
],
|
|
49
|
+
});
|
|
50
|
+
allFiles.push(...found);
|
|
51
|
+
}
|
|
52
|
+
const uniqueFiles = [...new Set(allFiles)];
|
|
53
|
+
let regex;
|
|
54
|
+
try {
|
|
55
|
+
regex = new RegExp(query, 'gi');
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
// If not valid regex, escape and use as literal
|
|
59
|
+
const escaped = query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
60
|
+
regex = new RegExp(escaped, 'gi');
|
|
61
|
+
}
|
|
62
|
+
const results = [];
|
|
63
|
+
const maxMatches = 60;
|
|
64
|
+
for (const file of uniqueFiles) {
|
|
65
|
+
if (results.length >= maxMatches)
|
|
66
|
+
break;
|
|
67
|
+
const fullPath = path.join(ctx.workspaceDir, file);
|
|
68
|
+
try {
|
|
69
|
+
const content = await fs.readFile(fullPath, 'utf-8');
|
|
70
|
+
const lines = content.split('\n');
|
|
71
|
+
for (let i = 0; i < lines.length; i++) {
|
|
72
|
+
if (results.length >= maxMatches)
|
|
73
|
+
break;
|
|
74
|
+
const line = lines[i];
|
|
75
|
+
regex.lastIndex = 0;
|
|
76
|
+
if (regex.test(line)) {
|
|
77
|
+
results.push(`${file}:${i + 1}: ${line.trim()}`);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// Skip binary or unreadable files
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (results.length === 0) {
|
|
86
|
+
return { success: true, output: 'No matches found.' };
|
|
87
|
+
}
|
|
88
|
+
let output = results.join('\n');
|
|
89
|
+
if (results.length >= maxMatches) {
|
|
90
|
+
output += '\n... (results truncated)';
|
|
91
|
+
}
|
|
92
|
+
return { success: true, output };
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
return {
|
|
96
|
+
success: false,
|
|
97
|
+
output: '',
|
|
98
|
+
error: `Search failed: ${err.message}`,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
};
|
|
103
|
+
//# sourceMappingURL=search-text.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-text.js","sourceRoot":"","sources":["../../src/tools/search-text.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/tools/utils.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,GACf,MAAM,GAAG,IAAI,CAOf"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
/**
|
|
3
|
+
* Resolve a user-supplied path against the workspace root,
|
|
4
|
+
* rejecting any path that escapes the workspace boundary.
|
|
5
|
+
*/
|
|
6
|
+
export function resolveSafePath(workspaceDir, filePath) {
|
|
7
|
+
const resolved = path.resolve(workspaceDir, filePath);
|
|
8
|
+
// Ensure the resolved path is within or equal to the workspace
|
|
9
|
+
if (!resolved.startsWith(workspaceDir + path.sep) && resolved !== workspaceDir) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
return resolved;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/tools/utils.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;GAGG;AACH,MAAM,UAAU,eAAe,CAC7B,YAAoB,EACpB,QAAgB;IAEhB,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;IACtD,+DAA+D;IAC/D,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,QAAQ,KAAK,YAAY,EAAE,CAAC;QAC/E,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-search.d.ts","sourceRoot":"","sources":["../../src/tools/web-search.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAe,MAAM,eAAe,CAAC;AA6C9D,eAAO,MAAM,aAAa,EAAE,WA+C3B,CAAC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { loadConfig } from '../config/index.js';
|
|
3
|
+
const schema = z.object({
|
|
4
|
+
query: z.string(),
|
|
5
|
+
});
|
|
6
|
+
// ---- Brave Search ----
|
|
7
|
+
async function searchBrave(query, apiKey) {
|
|
8
|
+
const url = `https://api.search.brave.com/res/v1/web/search?q=${encodeURIComponent(query)}&count=5`;
|
|
9
|
+
const resp = await fetch(url, {
|
|
10
|
+
headers: { 'X-Subscription-Token': apiKey, Accept: 'application/json' },
|
|
11
|
+
});
|
|
12
|
+
if (!resp.ok) {
|
|
13
|
+
throw new Error(`Brave API ${resp.status}: ${await resp.text()}`);
|
|
14
|
+
}
|
|
15
|
+
const data = (await resp.json());
|
|
16
|
+
const results = (data.web?.results ?? []).slice(0, 5);
|
|
17
|
+
return results
|
|
18
|
+
.map((r) => `**${r.title}**\n${r.url}\n${r.description ?? ''}`)
|
|
19
|
+
.join('\n\n');
|
|
20
|
+
}
|
|
21
|
+
// ---- Serper ----
|
|
22
|
+
async function searchSerper(query, apiKey) {
|
|
23
|
+
const resp = await fetch('https://google.serper.dev/search', {
|
|
24
|
+
method: 'POST',
|
|
25
|
+
headers: { 'X-API-KEY': apiKey, 'Content-Type': 'application/json' },
|
|
26
|
+
body: JSON.stringify({ q: query, num: 5 }),
|
|
27
|
+
});
|
|
28
|
+
if (!resp.ok) {
|
|
29
|
+
throw new Error(`Serper API ${resp.status}: ${await resp.text()}`);
|
|
30
|
+
}
|
|
31
|
+
const data = (await resp.json());
|
|
32
|
+
const results = (data.organic ?? []).slice(0, 5);
|
|
33
|
+
return results
|
|
34
|
+
.map((r) => `**${r.title}**\n${r.link}\n${r.snippet ?? ''}`)
|
|
35
|
+
.join('\n\n');
|
|
36
|
+
}
|
|
37
|
+
// ---- Tool handler ----
|
|
38
|
+
export const webSearchTool = {
|
|
39
|
+
name: 'web_search',
|
|
40
|
+
description: 'Search the web using a configured provider (Brave Search or Serper). ' +
|
|
41
|
+
'Returns top results with titles and snippets. Returns a structured error if no provider is configured.',
|
|
42
|
+
schema,
|
|
43
|
+
jsonSchema: {
|
|
44
|
+
type: 'object',
|
|
45
|
+
properties: {
|
|
46
|
+
query: { type: 'string', description: 'Search query' },
|
|
47
|
+
},
|
|
48
|
+
required: ['query'],
|
|
49
|
+
},
|
|
50
|
+
async execute(input, _ctx) {
|
|
51
|
+
const { query } = schema.parse(input);
|
|
52
|
+
const config = loadConfig();
|
|
53
|
+
const braveKey = config.webSearch.braveApiKey ?? process.env['BRAVE_SEARCH_API_KEY'];
|
|
54
|
+
const serperKey = config.webSearch.serperApiKey ?? process.env['SERPER_API_KEY'];
|
|
55
|
+
try {
|
|
56
|
+
if (braveKey) {
|
|
57
|
+
const output = await searchBrave(query, braveKey);
|
|
58
|
+
return { success: true, output };
|
|
59
|
+
}
|
|
60
|
+
if (serperKey) {
|
|
61
|
+
const output = await searchSerper(query, serperKey);
|
|
62
|
+
return { success: true, output };
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
success: false,
|
|
66
|
+
output: '',
|
|
67
|
+
error: 'Web search not configured. Set BRAVE_SEARCH_API_KEY or SERPER_API_KEY environment variable, ' +
|
|
68
|
+
'or run `developer-ai onboard` to configure.',
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
catch (err) {
|
|
72
|
+
return {
|
|
73
|
+
success: false,
|
|
74
|
+
output: '',
|
|
75
|
+
error: `Web search failed: ${err.message}`,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
//# sourceMappingURL=web-search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-search.js","sourceRoot":"","sources":["../../src/tools/web-search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAEhD,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC;IACtB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE;CAClB,CAAC,CAAC;AAEH,yBAAyB;AAEzB,KAAK,UAAU,WAAW,CAAC,KAAa,EAAE,MAAc;IACtD,MAAM,GAAG,GAAG,oDAAoD,kBAAkB,CAAC,KAAK,CAAC,UAAU,CAAC;IACpG,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;QAC5B,OAAO,EAAE,EAAE,sBAAsB,EAAE,MAAM,EAAE,MAAM,EAAE,kBAAkB,EAAE;KACxE,CAAC,CAAC;IACH,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,aAAa,IAAI,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACpE,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAkB,CAAC;IAClD,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACtD,OAAO,OAAO;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC;SAC9D,IAAI,CAAC,MAAM,CAAC,CAAC;AAClB,CAAC;AAED,mBAAmB;AAEnB,KAAK,UAAU,YAAY,CAAC,KAAa,EAAE,MAAc;IACvD,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,kCAAkC,EAAE;QAC3D,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,cAAc,EAAE,kBAAkB,EAAE;QACpE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;KAC3C,CAAC,CAAC;IACH,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,cAAc,IAAI,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACrE,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAmB,CAAC;IACnD,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACjD,OAAO,OAAO;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;SAC3D,IAAI,CAAC,MAAM,CAAC,CAAC;AAClB,CAAC;AAED,yBAAyB;AAEzB,MAAM,CAAC,MAAM,aAAa,GAAgB;IACxC,IAAI,EAAE,YAAY;IAClB,WAAW,EACT,uEAAuE;QACvE,wGAAwG;IAC1G,MAAM;IACN,UAAU,EAAE;QACV,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE;SACvD;QACD,QAAQ,EAAE,CAAC,OAAO,CAAC;KACpB;IAED,KAAK,CAAC,OAAO,CAAC,KAAc,EAAE,IAAiB;QAC7C,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACtC,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAE5B,MAAM,QAAQ,GACZ,MAAM,CAAC,SAAS,CAAC,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;QACtE,MAAM,SAAS,GACb,MAAM,CAAC,SAAS,CAAC,YAAY,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAEjE,IAAI,CAAC;YACH,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;gBAClD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;YACnC,CAAC;YACD,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;gBACpD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;YACnC,CAAC;YACD,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,MAAM,EAAE,EAAE;gBACV,KAAK,EACH,8FAA8F;oBAC9F,6CAA6C;aAChD,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,MAAM,EAAE,EAAE;gBACV,KAAK,EAAE,sBAAuB,GAAa,CAAC,OAAO,EAAE;aACtD,CAAC;QACJ,CAAC;IACH,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-file.d.ts","sourceRoot":"","sources":["../../src/tools/write-file.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAe,MAAM,eAAe,CAAC;AAU9D,eAAO,MAAM,aAAa,EAAE,WA4D3B,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
import { resolveSafePath } from './utils.js';
|
|
5
|
+
const schema = z.object({
|
|
6
|
+
path: z.string(),
|
|
7
|
+
content: z.string(),
|
|
8
|
+
confirmOverwrite: z.boolean().optional().default(false),
|
|
9
|
+
});
|
|
10
|
+
export const writeFileTool = {
|
|
11
|
+
name: 'write_file',
|
|
12
|
+
description: 'Write content to a file in the workspace. Creates parent directories automatically. ' +
|
|
13
|
+
'If the file already exists, set confirmOverwrite=true or the user will be prompted.',
|
|
14
|
+
schema,
|
|
15
|
+
jsonSchema: {
|
|
16
|
+
type: 'object',
|
|
17
|
+
properties: {
|
|
18
|
+
path: { type: 'string', description: 'Workspace-relative file path' },
|
|
19
|
+
content: { type: 'string', description: 'Full file content to write' },
|
|
20
|
+
confirmOverwrite: {
|
|
21
|
+
type: 'boolean',
|
|
22
|
+
description: 'Set true to confirm overwriting an existing file',
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
required: ['path', 'content'],
|
|
26
|
+
},
|
|
27
|
+
async execute(input, ctx) {
|
|
28
|
+
const { path: filePath, content, confirmOverwrite } = schema.parse(input);
|
|
29
|
+
const resolved = resolveSafePath(ctx.workspaceDir, filePath);
|
|
30
|
+
if (!resolved) {
|
|
31
|
+
return { success: false, output: '', error: 'Path escapes workspace directory' };
|
|
32
|
+
}
|
|
33
|
+
// Check if file exists and needs confirmation
|
|
34
|
+
let exists = false;
|
|
35
|
+
try {
|
|
36
|
+
await fs.access(resolved);
|
|
37
|
+
exists = true;
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
// File does not exist — safe to create
|
|
41
|
+
}
|
|
42
|
+
if (exists && !confirmOverwrite && !ctx.autoYes) {
|
|
43
|
+
const confirmed = await ctx.confirmFn(`File "${filePath}" already exists. Overwrite?`);
|
|
44
|
+
if (!confirmed) {
|
|
45
|
+
return { success: false, output: '', error: 'Overwrite cancelled by user' };
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
await fs.mkdir(path.dirname(resolved), { recursive: true });
|
|
50
|
+
await fs.writeFile(resolved, content, 'utf-8');
|
|
51
|
+
const lines = content.split('\n').length;
|
|
52
|
+
return {
|
|
53
|
+
success: true,
|
|
54
|
+
output: `Written: ${filePath} (${lines} lines, ${content.length} bytes)`,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
return {
|
|
59
|
+
success: false,
|
|
60
|
+
output: '',
|
|
61
|
+
error: `Cannot write file: ${err.message}`,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
//# sourceMappingURL=write-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-file.js","sourceRoot":"","sources":["../../src/tools/write-file.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "developer-ai",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A production-grade terminal AI coding assistant. Supports OpenAI and Ollama, MCP servers, web search, and agent skills.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"developer-ai": "./bin/developer-ai.js"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"dev": "tsc --watch",
|
|
14
|
+
"lint": "tsc --noEmit",
|
|
15
|
+
"test": "node --test dist/tests/*.test.js",
|
|
16
|
+
"pretest": "npm run build",
|
|
17
|
+
"prepublishOnly": "npm run build"
|
|
18
|
+
},
|
|
19
|
+
"engines": {
|
|
20
|
+
"node": ">=20.0.0"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"ai",
|
|
24
|
+
"coding-assistant",
|
|
25
|
+
"cli",
|
|
26
|
+
"openai",
|
|
27
|
+
"ollama",
|
|
28
|
+
"mcp",
|
|
29
|
+
"agent",
|
|
30
|
+
"terminal",
|
|
31
|
+
"copilot"
|
|
32
|
+
],
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"files": [
|
|
35
|
+
"dist/",
|
|
36
|
+
"bin/",
|
|
37
|
+
"skills/",
|
|
38
|
+
"README.md"
|
|
39
|
+
],
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"chalk": "^5.4.1",
|
|
42
|
+
"commander": "^13.1.0",
|
|
43
|
+
"glob": "^11.0.1",
|
|
44
|
+
"openai": "^4.86.2",
|
|
45
|
+
"zod": "^3.24.2"
|
|
46
|
+
},
|
|
47
|
+
"optionalDependencies": {
|
|
48
|
+
"@modelcontextprotocol/sdk": "^1.12.0"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@types/node": "^22.13.4",
|
|
52
|
+
"typescript": "^5.7.3"
|
|
53
|
+
}
|
|
54
|
+
}
|