mocode-ai 1.0.14 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -19
- package/README.zh-CN.md +1 -1
- package/bin/mocode-agent-host.js +1 -1
- package/dist/agent/core.js +24 -5
- package/dist/agent/index.js +2 -0
- package/dist/agent/mode.js +9 -10
- package/dist/agent/spawn.js +9 -9
- package/dist/agent/work-discipline.js +19 -26
- package/dist/config/index.js +117 -226
- package/dist/context/artifacts.js +2 -2
- package/dist/context/classifier.js +3 -6
- package/dist/context/encoders/_util.js +2 -1
- package/dist/context/encoders/index.js +3 -4
- package/dist/context/lifecycle.js +3 -23
- package/dist/context/relevance.js +3 -22
- package/dist/host/protocol.js +19 -1
- package/dist/host/stdio.js +205 -0
- package/dist/i18n/index.js +0 -30
- package/dist/memory/index.js +3 -50
- package/dist/repl/index.js +18 -278
- package/dist/sandbox/policy.js +6 -4
- package/dist/session/notes-plan.js +41 -0
- package/dist/skills/builtin-skills.js +56 -0
- package/dist/skills/discover.js +7 -0
- package/dist/skills/index.js +23 -4
- package/dist/tools/builtins/glob.js +1 -1
- package/dist/tools/builtins/grep.js +1 -1
- package/dist/tools/builtins/index.js +0 -14
- package/dist/tools/builtins/read-file.js +1 -1
- package/dist/tools/constants.js +2 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -72,7 +72,7 @@ MoCode isn't a chat box with a coat of paint — it's an agent that actually get
|
|
|
72
72
|
- **Plan / Auto dual mode** — In `plan` mode the agent is read-only (reads code, queries indexes, searches — never writes to disk, runs commands, or spawns sub-agents) and produces a plan; `auto` mode unlocks the full toolset. The agent can switch between the two on its own — scope out an unfamiliar codebase first, then start making changes.
|
|
73
73
|
- **Automatic context compression** — As the context window fills up, a three-tier compression kicks in (trim individual results → compact older tool results in place → summarize older turns), so long sessions never overflow. `/context` shows live token usage; `/compact` triggers manual compression (optionally with a focus hint to preserve what matters).
|
|
74
74
|
- **Cross-session long-term memory** — The agent can save project architecture, conventions, and lessons learned as long-term memory, auto-loaded in future sessions. A background process periodically reflects on conversations to mine things worth remembering. Memories can be created, searched, updated, and forgotten, with recall-based decay.
|
|
75
|
-
- **Project context (
|
|
75
|
+
- **Project context (`MOCODE.md`)** — A single project-level memory file at `MOCODE.md` captures both static facts (project description, commands, module list, directory tree) and human/AI-written insights (conventions, architectural decisions, pitfalls). Generate it once with `/init`, then keep it up to date by hand or by asking the agent to refresh it. Loaded automatically into the system prompt on every turn.
|
|
76
76
|
- **Session notepad (notes.md)** — For complex multi-step tasks (≥3 file changes / ≥5 tool calls), the agent maintains a working notepad at `.mocode/sessions/<sessionId>/notes.md` (file-based, survives context compression). It can record intermediate findings, design decisions, open questions, and structured plans. A live progress chip in the TUI status bar shows `plan: [title] (3/7) ▸ [current step]` when a `## Plan:` section is present. The agent manages the file directly with write_file/edit_file/read_file.
|
|
77
77
|
- **Interruptible and reversible** — Ctrl+C interrupts the current turn at any time (kills child processes recursively, rolls history back to before the turn started, leaves no half-finished tool calls). `/rollback` restores file changes from per-turn snapshots, with a per-file keep/undo choice — no git dependency required.
|
|
78
78
|
- **Sandbox protection** — File reads/writes go through a sandbox that blocks out-of-bounds paths (`../../`, absolute paths outside the root, symlink escapes, etc.), so the agent never touches files outside your working directory.
|
|
@@ -89,7 +89,7 @@ MoCode isn't a chat box with a coat of paint — it's an agent that actually get
|
|
|
89
89
|
## Documentation
|
|
90
90
|
|
|
91
91
|
- [中文使用指南](./docs/usage.md) — 菜单式快速上手、命令速查、模式、会话、项目上下文与排障。
|
|
92
|
-
- [Project context](./docs/
|
|
92
|
+
- [Project context](./docs/usage.md#项目上下文) — `MOCODE.md` and Skills.
|
|
93
93
|
|
|
94
94
|
## Installation
|
|
95
95
|
|
|
@@ -235,8 +235,6 @@ The five `memory_*` tools are gated on `MEMORY_ENABLED=true` at startup; toggle
|
|
|
235
235
|
| `/pet` | Toggle the optional desktop pet (floating window mirroring agent state) |
|
|
236
236
|
| `/pet skin` | Pick a pet skin (↑↓ · Enter) |
|
|
237
237
|
| `/pet quit` | Fully shut down the pet process (not just disconnect) |
|
|
238
|
-
| `/snapshot_refresh` | Refresh project snapshot (re-scan files + regenerate LLM summary) |
|
|
239
|
-
| `/snapshot` | Toggle project snapshot on/off |
|
|
240
238
|
|
|
241
239
|
Type `/` to trigger the dropdown menu, keep typing to filter; Esc to cancel.
|
|
242
240
|
|
|
@@ -264,21 +262,6 @@ MoCode automatically scans the following directories for skills (each skill is a
|
|
|
264
262
|
|
|
265
263
|
A skill's `description` is injected into the system prompt (progressive disclosure, tier 1); the model calls `use_skill` to load the full body (tier 2) only when the task is relevant. Use `/skills` to see discovered skills.
|
|
266
264
|
|
|
267
|
-
## Project Context (Snapshot + Skill)
|
|
268
|
-
|
|
269
|
-
MoCode uses two complementary systems to help the agent understand your project:
|
|
270
|
-
|
|
271
|
-
- **Project Snapshot** (automatic + LLM-enhanced, enabled by default): Scans your project files and generates a structured summary including project description, tech stack, key commands, module responsibilities, and directory tree. Stored in `.mocode/snapshot.json` and reused across sessions. Use `/snapshot` to toggle it and `/snapshot_refresh` after major changes.
|
|
272
|
-
- **Project Skill** (manual + AI-assisted, disabled by default): A knowledge base for design decisions, architectural patterns, pitfalls, conventions, and workflow notes. Enable it with `/project_skill on` (or `MOCODE_PROJECT_SKILL=true`), generate an initial draft with `/project_skill init`, then refine `.mocode/project-skill.md`. The agent can update it through `project_skill_update` during conversations.
|
|
273
|
-
|
|
274
|
-
**Complementary principle**: Snapshot provides *what/where* (facts: files, structure, commands), Skill provides *why/how* (insights: decisions, behaviors, gotchas). No duplication, ~46% token savings compared to the previous approach.
|
|
275
|
-
|
|
276
|
-
Control via environment variables:
|
|
277
|
-
- `MOCODE_PROJECT_SNAPSHOT=false` — disable snapshot
|
|
278
|
-
- `MOCODE_PROJECT_SKILL=true` — enable Project Skill
|
|
279
|
-
|
|
280
|
-
See [docs/USAGE_SNAPSHOT_SKILL.md](./docs/USAGE_SNAPSHOT_SKILL.md) for detailed usage.
|
|
281
|
-
|
|
282
265
|
## Working discipline (Build-and-Self-Verify)
|
|
283
266
|
|
|
284
267
|
Every coding task runs through four sequential phases. Skipping or merging them is a failure mode — the system prompt injects this discipline on every turn (see `src/agent/work-discipline.ts`):
|
package/README.zh-CN.md
CHANGED
package/bin/mocode-agent-host.js
CHANGED
package/dist/agent/core.js
CHANGED
|
@@ -165,7 +165,7 @@ function readDiffContext(tc, parsed) {
|
|
|
165
165
|
* - pruner 在每个 runAgentCore 实例化一次(本闭包持有),会话级状态。
|
|
166
166
|
* - 开关关闭时 pruner 不创建(零开销、零行为变化)。
|
|
167
167
|
* 出口再经 Lifecycle Engine 做引用追踪:LIVE→REFERENCED→OBSOLETE→STUB 四态。
|
|
168
|
-
* - lifecycle 也在每个 runAgentCore 实例化一次,登记 grep/glob/
|
|
168
|
+
* - lifecycle 也在每个 runAgentCore 实例化一次,登记 grep/glob/web_search/web_fetch 等 producer
|
|
169
169
|
* 与 read/edit/write 的 consumer 关系;孤立+老化自动 STUB(观察类工具永不到 STUB)。
|
|
170
170
|
* - 开关关闭时 lifecycle=null 完全跳过。 */
|
|
171
171
|
/** RETRY-01: 把 thrash hint + 反思指针一次性拼到 output 尾部。
|
|
@@ -250,7 +250,8 @@ export async function runAgentCore(opts) {
|
|
|
250
250
|
? null
|
|
251
251
|
: (opts.preCompletionChecklist ?? _checklistMiddleware.handler);
|
|
252
252
|
const maxSteps = opts.maxSteps ?? config.maxSteps;
|
|
253
|
-
// 中断还原:
|
|
253
|
+
// 中断还原:repl 的 /plan / /auto / Shift+Tab 等用户面触发 setAgentMode 中途切了模式,
|
|
254
|
+
// abort 时连同模式一起还原回轮首。模型不再持有 switch_mode 工具,无法自切。
|
|
254
255
|
const savedMode = getAgentMode();
|
|
255
256
|
// 本轮计时:从入口到完毕(正常 return / 达上限),供 finally 打 ✻ Worked for 摘要行。
|
|
256
257
|
const t0 = Date.now();
|
|
@@ -318,7 +319,7 @@ export async function runAgentCore(opts) {
|
|
|
318
319
|
// 相关性裁剪 pruner:每个 runAgentCore 实例一个,纯静态、不调 LLM、自动判定 read_file 失效。
|
|
319
320
|
// 开关关闭时为 null,所有 pushToolResult 调用走无 pruner 路径(零行为变化)。
|
|
320
321
|
const relprune = config.contextRelprune ? createRelevancePruner() : null;
|
|
321
|
-
// 观察者生命周期引擎:每个 runAgentCore 实例一个,纯静态、自动维护 grep/glob/
|
|
322
|
+
// 观察者生命周期引擎:每个 runAgentCore 实例一个,纯静态、自动维护 grep/glob/web_search/web_fetch 等
|
|
322
323
|
// producer 与 read/edit/write 的 consumer 引用关系;孤立+老化的非观察类工具自动 STUB。
|
|
323
324
|
// 开关关闭时为 null,所有 pushToolResult / mutation 调用走无 lifecycle 路径(零行为变化)。
|
|
324
325
|
// 引擎需要从已有会话 history 恢复观察结果的年龄和 path 索引;不能只追踪本次
|
|
@@ -451,8 +452,26 @@ export async function runAgentCore(opts) {
|
|
|
451
452
|
const modelStartedAt = Date.now();
|
|
452
453
|
const provider = safeProviderId(requestBaseURL);
|
|
453
454
|
emitTrace('model_start', { model: requestModel, provider });
|
|
455
|
+
const dynamicSystemSuffix = [
|
|
456
|
+
opts.dynamicSystemSuffix?.().trim() ?? '',
|
|
457
|
+
historyRebuilt
|
|
458
|
+
? '## Post-compaction recovery\nContext was compacted before this request. Re-establish the current objective and unresolved work from retained evidence or the session note, avoid repeating completed investigation, and re-read exact file context before any dependent edit.'
|
|
459
|
+
: '',
|
|
460
|
+
].filter(Boolean).join('\n\n');
|
|
461
|
+
const systemMessage = history[0];
|
|
462
|
+
const requestHistory = dynamicSystemSuffix
|
|
463
|
+
&& systemMessage?.role === 'system'
|
|
464
|
+
&& typeof systemMessage.content === 'string'
|
|
465
|
+
? [
|
|
466
|
+
{
|
|
467
|
+
...systemMessage,
|
|
468
|
+
content: `${systemMessage.content}\n\n${dynamicSystemSuffix}`,
|
|
469
|
+
},
|
|
470
|
+
...history.slice(1),
|
|
471
|
+
]
|
|
472
|
+
: history;
|
|
454
473
|
try {
|
|
455
|
-
result = await chat(
|
|
474
|
+
result = await chat(requestHistory, {
|
|
456
475
|
onText,
|
|
457
476
|
onToolCall,
|
|
458
477
|
onRetry: (retry) => emitTrace('model_retry', {
|
|
@@ -513,7 +532,7 @@ export async function runAgentCore(opts) {
|
|
|
513
532
|
// 用本次实际发送的 tools 计算分母,再以 EWMA 更新 provider/model/tool-set 校准。
|
|
514
533
|
// 只持久化比例与样本数;无 usage 或短 prompt 时保持既有值。
|
|
515
534
|
if (result.usage?.promptTokens && result.usage.promptTokens > 100) {
|
|
516
|
-
const estimated = estimatePromptTokens(
|
|
535
|
+
const estimated = estimatePromptTokens(requestHistory, activeTools);
|
|
517
536
|
const updated = updateTokenCalibration(requestBaseURL, requestModel, activeTools, estimated, result.usage.promptTokens);
|
|
518
537
|
runtimeContextState.correction = updated.correction;
|
|
519
538
|
runtimeContextState.calibrationSamples = updated.samples;
|
package/dist/agent/index.js
CHANGED
|
@@ -15,6 +15,7 @@ import { createPetHooks } from '../pet/state.js';
|
|
|
15
15
|
import { t } from '../i18n/index.js';
|
|
16
16
|
import { isToolErrorOutput } from '../tools/result.js';
|
|
17
17
|
import { appendCurrentSessionTraceEvent } from '../session/index.js';
|
|
18
|
+
import { buildActiveNotesPlanReminder } from '../session/notes-plan.js';
|
|
18
19
|
/** 当前 turn 的 batch id(runAgent 内闭包变量;一条 turn 一轮 tool batch 结束即清空)。 */
|
|
19
20
|
let currentBatchId = null;
|
|
20
21
|
let turnFileChanges = [];
|
|
@@ -280,6 +281,7 @@ onContextUpdate) {
|
|
|
280
281
|
userInput,
|
|
281
282
|
signal,
|
|
282
283
|
onContextUpdate,
|
|
284
|
+
dynamicSystemSuffix: buildActiveNotesPlanReminder,
|
|
283
285
|
hooks: combinedHooks,
|
|
284
286
|
autoValidate: config.autoValidate,
|
|
285
287
|
onTraceEvent: appendCurrentSessionTraceEvent,
|
package/dist/agent/mode.js
CHANGED
|
@@ -2,19 +2,18 @@
|
|
|
2
2
|
* agent 模式的共享状态(零依赖纯叶子)。
|
|
3
3
|
*
|
|
4
4
|
* 把 `agentMode` 从 repl 的模块变量提到这里,让三方都能用、且不破坏依赖单向:
|
|
5
|
-
* - `
|
|
5
|
+
* - `repl/index.ts` 读写它 + 注册 onModeChange 监听器(做 applyMode 重写 history[0] +
|
|
6
|
+
* refreshStatusBase 刷状态行 modeTag),并通过 /plan / /auto / Shift+Tab(c cycleMode) 触发切换。
|
|
6
7
|
* - `agent/index.ts` 每步读它(getAgentMode)——决定 chat() 用全量 chatTools 还是 planChatTools 只读子集,
|
|
7
|
-
* 以及串行分支的 plan 防御 backstop
|
|
8
|
-
* -
|
|
9
|
-
* 刷状态行 modeTag)。
|
|
8
|
+
* 以及串行分支的 plan 防御 backstop。这样切换模式后,下一次 chat() 立即看到新工具集。
|
|
9
|
+
* - 模型不再持有 switch_mode 工具(已砍):模式切换只能由用户面触发。
|
|
10
10
|
*
|
|
11
|
-
* 依赖方向无环:本模块不 import
|
|
12
|
-
* → agent/mode` 链终点是本叶子,不回到 agent/index。`tools → agent/mode` 与既有 `tools → ui`(ask-human)、
|
|
13
|
-
* `tools → rollback`(registry)同性质——都是引叶子。
|
|
11
|
+
* 依赖方向无环:本模块不 import 任何业务模块。
|
|
14
12
|
*
|
|
15
|
-
* listener 同步触发:setAgentMode 在变更模式后同步调 listener(无 async)。
|
|
16
|
-
*
|
|
17
|
-
*
|
|
13
|
+
* listener 同步触发:setAgentMode 在变更模式后同步调 listener(无 async)。repl 的
|
|
14
|
+
* cycleMode / /plan / /auto 在 executeTool 路径之外调 setAgentMode → listener 同步
|
|
15
|
+
* applyMode(重写 history[0])+ refreshStatusBase;切换后下一步 chat() 读到新模式 +
|
|
16
|
+
* 新系统提示,一致。
|
|
18
17
|
*/
|
|
19
18
|
let currentMode = 'auto';
|
|
20
19
|
let listener = null;
|
package/dist/agent/spawn.js
CHANGED
|
@@ -20,18 +20,18 @@ import { summarizeToolCall, summarizeToolResult, truncateDisplay } from '../ui/r
|
|
|
20
20
|
import { createContextState } from '../session/compact.js';
|
|
21
21
|
import { inOverlay, mergeSubAgentChangeSet } from '../agents/coordinator.js';
|
|
22
22
|
/** 子 agent 系统提示后缀:角色与约束。 */
|
|
23
|
-
const SUBAGENT_SUFFIX = `
|
|
23
|
+
const SUBAGENT_SUFFIX = `
|
|
24
24
|
|
|
25
25
|
## ⛯ SUB-AGENT MODE (you are a sub-agent)
|
|
26
26
|
You are a sub-agent spawned by the main agent to handle an isolated sub-task. You have your own conversation history (independent of the main thread).
|
|
27
|
-
- Focus solely on the assigned sub-task. Do NOT attempt to call the "sub-agent" tool (no recursive spawning).
|
|
27
|
+
- Focus solely on the assigned sub-task. Do NOT attempt to call the "sub-agent" tool (no recursive spawning).
|
|
28
28
|
- Use the tools available to you to complete the sub-task.
|
|
29
29
|
- When done, your final text reply will be returned to the main agent as a summary — make it concise and actionable: what you did, key findings, files changed, and any issues. The main agent will decide the next step based on your summary.`;
|
|
30
|
-
const SUBAGENT_ROLE = `## Sub-agent execution
|
|
31
|
-
You are executing one delegated sub-task with the same engineering standards and capabilities as mocode.
|
|
32
|
-
- Treat Task context as authoritative facts already established by the main agent; do not rediscover them without evidence they are stale.
|
|
33
|
-
- Focus on the delegated scope, but continue until it is genuinely complete. Do not stop to save tokens.
|
|
34
|
-
- Do not recursively call sub-agent. A write task runs in an isolated overlay; the coordinator merges and performs final unified verification.
|
|
30
|
+
const SUBAGENT_ROLE = `## Sub-agent execution
|
|
31
|
+
You are executing one delegated sub-task with the same engineering standards and capabilities as mocode.
|
|
32
|
+
- Treat Task context as authoritative facts already established by the main agent; do not rediscover them without evidence they are stale.
|
|
33
|
+
- Focus on the delegated scope, but continue until it is genuinely complete. Do not stop to save tokens.
|
|
34
|
+
- Do not recursively call sub-agent. A write task runs in an isolated overlay; the coordinator merges and performs final unified verification.
|
|
35
35
|
- Return concise findings, changes, verification evidence, and blockers to the coordinator.`;
|
|
36
36
|
/**
|
|
37
37
|
* 派生一个子 agent 执行独立子任务。
|
|
@@ -66,7 +66,7 @@ export async function spawnAgent(opts) {
|
|
|
66
66
|
let toolsOverride;
|
|
67
67
|
const mode = opts.mode ?? 'read';
|
|
68
68
|
const requested = opts.tools?.length ? new Set(opts.tools) : null;
|
|
69
|
-
const readOnly = new Set(['read_file', 'glob', 'grep', '
|
|
69
|
+
const readOnly = new Set(['read_file', 'glob', 'grep', 'web_search', 'web_fetch', 'use_skill', 'memory_search', 'memory_list']);
|
|
70
70
|
toolsOverride = chatTools.filter((tool) => tool.function.name !== 'sub-agent' &&
|
|
71
71
|
(!requested || requested.has(tool.function.name)) &&
|
|
72
72
|
(mode === 'write' || readOnly.has(tool.function.name)));
|
|
@@ -139,7 +139,7 @@ export async function spawnAgent(opts) {
|
|
|
139
139
|
onToolOutcome: (tool, args) => {
|
|
140
140
|
if (tool === 'read_file' && typeof args.path === 'string')
|
|
141
141
|
readSet.add(args.path);
|
|
142
|
-
else if (['glob', 'grep'
|
|
142
|
+
else if (['glob', 'grep'].includes(tool))
|
|
143
143
|
readSet.add('workspace');
|
|
144
144
|
},
|
|
145
145
|
});
|
|
@@ -31,33 +31,30 @@ export function inferModelFamily(model) {
|
|
|
31
31
|
}
|
|
32
32
|
/**
|
|
33
33
|
* 4 阶段核心纪律(英文)。4 个 model family 共用此文本,只在首句与标题
|
|
34
|
-
*
|
|
34
|
+
* 标签上做轻量变体。保持短小,详细的完成检查由动态 checklist 按需注入。
|
|
35
35
|
*/
|
|
36
36
|
const CORE_SECTION = `## Working discipline — coding tasks (Build-and-Self-Verify)
|
|
37
37
|
|
|
38
|
-
Treat "verification" as a first-class part of the task, not an afterthought.
|
|
38
|
+
Treat "verification" as a first-class part of the task, not an afterthought. Use the smallest evidence-driven loop below.
|
|
39
39
|
|
|
40
40
|
### Phase 1 — Plan & Discover
|
|
41
|
-
-
|
|
42
|
-
-
|
|
43
|
-
- If the spec is ambiguous, surface the ambiguity to the user via \`ask_human\` before implementing — do not guess on irreversible choices (deletions, public API changes, schema/permission boundaries).
|
|
41
|
+
- State the goal and a concrete acceptance signal, then inspect the relevant code before changing it.
|
|
42
|
+
- Ask only when an unresolved choice is high-impact or user-owned; otherwise follow repository evidence and proceed.
|
|
44
43
|
|
|
45
44
|
### Phase 2 — Build
|
|
46
|
-
- Make the smallest change
|
|
47
|
-
-
|
|
48
|
-
-
|
|
45
|
+
- Make the smallest coherent change; avoid unrelated refactors.
|
|
46
|
+
- Add or update a focused test when behavior changes and the project has an applicable test suite.
|
|
47
|
+
- Re-read only when a dependent edit needs fresh exact content or state may be stale.
|
|
49
48
|
|
|
50
49
|
### Phase 3 — Verify
|
|
51
|
-
- Run
|
|
52
|
-
- Compare
|
|
53
|
-
- If the project has no test infra you can use, build the smallest possible reproducer (a script, a focused command) that exercises the change. "I read the code and it looks correct" is not verification.
|
|
50
|
+
- Run the smallest executable check that proves the requested behavior, then read its complete result.
|
|
51
|
+
- Compare evidence with the user's request, not merely with the diff.
|
|
54
52
|
|
|
55
53
|
### Phase 4 — Fix
|
|
56
|
-
-
|
|
57
|
-
- After
|
|
58
|
-
- Cap blind retries: after three identical failed attempts on the same tool with the same arguments, change the approach (different tool, different invariant, or \`ask_human\`) instead of retrying.
|
|
54
|
+
- Diagnose the root cause, make a focused correction, and rerun the relevant check.
|
|
55
|
+
- After three identical failures, change the approach instead of repeating the same call.
|
|
59
56
|
|
|
60
|
-
**Hard rule (non-negotiable):** "I read the code and it looks right" is not a completion signal.
|
|
57
|
+
**Hard rule (non-negotiable):** "I read the code and it looks right" is not a completion signal. Report the verification performed, or state clearly why it could not be run.`;
|
|
61
58
|
/**
|
|
62
59
|
* 把核心段适配到指定 model family:只改首行(语序 / 强动词)与段标题
|
|
63
60
|
* 末尾的 [model: X] 标签。Phase 内容保持原样,4 份共享同一份结构化文本。
|
|
@@ -67,21 +64,17 @@ function adapt(model, opener) {
|
|
|
67
64
|
.replace('## Working discipline — coding tasks (Build-and-Self-Verify)', `## Working discipline — coding tasks (Build-and-Self-Verify) [model: ${model}]`)
|
|
68
65
|
.replace('Treat "verification" as a first-class part of the task, not an afterthought.', opener);
|
|
69
66
|
}
|
|
70
|
-
/** ASK-01:
|
|
71
|
-
* 边界情形应当优先调 `ask_human`,而不是猜测。语种统一英文(与 PROMPT-01
|
|
72
|
-
* 保持一致,避免多语种漂移);5 个固定条目,与 checklist 第 6 项耦合。
|
|
73
|
-
*/
|
|
67
|
+
/** ASK-01: only user-owned, high-impact choices should interrupt autonomous execution. */
|
|
74
68
|
const ASK_WHITELIST_SECTION = `## When to ask instead of guess
|
|
75
69
|
|
|
76
|
-
|
|
70
|
+
Call \`ask_human\` before coding only when repository evidence cannot resolve a user-owned, high-impact choice:
|
|
71
|
+
1. irreversible deletion, migration, security, permission, or external side effect;
|
|
72
|
+
2. public API compatibility (keep, deprecate, rename, or remove);
|
|
73
|
+
3. multiple reasonable options that materially change product behavior.
|
|
77
74
|
|
|
78
|
-
|
|
79
|
-
2. **Naming conventions** — the project has no obvious style for this artifact (e.g. new file in a folder with no precedent); naming is cheap to fix and expensive to mass-rename later.
|
|
80
|
-
3. **Keep or remove old API** — the change deprecates, renames, or removes a function/type; the user must decide.
|
|
81
|
-
4. **Test expectations** — the spec says "should work" or "should handle" but does not pin down the input/output contract; ask for a concrete example or assertion.
|
|
82
|
-
5. **Implicit success criteria** — the user described intent but not the verification signal (which command, which output, which line of the spec). Without this, you cannot run Phase 3 honestly.
|
|
75
|
+
For naming, implementation detail, and verification commands, follow repository precedent and choose the safest reversible default. Disclose any consequential assumption.
|
|
83
76
|
|
|
84
|
-
Budget: at most 2 \`ask_human\` calls per turn.
|
|
77
|
+
Budget: at most 2 \`ask_human\` calls per turn. Beyond that, use the safest reversible default and disclose it in the final reply.`;
|
|
85
78
|
/**
|
|
86
79
|
* 拼出纪律段 + ASK-01 卡点白名单。返回完整段(两段用 \`\\n\\n\` 隔开);
|
|
87
80
|
* 工厂之前只返回纪律段,ASK-01 落地后变成纪律 + 白名单两段;
|