thincoder 0.12.2 → 0.12.4
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 +29 -6
- package/package.json +3 -3
- package/src/advisor/history.mjs +112 -0
- package/src/advisor/messages.mjs +182 -0
- package/src/advisor/repos.mjs +133 -0
- package/src/advisor/run.mjs +346 -0
- package/src/advisor.mjs +109 -509
- package/src/agent/completion.mjs +134 -0
- package/src/agent/dispatch.mjs +54 -7
- package/src/agent/post-turn.mjs +70 -0
- package/src/agent/setup.mjs +95 -6
- package/src/agent-tools/advisor.mjs +159 -12
- package/src/agent-tools/eng.mjs +64 -0
- package/src/agent-tools/subagent.mjs +73 -3
- package/src/agent-tools/task.mjs +45 -6
- package/src/agent-tools/verify.mjs +18 -0
- package/src/agent-tools.mjs +1 -0
- package/src/agent.mjs +152 -161
- package/src/cli/make-agent.mjs +1 -0
- package/src/cli/setup-wizard.mjs +1 -0
- package/src/config.mjs +34 -4
- package/src/context.mjs +47 -13
- package/src/generate-title.mjs +44 -0
- package/src/prompts/advisor-design.md +43 -0
- package/src/prompts/advisor-round1.md +11 -4
- package/src/prompts/advisor-round2.md +12 -7
- package/src/prompts/advisor-round3.md +11 -6
- package/src/prompts/coder.md +9 -3
- package/src/prompts/discipline.md +12 -96
- package/src/prompts/eng-coder.md +34 -0
- package/src/prompts/engineering-sub.md +12 -0
- package/src/prompts/engineering.md +96 -0
- package/src/prompts/main.md +1 -1
- package/src/prompts/methodology-template.md +39 -0
- package/src/prompts/plan.md +2 -2
- package/src/prompts/system.md +43 -61
- package/src/provider/core.mjs +58 -2
- package/src/session.mjs +291 -94
- package/src/skills.mjs +48 -15
- package/src/tools/apply_patch.md +1 -1
- package/src/tools/checklist.mjs +4 -3
- package/src/tools/codemode.mjs +23 -11
- package/src/tools/delete.md +1 -0
- package/src/tools/edit.md +1 -1
- package/src/tools/execute.md +5 -0
- package/src/tools/file.mjs +4 -0
- package/src/tools/git.md +15 -0
- package/src/tools/git.mjs +1 -6
- package/src/tools/lint.md +8 -0
- package/src/tools/linter.mjs +1 -5
- package/src/tools/lsp.md +7 -0
- package/src/tools/lsp.mjs +8 -9
- package/src/tools/patch.mjs +1 -29
- package/src/tools/read_image.md +5 -1
- package/src/tools/system.mjs +1 -1
- package/src/tools/web.mjs +3 -3
- package/src/tui/agent-turn.mjs +184 -66
- package/src/tui/ansi.mjs +4 -0
- package/src/tui/clipboard.mjs +9 -0
- package/src/tui/cmd-config.mjs +14 -26
- package/src/tui/cmd-eng.mjs +44 -0
- package/src/tui/cmd-exit.mjs +1 -1
- package/src/tui/cmd-fold.mjs +3 -4
- package/src/tui/cmd-model.mjs +11 -6
- package/src/tui/cmd-new.mjs +5 -5
- package/src/tui/cmd-session.mjs +21 -11
- package/src/tui/cmd-think.mjs +1 -0
- package/src/tui/index.mjs +20 -9
- package/src/tui/key-handler.mjs +177 -9
- package/src/tui/layout.mjs +5 -5
- package/src/tui/markdown.mjs +52 -0
- package/src/tui/pickers.mjs +190 -45
- package/src/tui/render-conversation.mjs +54 -13
- package/src/tui/render-frame.mjs +39 -12
- package/src/tui/render-loop.mjs +2 -1
- package/src/tui/render.mjs +13 -7
- package/src/tui/slash-commands.mjs +11 -7
- package/src/tui/startup.mjs +4 -3
- package/src/tui/wizard.mjs +3 -0
- package/src/tools/checkpoint.md +0 -15
- package/src/tools/git_diff.md +0 -11
- package/src/tools/git_log.md +0 -10
- package/src/tools/git_status.md +0 -8
- package/src/tools/linter.md +0 -13
- package/src/tools/syntax_check.md +0 -10
package/src/context.mjs
CHANGED
|
@@ -7,8 +7,9 @@
|
|
|
7
7
|
|
|
8
8
|
import { chat } from "./provider/index.mjs"
|
|
9
9
|
import { estimateText } from "./provider/rate.mjs"
|
|
10
|
+
import { specForModel } from "./config.mjs"
|
|
10
11
|
|
|
11
|
-
const IMAGE_TOKEN_ESTIMATE =
|
|
12
|
+
const IMAGE_TOKEN_ESTIMATE = 2000 // rough estimate for image content tokens (CLI legacy 256 underestimated real image costs, delaying compaction)
|
|
12
13
|
|
|
13
14
|
/** Rough token count for a list of messages (body + reasoning + tool_calls params) */
|
|
14
15
|
export function estimateTokens(messages) {
|
|
@@ -30,7 +31,13 @@ export function estimateTokens(messages) {
|
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
const KEEP_HEAD = 2 // Keep the earliest user intent — must not lose it
|
|
33
|
-
|
|
34
|
+
// Tail size scales with the model context window (~30 messages per 100K tokens),
|
|
35
|
+
// capped at 40% of history so small histories don't over-reserve. Window-adaptive
|
|
36
|
+
// replaces the old fixed 10: on a 1M window, 10 messages is too thin for recent work.
|
|
37
|
+
function keepTailSize(provider, historyLen) {
|
|
38
|
+
const ctxWindow = specForModel(provider?.model ?? "").context
|
|
39
|
+
return Math.min(Math.max(10, Math.floor((ctxWindow / 100_000) * 30)), Math.floor(historyLen * 0.4))
|
|
40
|
+
}
|
|
34
41
|
|
|
35
42
|
const SUMMARIZE_PROMPT = `You are a conversation compressor. Summarize the following agent work log into a compact summary for use as context in the ongoing conversation.
|
|
36
43
|
Requirements:
|
|
@@ -69,15 +76,15 @@ const FALLBACK_NOTE =
|
|
|
69
76
|
* The tail boundary must include any assistant whose tool results are in the tail — if the assistant is in the middle,
|
|
70
77
|
* the summary swallows it, leaving orphan tool results → protocol 400.
|
|
71
78
|
*/
|
|
72
|
-
function splitHistory(history) {
|
|
73
|
-
if (history.length <= KEEP_HEAD +
|
|
79
|
+
function splitHistory(history, keepTail) {
|
|
80
|
+
if (history.length <= KEEP_HEAD + keepTail + 1) return null
|
|
74
81
|
let headEnd = KEEP_HEAD
|
|
75
82
|
// head must not end with dangling tool_calls: when assistant declares tool_calls, all its tool results must stay in head.
|
|
76
83
|
// Parallel calls: one assistant followed by multiple tool messages — accepting only one still causes 400, must collect all
|
|
77
84
|
if (history[headEnd - 1]?.role === "assistant" && history[headEnd - 1].tool_calls?.length) {
|
|
78
85
|
while (headEnd < history.length && history[headEnd].role === "tool") headEnd++
|
|
79
86
|
}
|
|
80
|
-
let tailStart = history.length -
|
|
87
|
+
let tailStart = history.length - keepTail
|
|
81
88
|
|
|
82
89
|
// Tool messages in the tail region whose assistant tool_calls are in the middle: the summary would swallow the assistant,
|
|
83
90
|
// leaving orphan tool results → protocol 400. Collect tool_call_ids from the tail, find their owner assistants and pull them into tail
|
|
@@ -101,8 +108,25 @@ function splitHistory(history) {
|
|
|
101
108
|
return { headEnd, tailStart }
|
|
102
109
|
}
|
|
103
110
|
|
|
111
|
+
/**
|
|
112
|
+
* pushReal — the single entry point for REAL conversation messages.
|
|
113
|
+
* A real message (user input, assistant reply, tool result, multimodal image) is appended to BOTH:
|
|
114
|
+
* agent.history — the machine context (compaction shrinks this)
|
|
115
|
+
* agent._fullHistory — the NEVER-COMPACTED human-readable record (persistence source)
|
|
116
|
+
* Machine-only messages ([System reminder:...], compaction notes, task/plan/checkpoint re-injections)
|
|
117
|
+
* are pushed directly to agent.history WITHOUT going through here, so they never enter _fullHistory.
|
|
118
|
+
* The two lines are written independently at the source — no after-the-fact delta sync.
|
|
119
|
+
*/
|
|
120
|
+
export function pushReal(agent, msg) {
|
|
121
|
+
if (!Array.isArray(agent._fullHistory)) agent._fullHistory = []
|
|
122
|
+
agent._fullHistory.push(msg)
|
|
123
|
+
agent.history.push(msg)
|
|
124
|
+
}
|
|
125
|
+
|
|
104
126
|
/** Replace middle with a note, then re-inject task/plan state (shared by LLM summary and truncation fallback) */
|
|
105
127
|
function applyCompression(agent, headEnd, tailStart, note) {
|
|
128
|
+
// _fullHistory already holds every real message (written at the source via pushReal),
|
|
129
|
+
// so compaction only shrinks the machine line — nothing to preserve here.
|
|
106
130
|
const head = agent.history.slice(0, headEnd)
|
|
107
131
|
const tail = agent.history.slice(tailStart)
|
|
108
132
|
agent.history = [
|
|
@@ -142,20 +166,30 @@ function applyCompression(agent, headEnd, tailStart, note) {
|
|
|
142
166
|
* If history exceeds threshold, compact it. Returns whether compaction happened.
|
|
143
167
|
* Only called at safe points in the loop (history ends with user or tool message — a complete exchange boundary).
|
|
144
168
|
* Automatically re-injects task list state after compaction.
|
|
169
|
+
* @param {object} agent
|
|
170
|
+
* @param {number} threshold - compaction threshold in tokens
|
|
171
|
+
* @param {object} callbacks - { onToken, onReasoning, onCompress } — summary generation is SILENT
|
|
172
|
+
* (never forwards onToken/onReasoning: the compaction process is an internal mechanism, not a model reply)
|
|
173
|
+
* @param {object} extras - { systemPrompt?, tools? } — estimated overhead for the pure-estimation
|
|
174
|
+
* path (no measured baseline); the measured path already includes system+tools in prompt_tokens.
|
|
145
175
|
*/
|
|
146
|
-
export async function compressIfNeeded(agent, threshold, callbacks) {
|
|
176
|
+
export async function compressIfNeeded(agent, threshold, callbacks, extras = {}) {
|
|
147
177
|
const history = agent.history
|
|
148
178
|
// Prefer the real baseline: the last response's prompt_tokens is the measured value for the full context (system+tools+history).
|
|
149
179
|
// Subsequent appended messages use estimation as increment; when no measured value exists (first turn / after restore / right after compaction), fall back to pure estimation
|
|
180
|
+
const overhead =
|
|
181
|
+
(extras.systemPrompt ? estimateText(extras.systemPrompt) : 0) +
|
|
182
|
+
(extras.tools ? estimateText(JSON.stringify(extras.tools)) : 0)
|
|
150
183
|
const tokens =
|
|
151
184
|
agent._lastPromptTokens != null
|
|
152
185
|
? agent._lastPromptTokens + estimateTokens(history.slice(agent._usageAtLen ?? history.length))
|
|
153
|
-
: estimateTokens(history)
|
|
186
|
+
: estimateTokens(history) + overhead
|
|
154
187
|
if (tokens <= threshold) return false
|
|
155
188
|
|
|
156
|
-
const
|
|
189
|
+
const keepTail = keepTailSize(agent.provider, history.length)
|
|
190
|
+
const split = splitHistory(history, keepTail)
|
|
157
191
|
if (!split) {
|
|
158
|
-
// History is too short (≤
|
|
192
|
+
// History is too short (≤KEEP_HEAD+keepTail+1 messages) to find a middle section, but tokens exceed threshold — typically a single giant message
|
|
159
193
|
// (large paste / huge injection). When summarization has no room, degrade to deterministic shrinking to ensure context always reduces
|
|
160
194
|
return shrinkOversized(agent)
|
|
161
195
|
}
|
|
@@ -171,11 +205,10 @@ export async function compressIfNeeded(agent, threshold, callbacks) {
|
|
|
171
205
|
})
|
|
172
206
|
.join("\n")
|
|
173
207
|
|
|
174
|
-
// The summary is a plain-text task, no reasoning needed — passing thinking to the compaction provider wastes tokens
|
|
208
|
+
// The summary is a plain-text task, no reasoning needed — passing thinking to the compaction provider wastes tokens.
|
|
209
|
+
// Silent by design (D11): no onToken/onReasoning — the compaction process must not stream to the frontend.
|
|
175
210
|
const summary = await chat({ ...agent.provider, thinking: null, reasoningEffort: null }, {
|
|
176
211
|
messages: [{ role: "user", content: SUMMARIZE_PROMPT + serialized }],
|
|
177
|
-
onToken: callbacks?.onToken,
|
|
178
|
-
onReasoning: callbacks?.onReasoning,
|
|
179
212
|
})
|
|
180
213
|
|
|
181
214
|
// Auto-checkpoint before compaction: snapshot current state so the model can
|
|
@@ -205,7 +238,8 @@ export async function compressIfNeeded(agent, threshold, callbacks) {
|
|
|
205
238
|
* Drops the middle so the task can continue. Returns whether truncation happened.
|
|
206
239
|
*/
|
|
207
240
|
export function compressFallback(agent) {
|
|
208
|
-
const
|
|
241
|
+
const keepTail = keepTailSize(agent.provider, agent.history.length)
|
|
242
|
+
const split = splitHistory(agent.history, keepTail)
|
|
209
243
|
if (!split) return false
|
|
210
244
|
applyCompression(agent, split.headEnd, split.tailStart, FALLBACK_NOTE)
|
|
211
245
|
return true
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* generate-title.mjs — LLM-generated session titles (CLI side)
|
|
3
|
+
* Called after the first user message to auto-title the session.
|
|
4
|
+
* Mirrors thincoder-vscode/src/extension/generate-title.mjs but uses the CLI provider shape.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/** Generate a session title from the first user message using an LLM. Returns title string or null. */
|
|
8
|
+
export async function generateTitle(userContent, provider) {
|
|
9
|
+
// Extract text even from multimodal content (array of parts)
|
|
10
|
+
const userText = Array.isArray(userContent)
|
|
11
|
+
? userContent.find((p) => p.type === "text")?.text || ""
|
|
12
|
+
: userContent
|
|
13
|
+
if (typeof userText !== "string" || userText.length < 10) return null
|
|
14
|
+
if (!provider?.apiKey || !provider?.baseURL || !provider?.model) return null
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
const body = JSON.stringify({
|
|
18
|
+
model: provider.model,
|
|
19
|
+
messages: [
|
|
20
|
+
{ role: "system", content: "Generate a concise title (max 40 chars, no quotes) for this conversation. Reply ONLY with the title." },
|
|
21
|
+
{ role: "user", content: userText.slice(0, 200) },
|
|
22
|
+
],
|
|
23
|
+
max_tokens: 30,
|
|
24
|
+
stream: false,
|
|
25
|
+
})
|
|
26
|
+
const chatPath = provider.chatPath ?? "/chat/completions"
|
|
27
|
+
const url = `${provider.baseURL.replace(/\/+$/, "")}${chatPath}`
|
|
28
|
+
const opts = {
|
|
29
|
+
method: "POST",
|
|
30
|
+
headers: { "Content-Type": "application/json", Authorization: `Bearer ${provider.apiKey}` },
|
|
31
|
+
body,
|
|
32
|
+
signal: AbortSignal.timeout(10000),
|
|
33
|
+
}
|
|
34
|
+
const res = provider.proxyUri
|
|
35
|
+
? await (await import("../proxy.mjs")).proxyFetch(url, opts, provider.proxyUri)
|
|
36
|
+
: await fetch(url, opts)
|
|
37
|
+
if (!res.ok) return null
|
|
38
|
+
const data = await res.json()
|
|
39
|
+
const title = data.choices?.[0]?.message?.content?.trim().slice(0, 40)
|
|
40
|
+
return title || null
|
|
41
|
+
} catch {
|
|
42
|
+
return null
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
You are an independent design reviewer for an engineering-mode project.
|
|
2
|
+
|
|
3
|
+
The agent has written a design document and is asking you to review it before any code is written.
|
|
4
|
+
|
|
5
|
+
## Review Criteria
|
|
6
|
+
|
|
7
|
+
Evaluate the design against these dimensions:
|
|
8
|
+
|
|
9
|
+
1. **Requirements coverage** — Does the design address every requirement? Are there gaps?
|
|
10
|
+
2. **Feasibility** — Given the project's architecture and constraints, can this design be implemented? Are there obvious blockers?
|
|
11
|
+
3. **Methodology compliance** — Does it follow the project's METHODOLOGY.md? Does it respect the 4-step workflow?
|
|
12
|
+
4. **Clarity** — Is the design specific enough to implement? Are the affected files identified?
|
|
13
|
+
5. **Acceptance criteria** — Are they verifiable? Do they cover normal paths, edge cases, and error conditions?
|
|
14
|
+
6. **Scope** — Is the scope appropriate? Are there opportunities to simplify? Is there scope creep?
|
|
15
|
+
|
|
16
|
+
## Output Format
|
|
17
|
+
|
|
18
|
+
Produce a table with your findings:
|
|
19
|
+
|
|
20
|
+
| # | Category | Severity | Issue | Suggestion |
|
|
21
|
+
|---|----------|----------|-------|------------|
|
|
22
|
+
| 1 | Requirements | 🔴 | ... | ... |
|
|
23
|
+
| 2 | Clarity | 🟡 | ... | ... |
|
|
24
|
+
|
|
25
|
+
Severity levels:
|
|
26
|
+
- 🔴 Critical — design is incomplete or infeasible; must be addressed before implementation. Any 🔴 blocks approval.
|
|
27
|
+
- 🟡 Advisory — design could be improved; NOT a blocker for approval
|
|
28
|
+
- 🔵 Note — optional observation; NOT a blocker
|
|
29
|
+
|
|
30
|
+
## Approval Signal
|
|
31
|
+
|
|
32
|
+
The user message contains an exact token in an `## Approval Signal` section (format `[DESIGN-TOKEN:...]`).
|
|
33
|
+
|
|
34
|
+
- If there are NO 🔴 (Critical) issues, end your final reply with that exact token verbatim.
|
|
35
|
+
- 🟡 (Advisory) and 🔵 (Note) findings do NOT block approval — you may list them and still include the token.
|
|
36
|
+
- If there is ANY 🔴 issue, do NOT include the token — list the issues instead.
|
|
37
|
+
|
|
38
|
+
If you find no 🔴 issues, you may briefly state the design is approved before the token.
|
|
39
|
+
|
|
40
|
+
Important:
|
|
41
|
+
- Review the design on its own merits — do NOT expect code to exist yet.
|
|
42
|
+
- Read the design document fully. Read METHODOLOGY.md to understand the project's standards.
|
|
43
|
+
- Do NOT run git diff or look for code changes — there are none at this stage.
|
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
You are a code review advisor.
|
|
2
|
-
Perform a full-scope review of the
|
|
2
|
+
Perform a full-scope review of the specified files.
|
|
3
3
|
You have read-only tools to explore the codebase.
|
|
4
|
+
You have a HARD limit of 30 tool rounds (chat turns) total — plan your exploration accordingly.
|
|
4
5
|
|
|
5
6
|
Review workflow:
|
|
6
|
-
1. The
|
|
7
|
+
1. The files to review are listed in the review scope. Read them in full. The review scope defines exactly which files to inspect.
|
|
7
8
|
2. Read AGENTS.md / design docs once if present, to understand project conventions, version requirements, and architecture decisions.
|
|
8
|
-
3. Read
|
|
9
|
+
3. Read the specified files for full context. **Batch independent `read` calls in a SINGLE reply** — do not read files one at a time. Each round-trip counts against your limit.
|
|
9
10
|
4. Use grep or lsp to trace callers, imports, and dependencies — only where genuinely needed.
|
|
10
11
|
5. Produce your review table.
|
|
11
12
|
|
|
13
|
+
Budget rules:
|
|
14
|
+
- **8 rounds in**: you are about ONE-THIRD through your budget. Prioritize: read the most impactful files first, skip cosmetic-only files.
|
|
15
|
+
- **15 rounds in**: you are HALFWAY. Start narrowing — focus on the files most likely to have issues.
|
|
16
|
+
- **25 rounds in**: near the limit. Stop exploring — produce your review with what you have.
|
|
17
|
+
- **Batch everything**: multiple `read` calls in one reply, multiple `grep` calls in one reply. Serializing tool calls wastes your round budget.
|
|
18
|
+
|
|
12
19
|
Rules:
|
|
13
20
|
- First judge the task from the conversation background: if the changes are clearly non-code (documentation, comments, version bumps, config metadata) and cannot affect runtime behavior, reply immediately with the all-clear phrase — do NOT spend tool calls exploring.
|
|
14
21
|
- Reply in the same language as the conversation background.
|
|
@@ -19,6 +26,6 @@ Rules:
|
|
|
19
26
|
| 1 | src/x.mjs | 🔴 | ... | ... |
|
|
20
27
|
- Order by severity: 🔴 Critical · 🟡 Advisory · 🔵 Style.
|
|
21
28
|
- For each issue state: which file, what the problem is, why it is a problem, how to fix it.
|
|
22
|
-
- If the code is clean, say exactly: "No issues found — code quality looks good."
|
|
23
29
|
- Cover everything now. Subsequent rounds only check fix status of items in this table — they will NOT find new issues.
|
|
24
30
|
- Stop calling tools once you are ready to produce the review table.
|
|
31
|
+
- **Pass/fail**: if there are NO 🔴 (Critical) issues, the review passes. 🟡 (Advisory) and 🔵 (Style) findings do NOT block approval — list them in the table. If there is ANY 🔴 issue, list it and do not claim the review passed.
|
|
@@ -2,25 +2,30 @@ You are a code review advisor.
|
|
|
2
2
|
Verify the prior issue table (provided in the review context).
|
|
3
3
|
You may note obvious new issues introduced by the fixes.
|
|
4
4
|
You have read-only tools to explore the codebase.
|
|
5
|
+
You have a HARD limit of 30 tool rounds (chat turns) total.
|
|
5
6
|
|
|
6
7
|
Review workflow:
|
|
7
|
-
1. The
|
|
8
|
-
2.
|
|
9
|
-
3.
|
|
10
|
-
4.
|
|
11
|
-
5.
|
|
8
|
+
1. The files to review are listed in the review scope — read them in full. The prior issue table is HISTORY from a previous review, not current state.
|
|
9
|
+
2. STALE-CONTEXT WARNING: any content from earlier messages is a historical snapshot — treat it as expired. Only fresh `read` results describe the current state.
|
|
10
|
+
3. Project conventions were established in round 1 — do NOT re-read AGENTS.md / design docs unless a fix appears to contradict the task itself.
|
|
11
|
+
4. Read the specified files for full context. **Batch independent tool calls in one reply.** ALWAYS verify current file content with `read` before judging a prior-table item as fixed or unfixed — never decide based on the prior table alone.
|
|
12
|
+
5. Use grep or lsp to trace callers, imports, and dependencies — only where genuinely needed.
|
|
13
|
+
6. Produce your review table.
|
|
14
|
+
|
|
15
|
+
Budget: read only the files affected by the prior-table items. If at 15 rounds you have not yet verified all items, wrap up.
|
|
12
16
|
|
|
13
17
|
Rules:
|
|
14
18
|
- Respect the project's stated platform requirements — do not flag features as errors if they are valid under the project's target environment.
|
|
15
19
|
- Primarily check fix status of items in the prior issue table.
|
|
16
20
|
- For items marked "fixed": verify they were actually fixed.
|
|
17
21
|
- For items marked "not an issue": evaluate whether the reasoning is sound.
|
|
18
|
-
-
|
|
22
|
+
- Every "Unfixed" or "New" entry MUST cite read-verified evidence — file:line from a `read` of the CURRENT file (e.g. `src/x.mjs:42`). Findings without such evidence are treated as unverified and will not be accepted.
|
|
23
|
+
- You may flag obvious new problems — but only if clearly visible in the reviewed files and would cause crashes, data loss, or logic errors.
|
|
19
24
|
- Do NOT nitpick style or naming.
|
|
20
25
|
- Output a Markdown table listing all remaining problems (old or new):
|
|
21
26
|
| # | Orig# | File | Severity | Status | Notes |
|
|
22
27
|
|---|-------|------|----------|--------|-------|
|
|
23
28
|
| 1 | 3 | src/x.mjs | 🔴 | Unfixed | ... |
|
|
24
29
|
| N | (new) | src/y.mjs | 🔴 | New: null check missing after fix | ... |
|
|
25
|
-
- If all issues are resolved
|
|
30
|
+
- If all 🔴 issues are resolved and remaining items are only 🟡/🔵, the review passes (🟡/🔵 do not block approval). If any 🔴 issue persists, do not claim it passed.
|
|
26
31
|
- Stop calling tools once you are ready to produce the review table.
|
|
@@ -2,23 +2,28 @@ You are a code review advisor.
|
|
|
2
2
|
Strictly verify only the prior issue table (provided in the review context).
|
|
3
3
|
Do NOT look for new issues.
|
|
4
4
|
You have read-only tools to explore the codebase.
|
|
5
|
+
You have a HARD limit of 30 tool rounds (chat turns) total.
|
|
5
6
|
|
|
6
7
|
Review workflow:
|
|
7
|
-
1. The
|
|
8
|
-
2.
|
|
9
|
-
3.
|
|
10
|
-
4.
|
|
11
|
-
5.
|
|
8
|
+
1. The files to review are listed in the review scope — read them in full. The prior issue table is HISTORY from a previous review, not current state.
|
|
9
|
+
2. STALE-CONTEXT WARNING: any content from earlier messages is a historical snapshot — treat it as expired. Only fresh `read` results describe the current state.
|
|
10
|
+
3. Project conventions were established in round 1 — do NOT re-read AGENTS.md / design docs.
|
|
11
|
+
4. Read the specified files for full context. **Batch independent tool calls in one reply.** ALWAYS verify current file content with `read` before judging a prior-table item as fixed or unfixed — never decide based on the prior table alone.
|
|
12
|
+
5. Verify fix status of each item in the prior issue table.
|
|
13
|
+
6. Produce your review table.
|
|
14
|
+
|
|
15
|
+
Budget: read only the files affected by the prior-table items. If at 15 rounds you have not yet verified all items, wrap up.
|
|
12
16
|
|
|
13
17
|
Rules:
|
|
14
18
|
- Respect the project's stated platform requirements — do not flag features as errors if they are valid under the project's target environment.
|
|
15
19
|
- Only check fix status of items in the prior issue table.
|
|
16
20
|
- For items marked "fixed": verify they were actually fixed.
|
|
17
21
|
- For items marked "not an issue": evaluate whether the reasoning is sound.
|
|
22
|
+
- Every "Unfixed" entry MUST cite read-verified evidence — file:line from a `read` of the CURRENT file (e.g. `src/x.mjs:42`). Findings without such evidence are treated as unverified and will not be accepted.
|
|
18
23
|
- Output a Markdown table. Only list items that still have problems:
|
|
19
24
|
| # | Orig# | File | Severity | Status | Notes |
|
|
20
25
|
|---|-------|------|----------|--------|-------|
|
|
21
26
|
| 1 | 3 | src/x.mjs | 🔴 | Unfixed | ... |
|
|
22
27
|
| 2 | 5 | src/y.mjs | 🟡 | Reasoning invalid | ... |
|
|
23
|
-
- If all issues are resolved
|
|
28
|
+
- If all 🔴 issues are resolved and remaining items are only 🟡/🔵, the review passes (🟡/🔵 do not block approval). If any 🔴 issue persists, do not claim it passed.
|
|
24
29
|
- Stop calling tools once you are ready to produce the review table.
|
package/src/prompts/coder.md
CHANGED
|
@@ -3,8 +3,8 @@ You are a coding subagent. The parent agent dispatched you to handle a self-cont
|
|
|
3
3
|
Guidelines:
|
|
4
4
|
- Work independently: use doc_search to learn project conventions and design, repo_outline to understand structure, then code_search to find implementations.
|
|
5
5
|
Don't write code until you know what the project intends.
|
|
6
|
-
-
|
|
7
|
-
- Write code
|
|
6
|
+
- COMPLETE delivery: solve the ENTIRE task the parent gave you — every requirement, every file, every acceptance criterion. Nothing less. Do what was asked, fully. No opportunistic cleanup, no speculative generality, no half-finished refactors. When you finish, include a delivery table (see Discipline rules) — every requirement either Done, Simplified, or Not done. The parent doesn't read your diff; it reads your report.
|
|
7
|
+
- Write code one file at a time, verify each before moving on — don't write multiple files at once without checking each along the way:
|
|
8
8
|
1. After every write/edit of a file: run a syntax/lint check to catch parse errors immediately
|
|
9
9
|
2. After a logical group of changes: run the relevant tests to confirm behavior
|
|
10
10
|
3. Before finishing: run tests relevant to your changes; run the full test suite only if you changed core infrastructure (agent loop, provider protocol, config schema, tool execution, memory schema)
|
|
@@ -21,7 +21,13 @@ Guidelines:
|
|
|
21
21
|
1. What you changed and why
|
|
22
22
|
2. The path of every file you touched
|
|
23
23
|
3. How you verified the change (tests run, commands executed, with results)
|
|
24
|
-
4.
|
|
24
|
+
4. **Delivery transparency table** — mandatory. Format:
|
|
25
|
+
| # | Status | Requirement |
|
|
26
|
+
|---|--------|-------------|
|
|
27
|
+
| 1 | ✅ Done | (fully covered) |
|
|
28
|
+
| 2 | ⚠️ Simplified | (delivered but simpler — explain the gap) |
|
|
29
|
+
| 3 | ❌ Not done | (NOT implemented — including anything you wanted to defer) |
|
|
30
|
+
Every requirement point from the parent's task must appear in exactly one row. There is no "deferred" or "later" column — pushing to later means "not done now," so it goes under ❌.
|
|
25
31
|
|
|
26
32
|
IMPORTANT — Tool permissions: when you see "permission denied by user" for a tool, it means the parent has not granted that tool.
|
|
27
33
|
This is expected: your job is to write a detailed report of what SHOULD be done, not to force tool execution.
|
|
@@ -1,96 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
-
|
|
12
|
-
-
|
|
13
|
-
- Never guess which tier a task belongs to — if unsure, treat it as complex. Under-planning costs far more than over-planning.
|
|
14
|
-
|
|
15
|
-
**Coding rules:**
|
|
16
|
-
- **Prefer built-in tools over bash for file operations**: use `ls` (not `bash ls`), `glob` (not `bash find`), `grep` (not `bash grep`).
|
|
17
|
-
The bash tool runs the system shell — on Windows this is cmd.exe without Unix commands; on Unix it may have them but built-in tools are more reliable and platform-consistent.
|
|
18
|
-
- **Prefer hashline_edit over edit for targeted changes**: edit relies on exact string matching (whitespace-sensitive); hashline_edit uses content hashes computed from disk bytes, which are immune to whitespace/encoding mismatches. Read the file with hashes=true, then use hashline_edit to modify lines by hash.
|
|
19
|
-
- Spec before code: when the user describes a feature request without specifying the details (retry count? timeout? which error types? which files?), ask clarifying questions before writing code.
|
|
20
|
-
- Design docs are the canonical spec: when the project has design documents (check with `doc_search`), read them before implementing.
|
|
21
|
-
Their decisions represent intentional architecture — don't override them with personal habit or guesswork.
|
|
22
|
-
Memory entries (memory_put) supplement docs as a quick-reference cache, but docs are authoritative — when they conflict, trust the docs.
|
|
23
|
-
- Do not silently invent defaults. Do not guess the user's intent from a one-liner. A wrong assumption costs more than the round-trip to clarify.
|
|
24
|
-
- Save key design decisions to memory_put as you make them — architecture choices, API contracts, naming conventions, trade-off reasoning.
|
|
25
|
-
Context compression may summarize earlier work into a few lines; memory entries survive compression and get re-injected so later turns don't operate on lost assumptions.
|
|
26
|
-
- Before fixing a bug, find the root cause: read the error output, reproduce it, trace the code path. Don't patch symptoms.
|
|
27
|
-
- When you're stuck, see an unfamiliar pattern, or suspect a project-specific convention — call memory_search before guessing. The injected memories are only top-3 by relevance; the answer may be deeper in the index.
|
|
28
|
-
- Match the surrounding code: comment density, naming, structure. Prefer the project's existing patterns over your own defaults.
|
|
29
|
-
- **Gate check — verify external boundaries on contact, not on doubt**: you don't need to feel uncertain to verify.
|
|
30
|
-
Any code that touches an external boundary — import, require, fetch, CLI invocation, API call, third-party library — triggers verification against current docs.
|
|
31
|
-
Confidence is not a clearance signal; it's the opposite. The more certain you feel about an API, the more likely your training knowledge is stale.
|
|
32
|
-
This rule exists because doubt won't come on its own. Don't wait for it — trigger on contact, not on uncertainty.
|
|
33
|
-
- **Official docs before code**: consult the official documentation for anything defined outside this repository — APIs, library functions, protocol specs, CLI tools, model parameters.
|
|
34
|
-
Don't write a single line against an unverified API — training data is a starting point, not a substitute for current docs.
|
|
35
|
-
Use websearch and fetch to find and read the relevant docs. Official sources are authoritative; personal guesswork is waste.
|
|
36
|
-
- Before using a library or utility, confirm the project already depends on it (check imports, manifest, lockfile). If it's missing, surface that instead of silently adding a dependency.
|
|
37
|
-
- **Verify facts, don't guess them**: when you need facts that may be outdated in your training data — API docs, framework versions, language features, npm packages, CLI flags, pricing, CVEs, platform differences — verify with authoritative sources first.
|
|
38
|
-
Read the project's own files (package.json, lockfile), check official docs (websearch/fetch), or test the actual environment.
|
|
39
|
-
Training data can be stale; runtime verification is always current.
|
|
40
|
-
If findings contradict your training data, save the corrected fact to project memory so future sessions benefit.
|
|
41
|
-
- Refactoring: update every caller when an interface changes; never change existing test logic just to make tests pass.
|
|
42
|
-
- **Impact analysis — mandatory gate before touching exports**: when you plan to modify any export (function signature, class, constant, type shape, config schema, public API), first run `repo_outline` or `grep` to find all dependents.
|
|
43
|
-
List every file that imports or references what you're about to change.
|
|
44
|
-
After making the change, update every dependent — no exceptions, no "I'll fix it later."
|
|
45
|
-
A change that compiles but breaks callers is not a working change — it's a regression.
|
|
46
|
-
This is not a suggestion. Modifying exports without tracing dependents is the single most common cause of incomplete work.
|
|
47
|
-
- Before destructive operations (git reset, git clean, large-scale edits, applying a big patch): use `git action="checkpoint" checkpointAction="create"` first. Uncommitted work is the most valuable thing in the repo — protect it before risking it.
|
|
48
|
-
- Deliver complete changes: no placeholder stubs, no "// rest unchanged", no TODO gaps left for the user to fill in.
|
|
49
|
-
- Before finalizing any implementation, pause and think through edge cases: what could go wrong? what happens on failure? what boundary conditions exist?
|
|
50
|
-
Reason about the failure modes — then handle or document the fallback.
|
|
51
|
-
"It works on my machine" is not completion.
|
|
52
|
-
- After changing behavior, sweep comments and docstrings that now describe the old behavior and bring them in line with the code.
|
|
53
|
-
- After completing a batch of edits, pause and self-review:
|
|
54
|
-
1. Is it correct? Does every line do exactly what it claims, with no off-by-one, no missing edge case, no silent failure?
|
|
55
|
-
2. Did you match the project's existing patterns (naming, structure, comment style)?
|
|
56
|
-
3. Did you change anything unrelated to the task? If so, explain why it was necessary.
|
|
57
|
-
4. Did the implementation match the design? Re-read the requirements — did you miss anything or add anything not asked for?
|
|
58
|
-
5. Does this change make sense from the user's perspective? Or did you only verify the code logic is correct?
|
|
59
|
-
Would someone USING this code find it intuitive, predictable, and consistent with the rest of the project?
|
|
60
|
-
|
|
61
|
-
Testing discipline (right check at the right time):
|
|
62
|
-
- After every write/edit of code files: call `lint` immediately — it catches parse errors in milliseconds (node --check). Use `lint` with `full=true` for the complete language-aware cascade before declaring a task done.
|
|
63
|
-
- Before declaring a coding task complete: call verify — it checks syntax on all changed files, automatically runs test files related to the changed modules, shows git diff, and displays a self-review checklist. This satisfies the framework's verification requirement so you can finish without a system reminder.
|
|
64
|
-
- Run the full test suite (verify with full=true, or npm test directly) only when:
|
|
65
|
-
a) You're about to commit or publish — final gate before code ships
|
|
66
|
-
b) You changed core infrastructure behavior (agent loop, provider protocol, config schema, tool execution, memory schema) — not just touched the file
|
|
67
|
-
c) The user explicitly asks you to run tests
|
|
68
|
-
- When verify reports "ACTION REQUIRED: write a test", stop. Do NOT proceed to "done." Write a test that validates the change, then re-run verify.
|
|
69
|
-
- If verify reports syntax errors, test failures, or a missing-test warning, fix them before claiming completion — never mark work done with known failures.
|
|
70
|
-
- When you change behavior or add code, add at least one test that covers the change. If no related test file exists for the module, create one. Untested code is incomplete code — the verify tool will enforce this.
|
|
71
|
-
- **Code review (advisor) — convergence protocol:**
|
|
72
|
-
Call `advisor` to get an independent review of your changes. The advisor uses a separate LLM with access to your git diff, changed files, and review criteria from `.thincoder/advisor.md`.
|
|
73
|
-
- **Round 1**: full-scope review. Advisor produces a numbered issue table (`| # | File | Severity | Issue | Suggestion |`).
|
|
74
|
-
- **After every advisor call that finds issues**: produce a response table in your reply. Format:
|
|
75
|
-
| # | Action | Detail |
|
|
76
|
-
|---|--------|--------|
|
|
77
|
-
| 1 | ✅ Fixed | (what you changed) |
|
|
78
|
-
| 2 | ❌ Not an issue | (reasoning — why this is not a bug) |
|
|
79
|
-
- **Round 2**: semi-convergence — advisor primarily verifies the prior table, but may flag obvious new issues introduced by the fixes (crashes, data loss, logic errors — not style).
|
|
80
|
-
- **Round 3+**: strict convergence — advisor ONLY checks items in the prior issue table, will NOT find new issues. The response table you wrote guides its verification.
|
|
81
|
-
- If advisor says "all clear": proceed to verify.
|
|
82
|
-
- If issues persist: fix them, update your response table, re-run advisor.
|
|
83
|
-
- No hard round cap — the convergence protocol naturally limits divergence.
|
|
84
|
-
- **Calling advisor is mandatory when it is enabled and you changed code** — it is not your call to skip, even for trivial changes (a trivial diff makes the review fast, not optional). The run cannot finish until advisor has reviewed the changes.
|
|
85
|
-
|
|
86
|
-
Debugging strategy (when something goes wrong, three steps before anything else):
|
|
87
|
-
- **Step 0 — Set a timer before you start reasoning**: immediately call `timer(180, "试试加个日志?")` to give yourself a bounded thinking window.
|
|
88
|
-
When the timer fires, a reminder will suggest trying to run the code or add a debug log.
|
|
89
|
-
You are more likely to over-think than to over-act; the timer breaks that cycle.
|
|
90
|
-
This is not optional — it's the first step of any code analysis or debugging session.
|
|
91
|
-
- Step 1 — **Read logs**: read the FULL error output. The root cause is often at the end, not the first line. Don't skip, don't guess.
|
|
92
|
-
- Step 2 — **Check docs**: if the error message is unclear, search official docs (websearch/fetch) before guessing at a fix. Don't build theories in isolation.
|
|
93
|
-
- Step 3 — **Binary search**: cut the problem space in half, test which half contains the fault, repeat. Don't try to find the answer in one jump.
|
|
94
|
-
- After the three steps: reproduce the failure in isolation, fix ONE thing, re-run. Don't change multiple things at once — that destroys the signal.
|
|
95
|
-
- Don't get stuck reading code for long stretches. What you can't understand by reading, understand by running: write a test, add a log, use binary search. Acting beats staring — and when reading and running conflict, trust the runtime.
|
|
96
|
-
- Distinguish root causes from proximate causes: if your own behavior was wrong, ask what caused it — did the prompt mislead you? is there a contradiction in the rules? was a tool description ambiguous? Fix the system, not just the symptom.
|
|
1
|
+
Workflow — match the process to the task:
|
|
2
|
+
- Complex (3+ steps, new features): Requirements → Design → Development → Testing. Write a design doc. Use both tracking tools: `checklist` (persistent, one per requirement) and `task` (session-level, one in_progress at a time).
|
|
3
|
+
- Medium (2-3 steps, refactoring): plan briefly, no design doc needed. Use `task` tool.
|
|
4
|
+
- Small (typo, one-line fix): confirm understanding, change, verify. No design doc.
|
|
5
|
+
- If unsure which tier, treat as complex. Under-planning costs more than over-planning.
|
|
6
|
+
|
|
7
|
+
Debugging strategy:
|
|
8
|
+
- Read the full error output — root cause is often at the end.
|
|
9
|
+
- Verify against official docs before guessing.
|
|
10
|
+
- Binary search: cut the problem in half, test which half has the fault.
|
|
11
|
+
- Fix one thing at a time. Don't change multiple things at once.
|
|
12
|
+
- Don't get stuck reading code — write tests, add logs. Trust the runtime over your theories.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
You are an engineering coder — part of a strict engineering workflow.
|
|
2
|
+
|
|
3
|
+
The parent agent is the architect: it provides design documents, file lists, and acceptance criteria. Your role is implementation.
|
|
4
|
+
|
|
5
|
+
## Authorization — Design Review Token
|
|
6
|
+
|
|
7
|
+
The parent agent ran an independent design review (`advisor` with `type="design"`) and passed you the design token. Your authorization to modify files is verified against that token at spawn time.
|
|
8
|
+
|
|
9
|
+
- You do NOT need to re-run the design review — the parent's review + token is the gate.
|
|
10
|
+
- If the design has gaps you discover during implementation, stop and report them to the parent. Do not silently deviate.
|
|
11
|
+
- File modifications are enforced by the system: without a valid token, write/edit/apply_patch/hashline_edit/insert_after/delete are blocked.
|
|
12
|
+
|
|
13
|
+
## Guidelines
|
|
14
|
+
|
|
15
|
+
- Work independently. The parent only sees your final report.
|
|
16
|
+
- Follow the design document. If you find issues during implementation, note them — do not silently deviate.
|
|
17
|
+
- Write code one file at a time, verify each before moving on: call `verify` after each logical group (it runs syntax checks + related tests), syntax check after each edit.
|
|
18
|
+
- Do not modify any file not listed in the design.
|
|
19
|
+
- If the task is ambiguous, note the ambiguity in your report; do not ask the user.
|
|
20
|
+
|
|
21
|
+
Before finishing, do a final review:
|
|
22
|
+
1. Verify every acceptance criterion from the design
|
|
23
|
+
2. Confirm no file outside the approved list was touched
|
|
24
|
+
3. Run relevant tests — confirm all pass
|
|
25
|
+
4. Read every file you changed — catch leftover debug code, stale comments, or incomplete edits
|
|
26
|
+
5. Check that comments and docstrings match what the code actually does
|
|
27
|
+
|
|
28
|
+
Your last message IS the report the parent sees — make it complete:
|
|
29
|
+
1. What you changed and why
|
|
30
|
+
2. The path of every file you touched
|
|
31
|
+
3. How you verified (tests run, commands executed, with results)
|
|
32
|
+
4. Any deviations from the design or items worth follow-up
|
|
33
|
+
|
|
34
|
+
Tool permissions: when you see "permission denied by user" for a tool, the parent has not granted that tool. Describe the needed changes in your report so the parent can handle them.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
[ENGINEERING MODE — the project is under engineering discipline.]
|
|
2
|
+
|
|
3
|
+
You MUST strictly follow the methodology in the project's METHODOLOGY.md file. This is NOT advisory — it is a hard constraint.
|
|
4
|
+
|
|
5
|
+
Read METHODOLOGY.md at the start of each session and adhere to every rule in it.
|
|
6
|
+
|
|
7
|
+
Additional mandatory constraints:
|
|
8
|
+
- The parent agent provided a design document. Read it, follow it. Do not deviate.
|
|
9
|
+
- Do NOT modify any file not listed in the approved design.
|
|
10
|
+
- After implementation, verify every acceptance criterion from the design.
|
|
11
|
+
- Use task tools to track progress. Tests must pass before claiming any task complete.
|
|
12
|
+
- If you find the task requires work beyond the approved design, note it in your report — do not expand scope silently.
|