micro-models-agent 0.2.63 → 0.2.65
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 +401 -354
- package/dist/agent/loop.d.ts.map +1 -1
- package/dist/agent/loop.js +254 -14
- package/dist/agent/loop.js.map +1 -1
- package/dist/agent/system-prompt.d.ts +16 -16
- package/dist/agent/system-prompt.d.ts.map +1 -1
- package/dist/agent/system-prompt.js +104 -67
- package/dist/agent/system-prompt.js.map +1 -1
- package/dist/agent/tool-executor.d.ts +2 -10
- package/dist/agent/tool-executor.d.ts.map +1 -1
- package/dist/agent/tool-executor.js +92 -1
- package/dist/agent/tool-executor.js.map +1 -1
- package/dist/async-map.d.ts +6 -0
- package/dist/async-map.d.ts.map +1 -0
- package/dist/async-map.js +16 -0
- package/dist/async-map.js.map +1 -0
- package/dist/blog-api/types/index.d.ts +2 -0
- package/dist/blog-api/types/index.d.ts.map +1 -0
- package/dist/blog-api/types/index.js +2 -0
- package/dist/blog-api/types/index.js.map +1 -0
- package/dist/cli/config.js +1 -1
- package/dist/cli/config.js.map +1 -1
- package/dist/cli.js +2 -2
- package/dist/cli.js.map +1 -1
- package/dist/config/config.d.ts +10 -0
- package/dist/config/config.d.ts.map +1 -1
- package/dist/config/config.js +29 -2
- package/dist/config/config.js.map +1 -1
- package/dist/config/types.d.ts +16 -1
- package/dist/config/types.d.ts.map +1 -1
- package/dist/examples.d.ts +22 -0
- package/dist/examples.d.ts.map +1 -0
- package/dist/examples.js +45 -0
- package/dist/examples.js.map +1 -0
- package/dist/fibonacci.d.ts +19 -0
- package/dist/fibonacci.d.ts.map +1 -0
- package/dist/fibonacci.js +61 -0
- package/dist/fibonacci.js.map +1 -0
- package/dist/llm/lmstudio-native.d.ts +10 -0
- package/dist/llm/lmstudio-native.d.ts.map +1 -0
- package/dist/llm/lmstudio-native.js +179 -0
- package/dist/llm/lmstudio-native.js.map +1 -0
- package/dist/llm/openai-compat.js +1 -1
- package/dist/plugins/builtin/lint-on-write/index.ts +96 -96
- package/dist/plugins/builtin/notify/index.js +6 -6
- package/dist/plugins/builtin/notify/index.ts +104 -104
- package/dist/repl.d.ts +5 -0
- package/dist/repl.d.ts.map +1 -0
- package/dist/repl.js +472 -0
- package/dist/repl.js.map +1 -0
- package/dist/skills/builtin/agent-test/SKILL.md +68 -68
- package/dist/skills/builtin/grill-me/SKILL.md +46 -46
- package/dist/sort.d.ts +8 -0
- package/dist/sort.d.ts.map +1 -0
- package/dist/sort.js +36 -0
- package/dist/sort.js.map +1 -0
- package/dist/stack.d.ts +9 -0
- package/dist/stack.d.ts.map +1 -0
- package/dist/stack.js +22 -0
- package/dist/stack.js.map +1 -0
- package/dist/test-run.d.ts +2 -0
- package/dist/test-run.d.ts.map +1 -0
- package/dist/test-run.js +13 -0
- package/dist/test-run.js.map +1 -0
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +19 -0
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/fs/write-file.d.ts.map +1 -1
- package/dist/tools/fs/write-file.js +13 -2
- package/dist/tools/fs/write-file.js.map +1 -1
- package/dist/tools/native/plan.d.ts +1 -1
- package/dist/tools/native/plan.d.ts.map +1 -1
- package/dist/tools/native/plan.js +85 -16
- package/dist/tools/native/plan.js.map +1 -1
- package/dist/tools/native/scaffold.d.ts +5 -0
- package/dist/tools/native/scaffold.d.ts.map +1 -0
- package/dist/tools/native/scaffold.js +246 -0
- package/dist/tools/native/scaffold.js.map +1 -0
- package/dist/tools/plan.d.ts +9 -0
- package/dist/tools/plan.d.ts.map +1 -1
- package/dist/tools/plan.js +27 -2
- package/dist/tools/plan.js.map +1 -1
- package/dist/tools/registry.d.ts.map +1 -1
- package/dist/tools/registry.js +3 -0
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/subagent.d.ts +16 -1
- package/dist/tools/subagent.d.ts.map +1 -1
- package/dist/tools/subagent.js +99 -10
- package/dist/tools/subagent.js.map +1 -1
- package/dist/ui/components/diff-view.d.ts +8 -0
- package/dist/ui/components/diff-view.d.ts.map +1 -0
- package/dist/ui/components/diff-view.js +25 -0
- package/dist/ui/components/diff-view.js.map +1 -0
- package/dist/ui/double-press.d.ts +9 -0
- package/dist/ui/double-press.d.ts.map +1 -0
- package/dist/ui/double-press.js +18 -0
- package/dist/ui/double-press.js.map +1 -0
- package/dist/ui/opentui-renderer.d.ts +53 -0
- package/dist/ui/opentui-renderer.d.ts.map +1 -0
- package/dist/ui/opentui-renderer.js +463 -0
- package/dist/ui/opentui-renderer.js.map +1 -0
- package/dist/utils/memoize.d.ts +14 -0
- package/dist/utils/memoize.d.ts.map +1 -0
- package/dist/utils/memoize.js +51 -0
- package/dist/utils/memoize.js.map +1 -0
- package/dist/utils/types.d.ts +6 -0
- package/dist/utils/types.d.ts.map +1 -0
- package/dist/utils/types.js +2 -0
- package/dist/utils/types.js.map +1 -0
- package/dist/utils.d.ts +22 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +81 -0
- package/dist/utils.js.map +1 -0
- package/package.json +2 -2
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { writeFileSync, mkdirSync } from 'node:fs';
|
|
2
|
+
import { join, dirname } from 'node:path';
|
|
3
|
+
import { resolvePath, normalizePath } from '../fs/path-utils.js';
|
|
4
|
+
import { fsError, fsOk } from '../fs/types.js';
|
|
5
|
+
const TEMPLATES = {
|
|
6
|
+
'vite-react-ts': {
|
|
7
|
+
name: 'Vite + React + TypeScript',
|
|
8
|
+
files: {
|
|
9
|
+
'package.json': (dir) => JSON.stringify({
|
|
10
|
+
name: dir || 'app',
|
|
11
|
+
private: true,
|
|
12
|
+
version: '0.0.0',
|
|
13
|
+
type: 'module',
|
|
14
|
+
scripts: { dev: 'vite', build: 'tsc -b && vite build', preview: 'vite preview' },
|
|
15
|
+
dependencies: { react: '^19.0.0', 'react-dom': '^19.0.0' },
|
|
16
|
+
devDependencies: {
|
|
17
|
+
'@types/react': '^19.0.0',
|
|
18
|
+
'@types/react-dom': '^19.0.0',
|
|
19
|
+
'@vitejs/plugin-react': '^4.3.0',
|
|
20
|
+
typescript: '^5.7.0',
|
|
21
|
+
vite: '^6.0.0',
|
|
22
|
+
},
|
|
23
|
+
}, null, 2),
|
|
24
|
+
'vite.config.ts': `import { defineConfig } from 'vite'
|
|
25
|
+
import react from '@vitejs/plugin-react'
|
|
26
|
+
|
|
27
|
+
export default defineConfig({
|
|
28
|
+
plugins: [react()],
|
|
29
|
+
})
|
|
30
|
+
`,
|
|
31
|
+
'tsconfig.json': `{
|
|
32
|
+
"compilerOptions": {
|
|
33
|
+
"target": "ES2020",
|
|
34
|
+
"useDefineForClassFields": true,
|
|
35
|
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
36
|
+
"module": "ESNext",
|
|
37
|
+
"skipLibCheck": true,
|
|
38
|
+
"moduleResolution": "bundler",
|
|
39
|
+
"allowImportingTsExtensions": true,
|
|
40
|
+
"isolatedModules": true,
|
|
41
|
+
"moduleDetection": "force",
|
|
42
|
+
"noEmit": true,
|
|
43
|
+
"jsx": "react-jsx",
|
|
44
|
+
"strict": true,
|
|
45
|
+
"noUnusedLocals": true,
|
|
46
|
+
"noUnusedParameters": true,
|
|
47
|
+
"noFallthroughCasesInSwitch": true
|
|
48
|
+
},
|
|
49
|
+
"include": ["src"]
|
|
50
|
+
}
|
|
51
|
+
`,
|
|
52
|
+
'index.html': `<!DOCTYPE html>
|
|
53
|
+
<html lang="en">
|
|
54
|
+
<head>
|
|
55
|
+
<meta charset="UTF-8" />
|
|
56
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
57
|
+
<title>Vite App</title>
|
|
58
|
+
</head>
|
|
59
|
+
<body>
|
|
60
|
+
<div id="root"></div>
|
|
61
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
62
|
+
</body>
|
|
63
|
+
</html>
|
|
64
|
+
`,
|
|
65
|
+
'src/main.tsx': `import { StrictMode } from 'react'
|
|
66
|
+
import { createRoot } from 'react-dom/client'
|
|
67
|
+
import App from './App'
|
|
68
|
+
|
|
69
|
+
createRoot(document.getElementById('root')!).render(
|
|
70
|
+
<StrictMode>
|
|
71
|
+
<App />
|
|
72
|
+
</StrictMode>,
|
|
73
|
+
)
|
|
74
|
+
`,
|
|
75
|
+
'src/App.tsx': `function App() {
|
|
76
|
+
return (
|
|
77
|
+
<div>
|
|
78
|
+
<h1>Hello Vite + React</h1>
|
|
79
|
+
</div>
|
|
80
|
+
)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export default App
|
|
84
|
+
`,
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
'vite-vanilla-ts': {
|
|
88
|
+
name: 'Vite + Vanilla TypeScript',
|
|
89
|
+
files: {
|
|
90
|
+
'package.json': (dir) => JSON.stringify({
|
|
91
|
+
name: dir || 'app',
|
|
92
|
+
private: true,
|
|
93
|
+
version: '0.0.0',
|
|
94
|
+
type: 'module',
|
|
95
|
+
scripts: { dev: 'vite', build: 'tsc && vite build', preview: 'vite preview' },
|
|
96
|
+
devDependencies: { typescript: '^5.7.0', vite: '^6.0.0' },
|
|
97
|
+
}, null, 2),
|
|
98
|
+
'vite.config.ts': `import { defineConfig } from 'vite'
|
|
99
|
+
|
|
100
|
+
export default defineConfig({})
|
|
101
|
+
`,
|
|
102
|
+
'tsconfig.json': `{
|
|
103
|
+
"compilerOptions": {
|
|
104
|
+
"target": "ES2020",
|
|
105
|
+
"useDefineForClassFields": true,
|
|
106
|
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
107
|
+
"module": "ESNext",
|
|
108
|
+
"skipLibCheck": true,
|
|
109
|
+
"moduleResolution": "bundler",
|
|
110
|
+
"allowImportingTsExtensions": true,
|
|
111
|
+
"isolatedModules": true,
|
|
112
|
+
"moduleDetection": "force",
|
|
113
|
+
"noEmit": true,
|
|
114
|
+
"strict": true
|
|
115
|
+
},
|
|
116
|
+
"include": ["src"]
|
|
117
|
+
}
|
|
118
|
+
`,
|
|
119
|
+
'index.html': `<!DOCTYPE html>
|
|
120
|
+
<html lang="en">
|
|
121
|
+
<head>
|
|
122
|
+
<meta charset="UTF-8" />
|
|
123
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
124
|
+
<title>Vite App</title>
|
|
125
|
+
</head>
|
|
126
|
+
<body>
|
|
127
|
+
<div id="root"></div>
|
|
128
|
+
<script type="module" src="/src/main.ts"></script>
|
|
129
|
+
</body>
|
|
130
|
+
</html>
|
|
131
|
+
`,
|
|
132
|
+
'src/main.ts': `console.log('Hello from Vite!')
|
|
133
|
+
`,
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
'node-express-ts': {
|
|
137
|
+
name: 'Node.js + Express + TypeScript',
|
|
138
|
+
files: {
|
|
139
|
+
'package.json': (dir) => JSON.stringify({
|
|
140
|
+
name: dir || 'app',
|
|
141
|
+
private: true,
|
|
142
|
+
version: '0.0.0',
|
|
143
|
+
type: 'module',
|
|
144
|
+
scripts: { dev: 'tsx watch src/index.ts', build: 'tsc', start: 'node dist/index.js' },
|
|
145
|
+
dependencies: { express: '^4.21.0' },
|
|
146
|
+
devDependencies: {
|
|
147
|
+
'@types/express': '^5.0.0',
|
|
148
|
+
'@types/node': '^22.0.0',
|
|
149
|
+
typescript: '^5.7.0',
|
|
150
|
+
tsx: '^4.0.0',
|
|
151
|
+
},
|
|
152
|
+
}, null, 2),
|
|
153
|
+
'tsconfig.json': `{
|
|
154
|
+
"compilerOptions": {
|
|
155
|
+
"target": "ES2022",
|
|
156
|
+
"module": "ESNext",
|
|
157
|
+
"moduleResolution": "bundler",
|
|
158
|
+
"outDir": "dist",
|
|
159
|
+
"rootDir": "src",
|
|
160
|
+
"strict": true,
|
|
161
|
+
"esModuleInterop": true,
|
|
162
|
+
"skipLibCheck": true
|
|
163
|
+
},
|
|
164
|
+
"include": ["src"]
|
|
165
|
+
}
|
|
166
|
+
`,
|
|
167
|
+
'src/index.ts': `import express from 'express'
|
|
168
|
+
|
|
169
|
+
const app = express()
|
|
170
|
+
const PORT = process.env.PORT || 3000
|
|
171
|
+
|
|
172
|
+
app.get('/', (req, res) => {
|
|
173
|
+
res.json({ message: 'Hello from Express!' })
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
app.listen(PORT, () => {
|
|
177
|
+
console.log(\`Server running on port \${PORT}\`)
|
|
178
|
+
})
|
|
179
|
+
`,
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
};
|
|
183
|
+
export const scaffoldDefinition = {
|
|
184
|
+
type: 'function',
|
|
185
|
+
function: {
|
|
186
|
+
name: 'scaffold',
|
|
187
|
+
description: 'Create a complete project structure programmatically. Supports: vite-react-ts, vite-vanilla-ts, node-express-ts. Creates all files at once (package.json, config, source files). Use this INSTEAD of creating files manually for known project types.',
|
|
188
|
+
parameters: {
|
|
189
|
+
type: 'object',
|
|
190
|
+
properties: {
|
|
191
|
+
template: {
|
|
192
|
+
type: 'string',
|
|
193
|
+
enum: ['vite-react-ts', 'vite-vanilla-ts', 'node-express-ts'],
|
|
194
|
+
description: 'Project template to scaffold',
|
|
195
|
+
},
|
|
196
|
+
dir: {
|
|
197
|
+
type: 'string',
|
|
198
|
+
description: 'Directory name for the project (e.g. "todo-app")',
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
required: ['template', 'dir'],
|
|
202
|
+
},
|
|
203
|
+
},
|
|
204
|
+
};
|
|
205
|
+
export const scaffoldHandler = {
|
|
206
|
+
name: 'scaffold',
|
|
207
|
+
definition: scaffoldDefinition,
|
|
208
|
+
async execute(args, ctx) {
|
|
209
|
+
const template = String(args.template ?? '');
|
|
210
|
+
const dir = String(args.dir ?? '');
|
|
211
|
+
if (!template || !TEMPLATES[template]) {
|
|
212
|
+
return fsError(`Unknown template: "${template}". Available: ${Object.keys(TEMPLATES).join(', ')}`);
|
|
213
|
+
}
|
|
214
|
+
if (!dir) {
|
|
215
|
+
return fsError('dir is required. Usage: scaffold({template:"vite-react-ts", dir:"todo-app"})');
|
|
216
|
+
}
|
|
217
|
+
const resolved = resolvePath(dir, ctx.cwd);
|
|
218
|
+
if (!resolved.ok)
|
|
219
|
+
return fsError(resolved.error);
|
|
220
|
+
const projectDir = resolved.abs;
|
|
221
|
+
const tmpl = TEMPLATES[template];
|
|
222
|
+
const createdFiles = [];
|
|
223
|
+
try {
|
|
224
|
+
// Create project directory
|
|
225
|
+
mkdirSync(projectDir, { recursive: true });
|
|
226
|
+
for (const [relPath, content] of Object.entries(tmpl.files)) {
|
|
227
|
+
const filePath = join(projectDir, relPath);
|
|
228
|
+
const fileDir = dirname(filePath);
|
|
229
|
+
// Create parent directories
|
|
230
|
+
mkdirSync(fileDir, { recursive: true });
|
|
231
|
+
// Generate content (some files need the dir name)
|
|
232
|
+
const fileContent = typeof content === 'function'
|
|
233
|
+
? content(dir)
|
|
234
|
+
: content;
|
|
235
|
+
writeFileSync(filePath, fileContent, 'utf-8');
|
|
236
|
+
createdFiles.push(relPath);
|
|
237
|
+
}
|
|
238
|
+
const fileList = createdFiles.map(f => ` ✅ ${f}`).join('\n');
|
|
239
|
+
return fsOk(`Scaffolded ${tmpl.name} project in ${normalizePath(dir)}/\n\nCreated ${createdFiles.length} files:\n${fileList}\n\nNext steps:\n cd ${dir}\n npm install\n npm run dev`);
|
|
240
|
+
}
|
|
241
|
+
catch (e) {
|
|
242
|
+
return fsError(`Scaffold failed: ${e.message}`);
|
|
243
|
+
}
|
|
244
|
+
},
|
|
245
|
+
};
|
|
246
|
+
//# sourceMappingURL=scaffold.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../../../src/tools/native/scaffold.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/plan.d.ts
CHANGED
|
@@ -21,6 +21,15 @@ export declare function showPlan(): string;
|
|
|
21
21
|
export declare function clearPlan(): string;
|
|
22
22
|
/** Возвращает количество незавершённых шагов плана (0 = все готово или нет плана) */
|
|
23
23
|
export declare function getPlanPendingCount(): number;
|
|
24
|
+
/** Возвращает заголовок шага плана по его ID (или null если плана нет/шаг не найден) */
|
|
25
|
+
export declare function getPlanStepTitle(stepId: number): string | null;
|
|
26
|
+
/** Возвращает следующий pending шаг плана (или null) */
|
|
27
|
+
export declare function getNextPendingStep(): PlanStep | null;
|
|
28
|
+
/** Извлекает ожидаемую директорию из заголовка шага.
|
|
29
|
+
* Например: "Create todo-app/package.json" → "todo-app"
|
|
30
|
+
* "Создать index.html в src/" → "src"
|
|
31
|
+
* Возвращает null если директория не найдена. */
|
|
32
|
+
export declare function extractDirFromStepTitle(title: string): string | null;
|
|
24
33
|
/** Парсит аргументы команды plan (create, done, progress, show, clear) */
|
|
25
34
|
export declare function parsePlanCommand(args: string): {
|
|
26
35
|
action: string;
|
package/dist/tools/plan.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../src/tools/plan.ts"],"names":[],"mappings":"AAmBA,gBAAgB;AAChB,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,SAAS,GAAG,aAAa,GAAG,MAAM,GAAG,SAAS,CAAC;CACxD;AAED,kBAAkB;AAClB,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAuBD,6CAA6C;AAC7C,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAahE;AAED,kCAAkC;AAClC,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,GAAG,MAAM,CAWjF;AAED,2CAA2C;AAC3C,wBAAgB,QAAQ,IAAI,MAAM,CAIjC;AAED,2BAA2B;AAC3B,wBAAgB,SAAS,IAAI,MAAM,CAKlC;AAED,qFAAqF;AACrF,wBAAgB,mBAAmB,IAAI,MAAM,CAI5C;AAqBD,0EAA0E;AAC1E,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAKnF"}
|
|
1
|
+
{"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../src/tools/plan.ts"],"names":[],"mappings":"AAmBA,gBAAgB;AAChB,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,SAAS,GAAG,aAAa,GAAG,MAAM,GAAG,SAAS,CAAC;CACxD;AAED,kBAAkB;AAClB,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAuBD,6CAA6C;AAC7C,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAahE;AAED,kCAAkC;AAClC,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,GAAG,MAAM,CAWjF;AAED,2CAA2C;AAC3C,wBAAgB,QAAQ,IAAI,MAAM,CAIjC;AAED,2BAA2B;AAC3B,wBAAgB,SAAS,IAAI,MAAM,CAKlC;AAED,qFAAqF;AACrF,wBAAgB,mBAAmB,IAAI,MAAM,CAI5C;AAED,wFAAwF;AACxF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAK9D;AAED,wDAAwD;AACxD,wBAAgB,kBAAkB,IAAI,QAAQ,GAAG,IAAI,CAIpD;AAED;;;kDAGkD;AAClD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAKpE;AAqBD,0EAA0E;AAC1E,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAKnF"}
|
package/dist/tools/plan.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
|
|
1
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync, unlinkSync } from 'node:fs';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { homedir } from 'node:os';
|
|
4
4
|
import { getTheme } from '../styling/index.js';
|
|
@@ -75,7 +75,7 @@ export function clearPlan() {
|
|
|
75
75
|
if (!plan)
|
|
76
76
|
return 'No active plan to clear.';
|
|
77
77
|
try {
|
|
78
|
-
|
|
78
|
+
unlinkSync(PLAN_FILE);
|
|
79
79
|
}
|
|
80
80
|
catch { /* ignore */ }
|
|
81
81
|
return `Plan "${plan.name}" cleared.`;
|
|
@@ -87,6 +87,31 @@ export function getPlanPendingCount() {
|
|
|
87
87
|
return 0;
|
|
88
88
|
return plan.steps.filter(s => s.status !== 'done' && s.status !== 'skipped').length;
|
|
89
89
|
}
|
|
90
|
+
/** Возвращает заголовок шага плана по его ID (или null если плана нет/шаг не найден) */
|
|
91
|
+
export function getPlanStepTitle(stepId) {
|
|
92
|
+
const plan = loadPlan();
|
|
93
|
+
if (!plan)
|
|
94
|
+
return null;
|
|
95
|
+
const step = plan.steps.find(s => s.id === stepId);
|
|
96
|
+
return step?.title ?? null;
|
|
97
|
+
}
|
|
98
|
+
/** Возвращает следующий pending шаг плана (или null) */
|
|
99
|
+
export function getNextPendingStep() {
|
|
100
|
+
const plan = loadPlan();
|
|
101
|
+
if (!plan)
|
|
102
|
+
return null;
|
|
103
|
+
return plan.steps.find(s => s.status === 'pending') ?? null;
|
|
104
|
+
}
|
|
105
|
+
/** Извлекает ожидаемую директорию из заголовка шага.
|
|
106
|
+
* Например: "Create todo-app/package.json" → "todo-app"
|
|
107
|
+
* "Создать index.html в src/" → "src"
|
|
108
|
+
* Возвращает null если директория не найдена. */
|
|
109
|
+
export function extractDirFromStepTitle(title) {
|
|
110
|
+
// Паттерн: "Create dir/file" или "Создать file в dir/"
|
|
111
|
+
const match = title.match(/(?:Create|Создать|Add|Добавить)\s+(\w[\w-]*)\//i)
|
|
112
|
+
|| title.match(/(?:Create|Создать|Add|Добавить)\s+\S+\s+(?:in|в)\s+(\w[\w-]*)\//i);
|
|
113
|
+
return match?.[1] ?? null;
|
|
114
|
+
}
|
|
90
115
|
/** Форматирует план для отображения (с иконками и прогрессом) */
|
|
91
116
|
function formatPlan(plan) {
|
|
92
117
|
const theme = getTheme();
|
package/dist/tools/plan.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../src/tools/plan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../src/tools/plan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACzF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAE/C;;;;;;;;;GASG;AAEH,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,EAAE,mBAAmB,CAAC,CAAC;AAiBtD,uDAAuD;AACvD,SAAS,SAAS;IAChB,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AACtE,CAAC;AAED,sCAAsC;AACtC,SAAS,QAAQ;IACf,IAAI,CAAC;QACH,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC1B,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IACxB,OAAO,IAAI,CAAC;AACd,CAAC;AAED,4BAA4B;AAC5B,SAAS,QAAQ,CAAC,IAAU;IAC1B,SAAS,EAAE,CAAC;IACZ,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;AACnE,CAAC;AAED,6CAA6C;AAC7C,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,KAAe;IACtD,MAAM,IAAI,GAAS;QACjB,IAAI;QACJ,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;YAC9B,EAAE,EAAE,CAAC,GAAG,CAAC;YACT,KAAK;YACL,MAAM,EAAE,SAAkB;SAC3B,CAAC,CAAC;QACH,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC;IACF,QAAQ,CAAC,IAAI,CAAC,CAAC;IACf,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,kCAAkC;AAClC,MAAM,UAAU,cAAc,CAAC,MAAc,EAAE,MAA0B;IACvE,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAC;IACxB,IAAI,CAAC,IAAI;QAAE,OAAO,qDAAqD,CAAC;IAExE,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;IACnD,IAAI,CAAC,IAAI;QAAE,OAAO,QAAQ,MAAM,aAAa,CAAC;IAE9C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACrB,IAAI,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC1C,QAAQ,CAAC,IAAI,CAAC,CAAC;IACf,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,2CAA2C;AAC3C,MAAM,UAAU,QAAQ;IACtB,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAC;IACxB,IAAI,CAAC,IAAI;QAAE,OAAO,+CAA+C,CAAC;IAClE,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,2BAA2B;AAC3B,MAAM,UAAU,SAAS;IACvB,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAC;IACxB,IAAI,CAAC,IAAI;QAAE,OAAO,0BAA0B,CAAC;IAC7C,IAAI,CAAC;QAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IACrD,OAAO,SAAS,IAAI,CAAC,IAAI,YAAY,CAAC;AACxC,CAAC;AAED,qFAAqF;AACrF,MAAM,UAAU,mBAAmB;IACjC,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAC;IACxB,IAAI,CAAC,IAAI;QAAE,OAAO,CAAC,CAAC;IACpB,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,MAAM,CAAC;AACtF,CAAC;AAED,wFAAwF;AACxF,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAC7C,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAC;IACxB,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;IACnD,OAAO,IAAI,EAAE,KAAK,IAAI,IAAI,CAAC;AAC7B,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,kBAAkB;IAChC,MAAM,IAAI,GAAG,QAAQ,EAAE,CAAC;IACxB,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,IAAI,IAAI,CAAC;AAC9D,CAAC;AAED;;;kDAGkD;AAClD,MAAM,UAAU,uBAAuB,CAAC,KAAa;IACnD,uDAAuD;IACvD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,iDAAiD,CAAC;WACvE,KAAK,CAAC,KAAK,CAAC,kEAAkE,CAAC,CAAC;IACrF,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AAC5B,CAAC;AAED,iEAAiE;AACjE,SAAS,UAAU,CAAC,IAAU;IAC5B,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IACzB,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;IAChE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;IAChC,MAAM,QAAQ,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAElE,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,SAAS,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,IAAI,KAAK,IAAI,QAAQ,IAAI,CAAC,CAAC;IACrF,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACzC,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC;IAClC,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC9B,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AAC5B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAiBtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE5C;;;;;;;GAOG;AAEH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACrC,CAAC;CACH;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,MAAM,UAAU,GAAG,UAAU,CAAC;AA4CpC;;;GAGG;AACH,qBAAa,YAAY;IACvB,2EAA2E;IAC3E,cAAc,IAAI,cAAc,EAAE;IAIlC,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO;IAIzC,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;CAGnC"}
|
package/dist/tools/registry.js
CHANGED
|
@@ -2,6 +2,7 @@ import { readFileDefinition } from './fs/read-file.js';
|
|
|
2
2
|
import { writeFileDefinition } from './fs/write-file.js';
|
|
3
3
|
import { editFileDefinition } from './fs/edit-file.js';
|
|
4
4
|
import { listDirDefinition } from './fs/list-dir.js';
|
|
5
|
+
import { scaffoldDefinition } from './native/scaffold.js';
|
|
5
6
|
import { createDirDefinition } from './fs/create-dir.js';
|
|
6
7
|
import { deleteFileDefinition } from './fs/delete-file.js';
|
|
7
8
|
import { copyFileDefinition } from './fs/copy-file.js';
|
|
@@ -33,6 +34,8 @@ const ALL_DEFINITIONS = [
|
|
|
33
34
|
},
|
|
34
35
|
// Bash
|
|
35
36
|
bashDefinition,
|
|
37
|
+
// Scaffold
|
|
38
|
+
scaffoldDefinition,
|
|
36
39
|
// FS
|
|
37
40
|
readFileDefinition,
|
|
38
41
|
writeFileDefinition,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AA6BpD,uDAAuD;AACvD,MAAM,eAAe,GAAqB;IACxC,SAAS;IACT;QACE,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE;YACR,IAAI,EAAE,UAAU;YAChB,WAAW,EAAE,6MAA6M;YAC1N,UAAU,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,2CAA2C,EAAE;oBAClF,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,oEAAoE,EAAE;iBACrH;gBACD,QAAQ,EAAE,CAAC,MAAM,CAAC;aACnB;SACF;KACF;IACD,OAAO;IACP,cAAc;IACd,KAAK;IACL,kBAAkB;IAClB,mBAAmB;IACnB,kBAAkB;IAClB,iBAAiB;IACjB,mBAAmB;IACnB,oBAAoB;IACpB,kBAAkB;IAClB,kBAAkB;IAClB,kBAAkB;IAClB,oBAAoB;IACpB,oBAAoB;IACpB,cAAc;IACd,MAAM;IACN,mBAAmB;IACnB,kBAAkB;CACnB,CAAC;AAEF,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AAE5E;;;GAGG;AACH,MAAM,OAAO,YAAY;IACvB,2EAA2E;IAC3E,cAAc;QACZ,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,UAAU,CAAC,OAAoB;QAC7B,OAAO,OAAO,CAAC,IAAI,KAAK,WAAW,IAAI,OAAO,CAAC,OAAO,KAAK,EAAE,CAAC;IAChE,CAAC;IAED,WAAW,CAAC,IAAY;QACtB,OAAO,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;CACF"}
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AA6BpD,uDAAuD;AACvD,MAAM,eAAe,GAAqB;IACxC,SAAS;IACT;QACE,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE;YACR,IAAI,EAAE,UAAU;YAChB,WAAW,EAAE,6MAA6M;YAC1N,UAAU,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,UAAU,EAAE;oBACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,2CAA2C,EAAE;oBAClF,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,oEAAoE,EAAE;iBACrH;gBACD,QAAQ,EAAE,CAAC,MAAM,CAAC;aACnB;SACF;KACF;IACD,OAAO;IACP,cAAc;IACd,WAAW;IACX,kBAAkB;IAClB,KAAK;IACL,kBAAkB;IAClB,mBAAmB;IACnB,kBAAkB;IAClB,iBAAiB;IACjB,mBAAmB;IACnB,oBAAoB;IACpB,kBAAkB;IAClB,kBAAkB;IAClB,kBAAkB;IAClB,oBAAoB;IACpB,oBAAoB;IACpB,cAAc;IACd,MAAM;IACN,mBAAmB;IACnB,kBAAkB;CACnB,CAAC;AAEF,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AAE5E;;;GAGG;AACH,MAAM,OAAO,YAAY;IACvB,2EAA2E;IAC3E,cAAc;QACZ,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,UAAU,CAAC,OAAoB;QAC7B,OAAO,OAAO,CAAC,IAAI,KAAK,WAAW,IAAI,OAAO,CAAC,OAAO,KAAK,EAAE,CAAC;IAChE,CAAC;IAED,WAAW,CAAC,IAAY;QACtB,OAAO,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;CACF"}
|
package/dist/tools/subagent.d.ts
CHANGED
|
@@ -31,6 +31,21 @@ export interface IsolatedLoopResult {
|
|
|
31
31
|
* @returns Текстовый контекст для system prompt субагента
|
|
32
32
|
*/
|
|
33
33
|
export declare function buildSubagentContext(cwd: string): string;
|
|
34
|
+
/**
|
|
35
|
+
* Контекст для specialist'а — фокусированное описание ошибки.
|
|
36
|
+
*
|
|
37
|
+
* @param toolName - имя упавшего инструмента
|
|
38
|
+
* @param toolArgs - аргументы которые были переданы
|
|
39
|
+
* @param errorOutput - текст ошибки
|
|
40
|
+
* @param userTask - исходный запрос пользователя (краткое описание)
|
|
41
|
+
* @param attemptCount - сколько раз ошибка повторилась
|
|
42
|
+
* @returns Текст задачи для specialist'а
|
|
43
|
+
*/
|
|
44
|
+
export declare function buildSpecialistTask(toolName: string, toolArgs: Record<string, unknown>, errorOutput: string, userTask: string, attemptCount: number): string;
|
|
45
|
+
/**
|
|
46
|
+
* Проверяет является ли ошибка тривиальной (не требует specialist).
|
|
47
|
+
*/
|
|
48
|
+
export declare function isTrivialError(toolName: string, errorOutput: string): boolean;
|
|
34
49
|
/**
|
|
35
50
|
* Извлекает все JSON-блоки из тегов <tool_call>...</tool_call>.
|
|
36
51
|
* Дублируется из loop.ts для изоляции субагентов.
|
|
@@ -79,7 +94,7 @@ export declare function doChat(provider: LLMProvider, messages: ChatMessage[], r
|
|
|
79
94
|
*
|
|
80
95
|
* @returns Результат: созданные файлы, ошибки, краткое описание, количество ходов
|
|
81
96
|
*/
|
|
82
|
-
export declare function runIsolatedLoop(provider: LLMProvider, registry: ToolRegistry, task: string, existingFiles: string, cwd: string, quiet: boolean, renderer: OutputRenderer, toolExecutor?: ToolExecutor, mode?: string): Promise<IsolatedLoopResult>;
|
|
97
|
+
export declare function runIsolatedLoop(provider: LLMProvider, registry: ToolRegistry, task: string, existingFiles: string, cwd: string, quiet: boolean, renderer: OutputRenderer, toolExecutor?: ToolExecutor, mode?: string, toolModel?: string, maxStepsParam?: number): Promise<IsolatedLoopResult>;
|
|
83
98
|
import type { ToolDefinition } from './registry.js';
|
|
84
99
|
export declare const subagentDefinition: ToolDefinition;
|
|
85
100
|
//# sourceMappingURL=subagent.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"subagent.d.ts","sourceRoot":"","sources":["../../src/tools/subagent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"subagent.d.ts","sourceRoot":"","sources":["../../src/tools/subagent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEnE,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAI9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAIxD;;;;;;;;;;;;;GAaG;AAIH,0DAA0D;AAC1D,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAID;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAwDxD;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,MAAM,CAmBR;AAsBD;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAgB7E;AAID;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CA+C9D;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,GAAG,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAmD7G;AAID;;;;;;;;;;;GAWG;AACH,wBAAsB,MAAM,CAC1B,QAAQ,EAAE,WAAW,EACrB,QAAQ,EAAE,WAAW,EAAE,EACvB,QAAQ,EAAE,cAAc,EACxB,MAAM,CAAC,EAAE,WAAW,EACpB,OAAO,SAAI,EACX,YAAY,UAAQ,EACpB,MAAM,GAAE,MAAM,GAAG,UAAmB,EACpC,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CA+KlD;AAyFD;;;;;;;;;;;GAWG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,WAAW,EACrB,QAAQ,EAAE,YAAY,EACtB,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,MAAM,EACrB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,cAAc,EACxB,YAAY,CAAC,EAAE,YAAY,EAC3B,IAAI,CAAC,EAAE,MAAM,EACb,SAAS,CAAC,EAAE,MAAM,EAClB,aAAa,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,kBAAkB,CAAC,CA6L7B;AAID,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,eAAO,MAAM,kBAAkB,EAAE,cAchC,CAAC"}
|
package/dist/tools/subagent.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { jsonrepair } from 'jsonrepair';
|
|
2
|
+
import { LMStudioNative } from '../llm/lmstudio-native.js';
|
|
2
3
|
import { ContextManager } from '../agent/context.js';
|
|
3
4
|
import { buildSystemPrompt } from '../agent/system-prompt.js';
|
|
4
5
|
import { checkFileSyntax } from './syntax-check.js';
|
|
@@ -72,6 +73,73 @@ export function buildSubagentContext(cwd) {
|
|
|
72
73
|
catch { /* no tsconfig */ }
|
|
73
74
|
return lines.join('\n');
|
|
74
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Контекст для specialist'а — фокусированное описание ошибки.
|
|
78
|
+
*
|
|
79
|
+
* @param toolName - имя упавшего инструмента
|
|
80
|
+
* @param toolArgs - аргументы которые были переданы
|
|
81
|
+
* @param errorOutput - текст ошибки
|
|
82
|
+
* @param userTask - исходный запрос пользователя (краткое описание)
|
|
83
|
+
* @param attemptCount - сколько раз ошибка повторилась
|
|
84
|
+
* @returns Текст задачи для specialist'а
|
|
85
|
+
*/
|
|
86
|
+
export function buildSpecialistTask(toolName, toolArgs, errorOutput, userTask, attemptCount) {
|
|
87
|
+
const argsStr = JSON.stringify(toolArgs, null, 2);
|
|
88
|
+
return [
|
|
89
|
+
`The tool "${toolName}" has failed ${attemptCount} times with the same error while working on: "${userTask.slice(0, 200)}"`,
|
|
90
|
+
'',
|
|
91
|
+
`Failed tool call:`,
|
|
92
|
+
` Tool: ${toolName}`,
|
|
93
|
+
` Arguments: ${argsStr}`,
|
|
94
|
+
'',
|
|
95
|
+
`Error output:`,
|
|
96
|
+
` ${errorOutput.slice(0, 500)}`,
|
|
97
|
+
'',
|
|
98
|
+
`Your task: Diagnose WHY this tool call fails and FIX the underlying problem.`,
|
|
99
|
+
` - Read the relevant files to understand the actual state`,
|
|
100
|
+
` - Fix the root cause (wrong path, missing file, syntax error, etc.)`,
|
|
101
|
+
` - If the tool call arguments are wrong, correct them`,
|
|
102
|
+
` - If the file doesn't exist, create it`,
|
|
103
|
+
` - Return a clear summary of what you found and what you fixed`,
|
|
104
|
+
].join('\n');
|
|
105
|
+
}
|
|
106
|
+
/** Паттерны ошибок которые НЕ триггерят specialist (trivial) */
|
|
107
|
+
const TRIVIAL_ERROR_PATTERNS = [
|
|
108
|
+
/no results? found/i,
|
|
109
|
+
/pattern .* matched 0 results/i,
|
|
110
|
+
/0 files? matched/i,
|
|
111
|
+
/command not found.*grep/i,
|
|
112
|
+
/not a directory/i,
|
|
113
|
+
];
|
|
114
|
+
/** Паттерны ошибок которые ВСЕГДА требуют specialist (не trivial) */
|
|
115
|
+
const NON_TRIVIAL_ERROR_PATTERNS = [
|
|
116
|
+
/unexpected token/i,
|
|
117
|
+
/syntaxerror/i,
|
|
118
|
+
/cannot find module/i,
|
|
119
|
+
/module not found/i,
|
|
120
|
+
/permission denied/i,
|
|
121
|
+
/enoent/i,
|
|
122
|
+
/eacces/i,
|
|
123
|
+
];
|
|
124
|
+
/**
|
|
125
|
+
* Проверяет является ли ошибка тривиальной (не требует specialist).
|
|
126
|
+
*/
|
|
127
|
+
export function isTrivialError(toolName, errorOutput) {
|
|
128
|
+
// Синтаксические и критические ошибки — ВСЕГДА не trivial
|
|
129
|
+
if (NON_TRIVIAL_ERROR_PATTERNS.some(p => p.test(errorOutput))) {
|
|
130
|
+
return false;
|
|
131
|
+
}
|
|
132
|
+
// grep_search/glob_search с 0 результатами — нормальное поведение
|
|
133
|
+
if (toolName === 'grep_search' || toolName === 'glob_search') {
|
|
134
|
+
if (/0 results|0 files|no match/i.test(errorOutput) && errorOutput.length < 200) {
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// Любая ошибка < 10 символов — скорее всего trivia
|
|
139
|
+
if (errorOutput.length < 10)
|
|
140
|
+
return true;
|
|
141
|
+
return TRIVIAL_ERROR_PATTERNS.some(p => p.test(errorOutput));
|
|
142
|
+
}
|
|
75
143
|
// ─── Tool call parsing ───────────────────────────────────
|
|
76
144
|
/**
|
|
77
145
|
* Извлекает все JSON-блоки из тегов <tool_call>...</tool_call>.
|
|
@@ -145,7 +213,7 @@ export function validateToolCall(parsed) {
|
|
|
145
213
|
if (!parsed || typeof parsed !== 'object') {
|
|
146
214
|
return { valid: false, error: 'Not an object' };
|
|
147
215
|
}
|
|
148
|
-
const VALID_TOOLS = new Set(['bash', 'plan', 'todo', 'question', 'approve', 'theme', 'user_profile', 'subagent', 'read_file', 'write_file', 'edit_file', 'list_dir', 'create_dir', 'delete_file', 'copy_file', 'move_file', 'file_info', 'glob_search', 'grep_search', 'tree', 'web_search', 'web_fetch']);
|
|
216
|
+
const VALID_TOOLS = new Set(['bash', 'plan', 'todo', 'question', 'approve', 'theme', 'user_profile', 'subagent', 'read_file', 'write_file', 'edit_file', 'list_dir', 'create_dir', 'delete_file', 'copy_file', 'move_file', 'file_info', 'glob_search', 'grep_search', 'tree', 'web_search', 'web_fetch', 'scaffold']);
|
|
149
217
|
if (!parsed.name || !VALID_TOOLS.has(parsed.name)) {
|
|
150
218
|
return { valid: false, error: `Unknown tool: ${parsed.name}` };
|
|
151
219
|
}
|
|
@@ -331,6 +399,21 @@ export async function doChat(provider, messages, renderer, signal, retries = 1,
|
|
|
331
399
|
return retryResult;
|
|
332
400
|
}
|
|
333
401
|
}
|
|
402
|
+
// Phase 2.5: Emergency — принудительно генерируем content с низкой температурой
|
|
403
|
+
// Когда reasoning есть, но content пустой — модель "застряла" в thinking loop
|
|
404
|
+
if (lastReasoningText.trim()) {
|
|
405
|
+
logInfo('DOCHAT', `emergency: forcing content with low temperature`);
|
|
406
|
+
renderer.writeDim(`[emergency: forcing content with temperature=0.1]`);
|
|
407
|
+
const emergencyMessages = [
|
|
408
|
+
...messages,
|
|
409
|
+
{ role: 'user', content: '[System] You MUST produce a response now. Do NOT use thinking tags. Reply with a tool call or a direct answer. Any response is better than empty.' },
|
|
410
|
+
];
|
|
411
|
+
const emergencyResult = await doChatOnce(provider, emergencyMessages, renderer, signal, false, showThinking, caller, maxTokens, 0.1);
|
|
412
|
+
if (emergencyResult.response.trim()) {
|
|
413
|
+
logInfo('DOCHAT', `emergency succeeded: ${emergencyResult.response.length} chars`);
|
|
414
|
+
return emergencyResult;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
334
417
|
// Phase 3: Fallback — используем reasoning как content
|
|
335
418
|
if (llmCfg.fallbackToReasoning && lastReasoningText.trim()) {
|
|
336
419
|
logInfo('DOCHAT', `fallback: using reasoning as content (${lastReasoningText.length} chars)`);
|
|
@@ -343,7 +426,7 @@ export async function doChat(provider, messages, renderer, signal, retries = 1,
|
|
|
343
426
|
* Одиночный вызов LLM без retry логики.
|
|
344
427
|
* Используется для retry с другими параметрами (например, enableThinking: false).
|
|
345
428
|
*/
|
|
346
|
-
async function doChatOnce(provider, messages, renderer, signal, enableThinking = true, showThinking = false, caller = 'main', maxTokens) {
|
|
429
|
+
async function doChatOnce(provider, messages, renderer, signal, enableThinking = true, showThinking = false, caller = 'main', maxTokens, temperature = 0.7) {
|
|
347
430
|
const startTime = performance.now();
|
|
348
431
|
const fullText = [];
|
|
349
432
|
let started = false;
|
|
@@ -352,7 +435,7 @@ async function doChatOnce(provider, messages, renderer, signal, enableThinking =
|
|
|
352
435
|
renderer.writeSpinner();
|
|
353
436
|
try {
|
|
354
437
|
let buf = '';
|
|
355
|
-
for await (const chunk of provider.chat(messages, { temperature
|
|
438
|
+
for await (const chunk of provider.chat(messages, { temperature, signal, showThinking, enableThinking, max_tokens: maxTokens })) {
|
|
356
439
|
if (!chunk.content && !chunk.finish_reason)
|
|
357
440
|
continue;
|
|
358
441
|
if (chunk.content) {
|
|
@@ -418,11 +501,17 @@ async function doChatOnce(provider, messages, renderer, signal, enableThinking =
|
|
|
418
501
|
*
|
|
419
502
|
* @returns Результат: созданные файлы, ошибки, краткое описание, количество ходов
|
|
420
503
|
*/
|
|
421
|
-
export async function runIsolatedLoop(provider, registry, task, existingFiles, cwd, quiet, renderer, toolExecutor, mode) {
|
|
504
|
+
export async function runIsolatedLoop(provider, registry, task, existingFiles, cwd, quiet, renderer, toolExecutor, mode, toolModel, maxStepsParam) {
|
|
422
505
|
const createdFiles = [];
|
|
423
506
|
const errors = [];
|
|
424
507
|
const startTime = performance.now();
|
|
425
|
-
|
|
508
|
+
// Two-model pipeline: если toolModel задана, создаём отдельный провайдер
|
|
509
|
+
let effectiveProvider = provider;
|
|
510
|
+
if (toolModel && provider instanceof LMStudioNative) {
|
|
511
|
+
effectiveProvider = new LMStudioNative(provider.baseUrl, toolModel, provider.contextWindow);
|
|
512
|
+
logInfo('SUBAGENT', `using tool model: ${toolModel} (main: ${provider.model})`);
|
|
513
|
+
}
|
|
514
|
+
logInfo('SUBAGENT', `START | task: "${task.slice(0, 200)}" | context window: ${effectiveProvider.contextWindow}`);
|
|
426
515
|
// Always build auto-context from project, even if model didn't pass existingFiles
|
|
427
516
|
const autoContext = buildSubagentContext(cwd);
|
|
428
517
|
const mergedContext = existingFiles
|
|
@@ -439,8 +528,8 @@ export async function runIsolatedLoop(provider, registry, task, existingFiles, c
|
|
|
439
528
|
{ role: 'system', content: systemPrompt },
|
|
440
529
|
{ role: 'user', content: task + contextInfo },
|
|
441
530
|
];
|
|
442
|
-
const ctx = new ContextManager(
|
|
443
|
-
const maxSteps = 20;
|
|
531
|
+
const ctx = new ContextManager(effectiveProvider.contextWindow);
|
|
532
|
+
const maxSteps = maxStepsParam ?? 20;
|
|
444
533
|
let toolCallCount = 0;
|
|
445
534
|
for (let step = 0; step < maxSteps; step++) {
|
|
446
535
|
await ctx.updateTokens(messages);
|
|
@@ -457,7 +546,7 @@ export async function runIsolatedLoop(provider, registry, task, existingFiles, c
|
|
|
457
546
|
const hasToolResult = messages.some(m => m.role === 'tool');
|
|
458
547
|
const llmCfg = getLLMConfig();
|
|
459
548
|
const maxTokens = hasToolResult ? llmCfg.maxTokensAfterTool : undefined;
|
|
460
|
-
const { response } = await doChat(
|
|
549
|
+
const { response } = await doChat(effectiveProvider, messages, renderer, renderer?.abortSignal, 1, false, 'subagent', maxTokens);
|
|
461
550
|
if (!response.trim()) {
|
|
462
551
|
logDebug('SUBAGENT', `empty response at step ${step}, stopping`);
|
|
463
552
|
break;
|
|
@@ -575,11 +664,11 @@ export const subagentDefinition = {
|
|
|
575
664
|
type: 'function',
|
|
576
665
|
function: {
|
|
577
666
|
name: 'subagent',
|
|
578
|
-
description: 'Delegate a task to an isolated agent
|
|
667
|
+
description: 'Delegate a task to an isolated agent with a FRESH context (no history of prior errors). Use for: (1) each file when creating 3+ new files, (2) any task where you are stuck or making repeated errors, (3) simple single-step operations (bash, file read/write). The subagent has all tools and starts clean — ideal when accumulated context is causing confusion.',
|
|
579
668
|
parameters: {
|
|
580
669
|
type: 'object',
|
|
581
670
|
properties: {
|
|
582
|
-
task: { type: 'string', description: 'What the subagent should
|
|
671
|
+
task: { type: 'string', description: 'What the subagent should do — be specific and include file paths' },
|
|
583
672
|
existingFiles: { type: 'string', description: 'Comma-separated files the subagent can read for context (optional)' },
|
|
584
673
|
},
|
|
585
674
|
required: ['task'],
|