codemini-cli 0.1.14 → 0.1.16
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/OPERATIONS.md +17 -2
- package/README.md +22 -0
- package/package.json +1 -1
- package/skills/brainstorm/SKILL.md +86 -0
- package/skills/superpowers-lite/SKILL.md +36 -2
- package/src/cli.js +1 -1
- package/src/core/chat-runtime.js +155 -21
- package/src/core/tools.js +45 -7
- package/skills/brainstorming-lite/SKILL.md +0 -37
- package/skills/executing-plan-lite/SKILL.md +0 -41
package/OPERATIONS.md
CHANGED
|
@@ -110,6 +110,7 @@ Use this when you want to separate:
|
|
|
110
110
|
```text
|
|
111
111
|
/help
|
|
112
112
|
/commands
|
|
113
|
+
/brainstorm <question>
|
|
113
114
|
/config list
|
|
114
115
|
/config get <key>
|
|
115
116
|
/history list
|
|
@@ -144,6 +145,14 @@ Continue into the relevant files and explain how skill loading works.
|
|
|
144
145
|
Find where shell.default is used and summarize the config path.
|
|
145
146
|
```
|
|
146
147
|
|
|
148
|
+
### Brainstorm before coding
|
|
149
|
+
|
|
150
|
+
```text
|
|
151
|
+
/brainstorm Should login retry stay local or become a shared helper?
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Use this when the implementation path is still fuzzy and you want the CLI to compare a few approaches before any code change.
|
|
155
|
+
|
|
147
156
|
### Spec and plan flow
|
|
148
157
|
|
|
149
158
|
```text
|
|
@@ -170,12 +179,18 @@ Execute this plan step by step.
|
|
|
170
179
|
```powershell
|
|
171
180
|
codemini skill list
|
|
172
181
|
codemini skill inspect superpowers-lite
|
|
173
|
-
codemini skill enable
|
|
174
|
-
codemini skill disable
|
|
182
|
+
codemini skill enable brainstorm
|
|
183
|
+
codemini skill disable brainstorm
|
|
175
184
|
codemini skill reindex
|
|
176
185
|
```
|
|
177
186
|
|
|
178
187
|
## Better Prompt Patterns
|
|
188
|
+
## Release Management
|
|
189
|
+
|
|
190
|
+
### Release Checklist
|
|
191
|
+
|
|
192
|
+
For information on how to perform a release, please see the [Release Checklist](RELEASE_CHECKLIST.md) document.
|
|
193
|
+
|
|
179
194
|
|
|
180
195
|
These usually work better:
|
|
181
196
|
|
package/README.md
CHANGED
|
@@ -63,6 +63,7 @@ codemini skill list|install|enable|disable|inspect|reindex
|
|
|
63
63
|
|
|
64
64
|
- `ui.reply_language` controls the assistant reply language at the prompt layer and also nudges generated docs and code comments to match
|
|
65
65
|
- Slash completion now prioritizes important commands and config keys, shows short descriptions, and supports `←/→` page switching
|
|
66
|
+
- Ambiguous feature requests can pause for lightweight brainstorming first, and `/brainstorm <question>` gives an explicit way to compare options before coding
|
|
66
67
|
- `plan auto` now turns the original goal into an acceptance checklist, uses a lighter chain only for truly tiny tasks, and treats unmet checklist items as failure signals
|
|
67
68
|
- Structured code tools reduce shell-noise for small models by preferring `locate -> open_target -> edit_target`
|
|
68
69
|
|
|
@@ -83,7 +84,19 @@ The base config directory is resolved in this order:
|
|
|
83
84
|
- Linux/XDG: `$XDG_CONFIG_HOME/codemini-cli`
|
|
84
85
|
- Fallback in restricted environments: `.codemini-cli/`
|
|
85
86
|
|
|
87
|
+
### Brainstorming
|
|
88
|
+
|
|
89
|
+
Use `/brainstorm <question>` when you want the assistant to stop before coding, compare 2-3 approaches, and choose one direction first.
|
|
90
|
+
|
|
91
|
+
```text
|
|
92
|
+
/brainstorm Should login retry stay local or become a shared helper?
|
|
93
|
+
```
|
|
94
|
+
|
|
86
95
|
### Documentation
|
|
96
|
+
### Release Checklist
|
|
97
|
+
|
|
98
|
+
For information on how to perform a release, please see the [Release Checklist](RELEASE_CHECKLIST.md) document.
|
|
99
|
+
|
|
87
100
|
|
|
88
101
|
- Operator guide and common command patterns: [OPERATIONS.md](/mnt/e/Git%20Projects/qurio-coder/OPERATIONS.md)
|
|
89
102
|
- Packaging and deployment guide: [deployment.md](/mnt/e/Git%20Projects/qurio-coder/deployment.md)
|
|
@@ -164,6 +177,7 @@ codemini skill list|install|enable|disable|inspect|reindex
|
|
|
164
177
|
|
|
165
178
|
- `ui.reply_language` 通过 prompt 层控制模型回复语言,也会尽量让生成文档和代码注释跟随该语言
|
|
166
179
|
- slash 补全会优先展示更重要的命令和配置项,显示简短说明,并支持 `←/→` 翻页
|
|
180
|
+
- 对于需求仍不明确的功能请求,CLI 会先偏向轻量 brainstorm;也可以显式使用 `/brainstorm <问题>` 先比较方案再决定是否编码
|
|
167
181
|
- `plan auto` 会先把原始目标展开成验收清单;只有真正很小的任务才会走轻量链路;如果 reviewer 或 tester 标记了未满足或未验证的验收项,就不会按成功处理
|
|
168
182
|
- 为了减少小模型被 shell 原始输出干扰,新增了 `locate -> open_target -> edit_target` 这套结构化代码工具流
|
|
169
183
|
|
|
@@ -184,6 +198,14 @@ CodeMini CLI 会从这些位置读取 skill:
|
|
|
184
198
|
- Linux / XDG:`$XDG_CONFIG_HOME/codemini-cli`
|
|
185
199
|
- 受限环境回退:`.codemini-cli/`
|
|
186
200
|
|
|
201
|
+
### Brainstorm 用法
|
|
202
|
+
|
|
203
|
+
当你希望助手先收敛方向、不要立即写代码时,可以使用:
|
|
204
|
+
|
|
205
|
+
```text
|
|
206
|
+
/brainstorm Should login retry stay local or become a shared helper?
|
|
207
|
+
```
|
|
208
|
+
|
|
187
209
|
### 文档入口
|
|
188
210
|
|
|
189
211
|
- 操作手册与常见命令组合:[OPERATIONS.md](/mnt/e/Git%20Projects/qurio-coder/OPERATIONS.md)
|
package/package.json
CHANGED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: brainstorm
|
|
3
|
+
description: Lightweight brainstorming skill for 30B-class models. Use when a feature or behavior request is still unclear and the agent should compare a few approaches before coding.
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
Use this skill only after the controller has decided the task needs clarification or option comparison before coding.
|
|
8
|
+
|
|
9
|
+
Primary purpose:
|
|
10
|
+
- ask one high-value question when a key constraint is missing
|
|
11
|
+
- compare 2-3 short options when the goal is clear but the approach is not
|
|
12
|
+
- stop at a clear decision point
|
|
13
|
+
|
|
14
|
+
Rules:
|
|
15
|
+
|
|
16
|
+
1. Ask one question at a time.
|
|
17
|
+
Do not dump a long questionnaire. Pick the most important uncertainty and resolve it first.
|
|
18
|
+
|
|
19
|
+
1a. If a key uncertainty remains, stop after one question.
|
|
20
|
+
Do not ask multiple numbered questions in the same reply. Do not continue into options, decisions, code, or file edits until that question is answered.
|
|
21
|
+
|
|
22
|
+
2. Stay concrete.
|
|
23
|
+
Focus only on the uncertainty that blocks execution.
|
|
24
|
+
|
|
25
|
+
3. Offer 2-3 approaches only when the key constraint is already clear.
|
|
26
|
+
Keep each option short and focused on the main tradeoff.
|
|
27
|
+
|
|
28
|
+
4. Keep the design small.
|
|
29
|
+
Do not expand a simple task into a long design discussion.
|
|
30
|
+
|
|
31
|
+
5. Confirm before implementation.
|
|
32
|
+
If options were given, wait for the user to choose unless the user explicitly asks for a recommendation.
|
|
33
|
+
|
|
34
|
+
6. No code before convergence.
|
|
35
|
+
Do not write implementation code, pseudo-code, or file edits while the direction is still being chosen.
|
|
36
|
+
|
|
37
|
+
7. Do not decide for the user when the request is still under-specified.
|
|
38
|
+
If the user has not provided enough information to choose confidently, ask the next best question and wait.
|
|
39
|
+
|
|
40
|
+
8. Do not inspect the repo unless existing project context is directly relevant.
|
|
41
|
+
For greenfield brainstorming, stay in conversation mode first.
|
|
42
|
+
|
|
43
|
+
Output format:
|
|
44
|
+
|
|
45
|
+
Mode A: key constraint missing
|
|
46
|
+
|
|
47
|
+
Question:
|
|
48
|
+
- ask:
|
|
49
|
+
- why this matters:
|
|
50
|
+
|
|
51
|
+
Wait for the user's answer.
|
|
52
|
+
|
|
53
|
+
Mode B: goal is clear but approach choice remains
|
|
54
|
+
|
|
55
|
+
Option 1:
|
|
56
|
+
- idea:
|
|
57
|
+
- pros:
|
|
58
|
+
- cons:
|
|
59
|
+
|
|
60
|
+
Option 2:
|
|
61
|
+
- idea:
|
|
62
|
+
- pros:
|
|
63
|
+
- cons:
|
|
64
|
+
|
|
65
|
+
Option 3 (optional):
|
|
66
|
+
- idea:
|
|
67
|
+
- pros:
|
|
68
|
+
- cons:
|
|
69
|
+
|
|
70
|
+
Decision:
|
|
71
|
+
- chosen:
|
|
72
|
+
- reason:
|
|
73
|
+
|
|
74
|
+
After decision:
|
|
75
|
+
- stop after the chosen direction unless the user clearly asks to continue into implementation
|
|
76
|
+
|
|
77
|
+
Suggested flow:
|
|
78
|
+
- Restate the task briefly
|
|
79
|
+
- Choose one mode only: Question or Options
|
|
80
|
+
- Stop at a clear decision point
|
|
81
|
+
|
|
82
|
+
Avoid:
|
|
83
|
+
- large ceremonies
|
|
84
|
+
- repeating the full conversation
|
|
85
|
+
- asking multiple independent questions in one turn
|
|
86
|
+
- proposing implementation details before the problem is clear
|
|
@@ -6,6 +6,33 @@ version: 0.1.0
|
|
|
6
6
|
|
|
7
7
|
Use this skill as the default lightweight operating style for coding work.
|
|
8
8
|
|
|
9
|
+
Primary behavior:
|
|
10
|
+
- keep momentum on clear tasks
|
|
11
|
+
- slow down before coding when the request is ambiguous
|
|
12
|
+
- keep edits local
|
|
13
|
+
- verify before claiming success
|
|
14
|
+
|
|
15
|
+
Routing:
|
|
16
|
+
|
|
17
|
+
1. If the task is clear, small, and the implementation path is obvious:
|
|
18
|
+
- execute directly
|
|
19
|
+
- do not force brainstorming
|
|
20
|
+
|
|
21
|
+
2. If the goal is clear but there are multiple reasonable implementation paths:
|
|
22
|
+
- use `brainstorm`
|
|
23
|
+
- give 2-3 short options
|
|
24
|
+
- do not choose for the user unless the user explicitly asks for a recommendation
|
|
25
|
+
|
|
26
|
+
3. If the request is still missing a key constraint or success condition:
|
|
27
|
+
- ask exactly one clarifying question
|
|
28
|
+
- do not give options yet
|
|
29
|
+
- do not write code yet
|
|
30
|
+
|
|
31
|
+
4. If the request is greenfield and underspecified, such as "build a page", "make a site", "generate an app", or similar:
|
|
32
|
+
- treat it as missing key constraints by default
|
|
33
|
+
- ask one high-value question before coding
|
|
34
|
+
- do not assume features, storage model, or scope unless the user already gave them
|
|
35
|
+
|
|
9
36
|
Core rules:
|
|
10
37
|
|
|
11
38
|
1. Search first.
|
|
@@ -21,15 +48,22 @@ When a task can be split cleanly, use sub-agents for bounded subtasks so the mai
|
|
|
21
48
|
- a tiny file evidence packet
|
|
22
49
|
- a concrete expected output
|
|
23
50
|
|
|
24
|
-
4.
|
|
51
|
+
4. Do not code against unclear requirements.
|
|
52
|
+
If the requested behavior, scope, or acceptance is unclear, do not jump into implementation. First decide which of these applies:
|
|
53
|
+
- missing key constraint -> ask one question
|
|
54
|
+
- multiple valid approaches -> use `brainstorm`
|
|
55
|
+
- clear enough to build -> proceed
|
|
56
|
+
|
|
57
|
+
5. Read and write with intent.
|
|
25
58
|
Use `read_file` only when shell output is not enough. Use `write_file` for edits. Avoid unnecessary tool calls and avoid rereading the same file without a reason.
|
|
26
59
|
|
|
27
|
-
|
|
60
|
+
6. Verify before claiming success.
|
|
28
61
|
Run the relevant test, check, or command before saying work is fixed or complete.
|
|
29
62
|
|
|
30
63
|
Default workflow:
|
|
31
64
|
- Search with `rg`
|
|
32
65
|
- Inspect local context
|
|
66
|
+
- If the request is unclear, first decide: ask one question, brainstorm, or proceed
|
|
33
67
|
- Plan the next smallest step
|
|
34
68
|
- Delegate if the work is independent
|
|
35
69
|
- Edit
|
package/src/cli.js
CHANGED
|
@@ -4,7 +4,7 @@ import { handleConfig } from './commands/config.js';
|
|
|
4
4
|
import { handleDoctor } from './commands/doctor.js';
|
|
5
5
|
import { handleSkill } from './commands/skill.js';
|
|
6
6
|
|
|
7
|
-
const VERSION = '0.1.
|
|
7
|
+
const VERSION = '0.1.16';
|
|
8
8
|
|
|
9
9
|
function printHelp() {
|
|
10
10
|
console.log(`codemini ${VERSION}
|
package/src/core/chat-runtime.js
CHANGED
|
@@ -106,8 +106,6 @@ const SUB_AGENT_CONTEXT_MAX_MESSAGES = 4;
|
|
|
106
106
|
const SUB_AGENT_CONTEXT_MAX_CHARS = 1200;
|
|
107
107
|
const SUB_AGENT_EVIDENCE_MAX_ITEMS = 3;
|
|
108
108
|
const SUB_AGENT_HANDOFF_MAX_ITEMS = 6;
|
|
109
|
-
const AUTO_SKILL_NAMES = ['superpowers-lite', 'brainstorming-lite', 'executing-plan-lite'];
|
|
110
|
-
|
|
111
109
|
function getSubAgentRolePrompt(role) {
|
|
112
110
|
if (role === 'planner') {
|
|
113
111
|
return 'You are a planning sub-agent. Produce a concrete implementation plan with risks and verification.';
|
|
@@ -430,6 +428,40 @@ function buildGoalRequirementPacket(goal, role) {
|
|
|
430
428
|
return lines.join('\n');
|
|
431
429
|
}
|
|
432
430
|
|
|
431
|
+
function buildAutoPlanPlannerGuidance() {
|
|
432
|
+
return [
|
|
433
|
+
'Auto-plan planning rules:',
|
|
434
|
+
'- If the goal still leaves room for multiple approaches, choose one practical direction before planning execution.',
|
|
435
|
+
'- Prefer the smallest local approach that satisfies the goal.',
|
|
436
|
+
'- Do not output multiple alternative branches in the final plan.',
|
|
437
|
+
'- Turn the chosen direction into concrete execution steps for coder, reviewer, and tester.',
|
|
438
|
+
'- Keep the plan ordered, implementation-oriented, and easy for small sub-agents to follow.'
|
|
439
|
+
].join('\n');
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
function buildAutoPlanExecutionGuidance(role) {
|
|
443
|
+
const common = [
|
|
444
|
+
'Auto-plan execution rules:',
|
|
445
|
+
'- Work in the smallest useful step.',
|
|
446
|
+
'- Read the target code before editing.',
|
|
447
|
+
'- Prefer local changes over broad refactors.',
|
|
448
|
+
'- Prefer narrow verification with concrete evidence before claiming success.'
|
|
449
|
+
];
|
|
450
|
+
|
|
451
|
+
if (role === 'coder') {
|
|
452
|
+
common.push('- Keep edits tightly scoped to the chosen plan direction.');
|
|
453
|
+
common.push('- Avoid speculative cleanup or unrelated improvements.');
|
|
454
|
+
} else if (role === 'reviewer') {
|
|
455
|
+
common.push('- Review against the chosen plan direction and the acceptance checklist.');
|
|
456
|
+
common.push('- Call out missing requested behavior, regression risk, and unverified claims.');
|
|
457
|
+
} else if (role === 'tester') {
|
|
458
|
+
common.push('- Prefer running the narrowest real verification command that matches the changed area.');
|
|
459
|
+
common.push('- Distinguish clearly between verified behavior and assumptions.');
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
return common.join('\n');
|
|
463
|
+
}
|
|
464
|
+
|
|
433
465
|
async function pathExists(targetPath) {
|
|
434
466
|
try {
|
|
435
467
|
await fs.access(targetPath);
|
|
@@ -536,15 +568,24 @@ function isSkillEnabled(config, name) {
|
|
|
536
568
|
function selectAutoSkillNames(text = '') {
|
|
537
569
|
const input = String(text || '').toLowerCase();
|
|
538
570
|
const selected = ['superpowers-lite'];
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
571
|
+
|
|
572
|
+
const explicitBrainstorm =
|
|
573
|
+
/(brainstorm|头脑风暴|方案|思路|设计一下|设计方案|怎么做|如何做|approach|options?)/i.test(input);
|
|
574
|
+
const ambiguitySignals =
|
|
575
|
+
/(not sure|unsure|unclear|help me think|let'?s think|should we|which (?:approach|option|way)|best way|trade-?off|vs\b|versus|or should|maybe|roughly|just something simple|要不要|不确定|不明确|先别写|先不要写|先讨论|先想一下|哪个方案|怎么设计|如何设计|取舍|还是|大概|先做个|做一个简单的|先来个)/i.test(
|
|
576
|
+
input
|
|
577
|
+
);
|
|
578
|
+
const featureRequest =
|
|
579
|
+
/\b(add|build|create|generate|make|implement|support|introduce|design|refactor|change|update)\b/i.test(input) ||
|
|
580
|
+
/(新增|增加|实现|支持|设计|重构|改造|调整|生成|做一个|做个|创建)/i.test(input);
|
|
581
|
+
const greenfieldBuildRequest =
|
|
582
|
+
(/\b(build|create|generate|make)\b/i.test(input) || /(生成|做一个|做个|创建)/i.test(input)) &&
|
|
583
|
+
/(\b(project|app|site|website|page|dashboard|tool|component|landing page|html page)\b|项目|应用|网页|页面|网站|工具|组件|看板)/i.test(
|
|
584
|
+
input
|
|
585
|
+
);
|
|
586
|
+
|
|
587
|
+
if (explicitBrainstorm || (ambiguitySignals && featureRequest) || greenfieldBuildRequest) {
|
|
588
|
+
selected.push('brainstorm');
|
|
548
589
|
}
|
|
549
590
|
return selected;
|
|
550
591
|
}
|
|
@@ -953,6 +994,7 @@ async function buildPlanFromSpecWithModel({
|
|
|
953
994
|
model,
|
|
954
995
|
systemPrompt
|
|
955
996
|
}) {
|
|
997
|
+
const projectConstraints = await inferProjectImplementationConstraints(process.cwd());
|
|
956
998
|
const prompt = [
|
|
957
999
|
'Convert the provided engineering spec into an implementation plan in markdown.',
|
|
958
1000
|
'Use this structure exactly:',
|
|
@@ -972,7 +1014,7 @@ async function buildPlanFromSpecWithModel({
|
|
|
972
1014
|
{ role: 'system', content: `${systemPrompt}\n${prompt}` },
|
|
973
1015
|
{
|
|
974
1016
|
role: 'user',
|
|
975
|
-
content: `Spec path: ${specPath || '(inline)'}\n\n${specText}`
|
|
1017
|
+
content: `Spec path: ${specPath || '(inline)'}\n\nProject implementation constraints:\n${projectConstraints}\n\n${specText}`
|
|
976
1018
|
}
|
|
977
1019
|
],
|
|
978
1020
|
timeoutMs: config.gateway.timeout_ms || 90000,
|
|
@@ -981,6 +1023,84 @@ async function buildPlanFromSpecWithModel({
|
|
|
981
1023
|
return String(result.text || '').trim();
|
|
982
1024
|
}
|
|
983
1025
|
|
|
1026
|
+
async function collectLikelyImplementationFiles(cwd) {
|
|
1027
|
+
const candidates = [];
|
|
1028
|
+
const roots = ['src', 'app', 'lib'];
|
|
1029
|
+
const preferredExts = new Set(['.js', '.jsx', '.ts', '.tsx', '.mjs', '.cjs']);
|
|
1030
|
+
|
|
1031
|
+
async function visit(dir) {
|
|
1032
|
+
let entries = [];
|
|
1033
|
+
try {
|
|
1034
|
+
entries = await fs.readdir(dir, { withFileTypes: true });
|
|
1035
|
+
} catch {
|
|
1036
|
+
return;
|
|
1037
|
+
}
|
|
1038
|
+
for (const entry of entries) {
|
|
1039
|
+
if (entry.name === 'node_modules' || entry.name === '.git' || entry.name === '.coder') continue;
|
|
1040
|
+
const abs = path.join(dir, entry.name);
|
|
1041
|
+
if (entry.isDirectory()) {
|
|
1042
|
+
await visit(abs);
|
|
1043
|
+
continue;
|
|
1044
|
+
}
|
|
1045
|
+
if (!preferredExts.has(path.extname(entry.name).toLowerCase())) continue;
|
|
1046
|
+
candidates.push(path.relative(cwd, abs).replace(/\\/g, '/'));
|
|
1047
|
+
if (candidates.length >= 8) return;
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
for (const root of roots) {
|
|
1052
|
+
const absRoot = path.join(cwd, root);
|
|
1053
|
+
if (!(await pathExists(absRoot))) continue;
|
|
1054
|
+
await visit(absRoot);
|
|
1055
|
+
if (candidates.length >= 8) break;
|
|
1056
|
+
}
|
|
1057
|
+
return candidates.slice(0, 8);
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
async function inferProjectImplementationConstraints(cwd) {
|
|
1061
|
+
const hints = [];
|
|
1062
|
+
const packageJsonPath = path.join(cwd, 'package.json');
|
|
1063
|
+
const pyprojectPath = path.join(cwd, 'pyproject.toml');
|
|
1064
|
+
const cargoPath = path.join(cwd, 'Cargo.toml');
|
|
1065
|
+
const goModPath = path.join(cwd, 'go.mod');
|
|
1066
|
+
|
|
1067
|
+
if (await pathExists(packageJsonPath)) {
|
|
1068
|
+
hints.push('- Detected package.json in the workspace.');
|
|
1069
|
+
hints.push('- Prefer JavaScript/TypeScript style paths and file names that fit the existing repo.');
|
|
1070
|
+
hints.push('- Reuse existing src/*.js, src/*.ts, or neighboring modules before inventing new utility modules.');
|
|
1071
|
+
}
|
|
1072
|
+
if (await pathExists(pyprojectPath)) {
|
|
1073
|
+
hints.push('- Detected pyproject.toml in the workspace.');
|
|
1074
|
+
hints.push('- Prefer Python modules and package layout that already exist in this repo.');
|
|
1075
|
+
}
|
|
1076
|
+
if (await pathExists(cargoPath)) {
|
|
1077
|
+
hints.push('- Detected Cargo.toml in the workspace.');
|
|
1078
|
+
hints.push('- Prefer Rust crate/module layout that matches the current workspace.');
|
|
1079
|
+
}
|
|
1080
|
+
if (await pathExists(goModPath)) {
|
|
1081
|
+
hints.push('- Detected go.mod in the workspace.');
|
|
1082
|
+
hints.push('- Prefer Go package paths and file names already present in the repo.');
|
|
1083
|
+
}
|
|
1084
|
+
|
|
1085
|
+
if (hints.length === 0) {
|
|
1086
|
+
hints.push('- No strong language marker was detected automatically.');
|
|
1087
|
+
hints.push('- Infer the implementation language from the referenced files in the spec and preserve that language family.');
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
const likelyFiles = await collectLikelyImplementationFiles(cwd);
|
|
1091
|
+
if (likelyFiles.length > 0) {
|
|
1092
|
+
hints.push('- Likely existing implementation files to reuse first:');
|
|
1093
|
+
for (const file of likelyFiles) {
|
|
1094
|
+
hints.push(` - ${file}`);
|
|
1095
|
+
}
|
|
1096
|
+
hints.push('- Prefer updating one of the listed files when the feature naturally fits there before inventing new modules.');
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
hints.push('- Do not invent files in another language family unless the spec explicitly requires it.');
|
|
1100
|
+
hints.push('- If the spec references existing files, keep the plan anchored to those exact files or their immediate neighbors.');
|
|
1101
|
+
return hints.join('\n');
|
|
1102
|
+
}
|
|
1103
|
+
|
|
984
1104
|
function clampRange(start, end, max) {
|
|
985
1105
|
const s = Math.max(1, Math.min(start, max));
|
|
986
1106
|
const e = Math.max(s, Math.min(end, max));
|
|
@@ -1268,7 +1388,8 @@ async function runSubAgentTask({
|
|
|
1268
1388
|
config,
|
|
1269
1389
|
model,
|
|
1270
1390
|
systemPrompt,
|
|
1271
|
-
onAgentEvent
|
|
1391
|
+
onAgentEvent,
|
|
1392
|
+
extraRolePrompt = ''
|
|
1272
1393
|
}) {
|
|
1273
1394
|
const subSession = { id: `sub-${Date.now()}`, messages: [] };
|
|
1274
1395
|
const rolePrompt = getSubAgentRolePrompt(role);
|
|
@@ -1320,7 +1441,7 @@ async function runSubAgentTask({
|
|
|
1320
1441
|
session: subSession,
|
|
1321
1442
|
config,
|
|
1322
1443
|
model,
|
|
1323
|
-
systemPrompt: `${systemPrompt}\n${rolePrompt}`,
|
|
1444
|
+
systemPrompt: `${systemPrompt}\n${rolePrompt}${extraRolePrompt ? `\n${extraRolePrompt}` : ''}`,
|
|
1324
1445
|
onAgentEvent: wrappedOnAgentEvent,
|
|
1325
1446
|
persistSession: false,
|
|
1326
1447
|
executionMode: 'auto'
|
|
@@ -1346,8 +1467,10 @@ async function buildAutoPlanAndRun({
|
|
|
1346
1467
|
sessionId
|
|
1347
1468
|
}) {
|
|
1348
1469
|
const requirementPacket = buildGoalRequirementPacket(goal, 'planner');
|
|
1349
|
-
const plannerPrompt =
|
|
1350
|
-
|
|
1470
|
+
const plannerPrompt = [
|
|
1471
|
+
buildAutoPlanPlannerGuidance(),
|
|
1472
|
+
'Return strict JSON only with shape {"summary":"...","steps":[{"title":"...","role":"planner|coder|reviewer|tester","task":"..."}]}. No markdown. Always include final reviewer and tester steps.'
|
|
1473
|
+
].join('\n');
|
|
1351
1474
|
let autoPlan = {
|
|
1352
1475
|
summary: `Auto plan for: ${goal}`,
|
|
1353
1476
|
steps: [
|
|
@@ -1406,7 +1529,8 @@ async function buildAutoPlanAndRun({
|
|
|
1406
1529
|
config,
|
|
1407
1530
|
model,
|
|
1408
1531
|
systemPrompt,
|
|
1409
|
-
onAgentEvent
|
|
1532
|
+
onAgentEvent,
|
|
1533
|
+
extraRolePrompt: buildAutoPlanExecutionGuidance(step.role)
|
|
1410
1534
|
});
|
|
1411
1535
|
const outputLooksSuccessful = looksLikeSuccessfulStepOutput(stepResult.text);
|
|
1412
1536
|
const outputHasFailureSignals = stepOutputHasFailureSignals(step.role, stepResult.text);
|
|
@@ -2414,10 +2538,20 @@ export async function createChatRuntime({
|
|
|
2414
2538
|
return { type: 'system', text: `Skill is disabled: ${custom.name}` };
|
|
2415
2539
|
}
|
|
2416
2540
|
|
|
2417
|
-
const
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2541
|
+
const customPrompt =
|
|
2542
|
+
custom.name === 'brainstorm'
|
|
2543
|
+
? [
|
|
2544
|
+
renderCommandPrompt(custom, []),
|
|
2545
|
+
'Explicit brainstorm mode:',
|
|
2546
|
+
'- Ask exactly one clarifying question first if any important uncertainty remains.',
|
|
2547
|
+
'- Do not inspect the repo or generate code unless the user explicitly asks for that.',
|
|
2548
|
+
'- Do not choose an option on the first reply unless the request is already specific enough or the user explicitly asks you to recommend one.',
|
|
2549
|
+
parsedInput.args.length > 0 ? `Current question:\n${parsedInput.args.join(' ')}` : ''
|
|
2550
|
+
]
|
|
2551
|
+
.filter(Boolean)
|
|
2552
|
+
.join('\n\n')
|
|
2553
|
+
: renderCommandPrompt(custom, parsedInput.args);
|
|
2554
|
+
const rendered = await expandFileMentions(customPrompt, process.cwd());
|
|
2421
2555
|
if (custom.metadata.type === 'skill' && onAgentEvent) {
|
|
2422
2556
|
onAgentEvent({ type: 'skill:start', name: custom.name });
|
|
2423
2557
|
}
|
package/src/core/tools.js
CHANGED
|
@@ -1105,17 +1105,55 @@ async function openTarget(root, args) {
|
|
|
1105
1105
|
};
|
|
1106
1106
|
}
|
|
1107
1107
|
|
|
1108
|
-
|
|
1108
|
+
function normalizeEditTargetArgs(args = {}) {
|
|
1109
1109
|
const file = String(args?.file || args?.path || '').trim();
|
|
1110
|
-
const
|
|
1110
|
+
const nestedEdit = args?.edit && typeof args.edit === 'object' ? args.edit : null;
|
|
1111
|
+
if (nestedEdit) {
|
|
1112
|
+
return {
|
|
1113
|
+
file,
|
|
1114
|
+
edit: nestedEdit
|
|
1115
|
+
};
|
|
1116
|
+
}
|
|
1117
|
+
return {
|
|
1118
|
+
file,
|
|
1119
|
+
edit: {
|
|
1120
|
+
kind: args?.kind,
|
|
1121
|
+
target: args?.target,
|
|
1122
|
+
new_content: args?.new_content ?? args?.content,
|
|
1123
|
+
old_text: args?.old_text,
|
|
1124
|
+
new_text: args?.new_text,
|
|
1125
|
+
anchor_text: args?.anchor_text,
|
|
1126
|
+
content: args?.content
|
|
1127
|
+
}
|
|
1128
|
+
};
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
async function editTarget(root, args) {
|
|
1132
|
+
const normalized = normalizeEditTargetArgs(args);
|
|
1133
|
+
const file = normalized.file;
|
|
1134
|
+
const edit = normalized.edit || {};
|
|
1111
1135
|
const kind = String(edit.kind || '').trim();
|
|
1112
1136
|
if (!file || !kind) throw new Error('edit_target requires file and edit.kind');
|
|
1113
1137
|
if (kind === 'replace_block') {
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1138
|
+
try {
|
|
1139
|
+
return await replaceBlock(root, {
|
|
1140
|
+
path: file,
|
|
1141
|
+
target: edit.target,
|
|
1142
|
+
new_content: edit.new_content
|
|
1143
|
+
});
|
|
1144
|
+
} catch (error) {
|
|
1145
|
+
if (!/old_hash mismatch/i.test(String(error?.message || ''))) throw error;
|
|
1146
|
+
const validation = await validateEdit(root, {
|
|
1147
|
+
path: file,
|
|
1148
|
+
kind: 'replace_block',
|
|
1149
|
+
target: edit.target
|
|
1150
|
+
});
|
|
1151
|
+
return replaceBlock(root, {
|
|
1152
|
+
path: file,
|
|
1153
|
+
target: validation.target,
|
|
1154
|
+
new_content: edit.new_content
|
|
1155
|
+
});
|
|
1156
|
+
}
|
|
1119
1157
|
}
|
|
1120
1158
|
if (kind === 'replace_text') {
|
|
1121
1159
|
return replaceText(root, {
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: brainstorming-lite
|
|
3
|
-
description: Lightweight brainstorming skill for 30B-class models. Clarify scope, ask one question at a time, compare a few options, and converge before implementation.
|
|
4
|
-
version: 0.1.0
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
Use this skill before adding new behavior, new features, or meaningful workflow changes.
|
|
8
|
-
|
|
9
|
-
Rules:
|
|
10
|
-
|
|
11
|
-
1. Ask one question at a time.
|
|
12
|
-
Do not dump a long questionnaire. Pick the most important uncertainty and resolve it first.
|
|
13
|
-
|
|
14
|
-
2. Stay concrete.
|
|
15
|
-
Focus on purpose, constraints, success criteria, and what should be intentionally left out.
|
|
16
|
-
|
|
17
|
-
3. Offer 2-3 approaches.
|
|
18
|
-
Keep each option short. Lead with the recommended option and say why.
|
|
19
|
-
|
|
20
|
-
4. Keep the design small.
|
|
21
|
-
Write only enough design for the current scope. Do not inflate a simple task into a full spec process unless needed.
|
|
22
|
-
|
|
23
|
-
5. Confirm before implementation.
|
|
24
|
-
Summarize the chosen direction in a few bullets or a short paragraph, then move to execution only after alignment.
|
|
25
|
-
|
|
26
|
-
Suggested flow:
|
|
27
|
-
- Restate the task briefly
|
|
28
|
-
- Ask the next best question
|
|
29
|
-
- Propose options with tradeoffs
|
|
30
|
-
- Confirm the chosen approach
|
|
31
|
-
- Hand off to plan execution
|
|
32
|
-
|
|
33
|
-
Avoid:
|
|
34
|
-
- large ceremonies
|
|
35
|
-
- repeating the full conversation
|
|
36
|
-
- asking multiple independent questions in one turn
|
|
37
|
-
- proposing implementation details before the problem is clear
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: executing-plan-lite
|
|
3
|
-
description: Lightweight plan execution skill for 30B-class models. Execute the plan in small verified steps with narrow context and frequent checks.
|
|
4
|
-
version: 0.1.0
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
Use this skill when a direction is chosen and the next job is to carry out implementation reliably.
|
|
8
|
-
|
|
9
|
-
Rules:
|
|
10
|
-
|
|
11
|
-
1. Execute the plan in small verified steps.
|
|
12
|
-
Take one bounded step at a time. Avoid mixing planning, implementation, and verification into one big jump.
|
|
13
|
-
|
|
14
|
-
2. Keep the active context narrow.
|
|
15
|
-
Work from the smallest relevant file set and recent evidence. If needed, use sub-agents for independent subtasks.
|
|
16
|
-
|
|
17
|
-
3. Search before editing.
|
|
18
|
-
Use `rg` to locate code, inspect the smallest useful context, then edit.
|
|
19
|
-
|
|
20
|
-
4. Verify after each meaningful change.
|
|
21
|
-
Run the most relevant test or command before claiming success.
|
|
22
|
-
|
|
23
|
-
5. Report progress briefly.
|
|
24
|
-
Summarize what changed, what was verified, and what remains.
|
|
25
|
-
|
|
26
|
-
Suggested flow:
|
|
27
|
-
- identify the next step
|
|
28
|
-
- search and inspect
|
|
29
|
-
- edit
|
|
30
|
-
- verify
|
|
31
|
-
- either continue or stop at a clear checkpoint
|
|
32
|
-
|
|
33
|
-
Use sub-agents when:
|
|
34
|
-
- the task can be split cleanly
|
|
35
|
-
- the write scope is disjoint
|
|
36
|
-
- the result can be reviewed independently
|
|
37
|
-
|
|
38
|
-
Avoid:
|
|
39
|
-
- broad refactors without a reason
|
|
40
|
-
- carrying full history into each step
|
|
41
|
-
- declaring completion without verification
|