dominds 1.20.1 → 1.20.2
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/dist/llm/defaults.yaml +9 -9
- package/dist/llm/gen/failure-classifier.js +22 -1
- package/dist/persistence.js +1 -1
- package/dist/tools/ctrl.js +4 -3
- package/dist/tools/prompts/control/en/principles.md +7 -1
- package/dist/tools/prompts/control/en/scenarios.md +8 -6
- package/dist/tools/prompts/control/en/tools.md +10 -3
- package/dist/tools/prompts/control/zh/principles.md +7 -1
- package/dist/tools/prompts/control/zh/scenarios.md +6 -6
- package/dist/tools/prompts/control/zh/tools.md +5 -3
- package/dist/utils/task-package.js +21 -7
- package/package.json +1 -1
package/dist/llm/defaults.yaml
CHANGED
|
@@ -102,13 +102,13 @@ providers:
|
|
|
102
102
|
models:
|
|
103
103
|
gpt-5.5:
|
|
104
104
|
name: GPT-5.5
|
|
105
|
-
optimal_max_tokens:
|
|
105
|
+
optimal_max_tokens: 200000
|
|
106
106
|
# Caution remediation reinjection cadence in generation turns (default: 10).
|
|
107
107
|
caution_remediation_cadence_generations: 10
|
|
108
|
-
context_length:
|
|
108
|
+
context_length: 272000
|
|
109
109
|
input_length: 272000
|
|
110
|
-
output_length:
|
|
111
|
-
context_window: '
|
|
110
|
+
output_length: 32768
|
|
111
|
+
context_window: '272K'
|
|
112
112
|
gpt-5.4:
|
|
113
113
|
name: GPT-5.4
|
|
114
114
|
optimal_max_tokens: 200000
|
|
@@ -871,13 +871,13 @@ providers:
|
|
|
871
871
|
models:
|
|
872
872
|
gpt-5.5:
|
|
873
873
|
name: GPT-5.5
|
|
874
|
-
optimal_max_tokens:
|
|
874
|
+
optimal_max_tokens: 200000
|
|
875
875
|
# Caution remediation reinjection cadence in generation turns (default: 10).
|
|
876
876
|
caution_remediation_cadence_generations: 10
|
|
877
|
-
context_length:
|
|
878
|
-
input_length:
|
|
879
|
-
output_length:
|
|
880
|
-
context_window: '
|
|
877
|
+
context_length: 272000
|
|
878
|
+
input_length: 272000
|
|
879
|
+
output_length: 32768
|
|
880
|
+
context_window: '272K'
|
|
881
881
|
gpt-5.5-pro:
|
|
882
882
|
name: GPT-5.5 Pro
|
|
883
883
|
optimal_max_tokens: 600000
|
|
@@ -234,6 +234,25 @@ function isOpenAiLikeRejectedFailure(error) {
|
|
|
234
234
|
const status = readErrorStatus(error);
|
|
235
235
|
return isHighConfidenceRejectedStatus(status);
|
|
236
236
|
}
|
|
237
|
+
function isOpenAiLikeContextWindowRejectedFailure(args) {
|
|
238
|
+
if (args.lowerCode === 'context_length_exceeded') {
|
|
239
|
+
return true;
|
|
240
|
+
}
|
|
241
|
+
if (args.lowerMessage.includes('context window') &&
|
|
242
|
+
(args.lowerMessage.includes('exceeds') || args.lowerMessage.includes('exceeded'))) {
|
|
243
|
+
return true;
|
|
244
|
+
}
|
|
245
|
+
if (args.lowerMessage.includes('context limit exceeded')) {
|
|
246
|
+
return true;
|
|
247
|
+
}
|
|
248
|
+
if (args.lowerMessage.includes('maximum context length')) {
|
|
249
|
+
return true;
|
|
250
|
+
}
|
|
251
|
+
if (args.lowerMessage.includes('context_length_exceeded')) {
|
|
252
|
+
return true;
|
|
253
|
+
}
|
|
254
|
+
return args.lowerMessage.includes('too many tokens') && args.lowerMessage.includes('context');
|
|
255
|
+
}
|
|
237
256
|
function isOpenAiLikeRateLimitFailure(error) {
|
|
238
257
|
const lowerMessage = buildFailureMessage(error).toLowerCase();
|
|
239
258
|
const status = readErrorStatus(error);
|
|
@@ -267,7 +286,9 @@ function classifyOpenAiLikeFailure(error) {
|
|
|
267
286
|
const lowerMessage = message.toLowerCase();
|
|
268
287
|
const status = readErrorStatus(error);
|
|
269
288
|
const code = readErrorCode(error);
|
|
270
|
-
|
|
289
|
+
const lowerCode = typeof code === 'string' ? code.trim().toLowerCase() : undefined;
|
|
290
|
+
if (isOpenAiLikeRejectedFailure(error) ||
|
|
291
|
+
isOpenAiLikeContextWindowRejectedFailure({ lowerMessage, lowerCode })) {
|
|
271
292
|
return {
|
|
272
293
|
kind: 'rejected',
|
|
273
294
|
message,
|
package/dist/persistence.js
CHANGED
|
@@ -4709,7 +4709,7 @@ class DialogPersistence {
|
|
|
4709
4709
|
genseq,
|
|
4710
4710
|
content,
|
|
4711
4711
|
};
|
|
4712
|
-
await this.appendEvent(dialog.id, course, ev, dialog.status);
|
|
4712
|
+
await this.appendEvent(dialog.id, course, attachRootGenerationRef(dialog, ev), dialog.status);
|
|
4713
4713
|
}
|
|
4714
4714
|
/**
|
|
4715
4715
|
* Capture the current byte offset of a course JSONL file.
|
package/dist/tools/ctrl.js
CHANGED
|
@@ -371,7 +371,7 @@ function getCtrlMessages(language) {
|
|
|
371
371
|
tooManyArgsChangeMind: '参数格式不对。用法:change_mind({ selector: string, category?: string, content: string })',
|
|
372
372
|
invalidFormatMindMore: '参数格式不对。用法:mind_more({ items: string[], sep?: string, selector?: string, category?: string })(selector 默认 progress)',
|
|
373
373
|
mindMoreItemsRequired: '需要提供要追加的条目(items),且每一项都必须是非空字符串。\n' +
|
|
374
|
-
'示例:mind_more({"items":["-
|
|
374
|
+
'示例:mind_more({"items":["- 下一步:复核验证结果(详见 <文档路径>#<章节>)","- 阻塞:等待 API 验收口径确认"]})',
|
|
375
375
|
invalidFormatRecallTaskdoc: '参数格式不对。用法:recall_taskdoc({ category: string, selector: string })',
|
|
376
376
|
taskDocContentRequired: '需要提供差遣牒内容(content)。\n' +
|
|
377
377
|
'示例:\n' +
|
|
@@ -408,7 +408,7 @@ function getCtrlMessages(language) {
|
|
|
408
408
|
tooManyArgsChangeMind: 'Error: Invalid args. Use: change_mind({ selector: string, category?: string, content: string })',
|
|
409
409
|
invalidFormatMindMore: 'Error: Invalid args. Use: mind_more({ items: string[], sep?: string, selector?: string, category?: string }) (selector defaults to progress).',
|
|
410
410
|
mindMoreItemsRequired: 'Error: items are required, and every item must be a non-empty string.\n' +
|
|
411
|
-
'Example: mind_more({"items":["- Next: review verification results","- Blocker:
|
|
411
|
+
'Example: mind_more({"items":["- Next: review verification results (details: <doc-path>#<section>)","- Blocker: API acceptance criteria pending"]})',
|
|
412
412
|
invalidFormatRecallTaskdoc: 'Error: Invalid args. Use: recall_taskdoc({ category: string, selector: string })',
|
|
413
413
|
taskDocContentRequired: 'Error: Taskdoc content is required (content).\n' +
|
|
414
414
|
'Copy/paste example:\n' +
|
|
@@ -1016,6 +1016,7 @@ exports.recallTaskdocTool = {
|
|
|
1016
1016
|
? `\n\n⚠️ 已截断:内容过大(${bytes} bytes),仅回显前 ${maxSize} bytes。`
|
|
1017
1017
|
: `\n\n⚠️ Truncated: content is too large (${bytes} bytes); showing first ${maxSize} bytes.`
|
|
1018
1018
|
: '';
|
|
1019
|
-
|
|
1019
|
+
const closingSeparatorPrefix = clipped.endsWith('\n') ? '' : '\n';
|
|
1020
|
+
return (0, tool_1.toolSuccess)(`**recall_taskdoc:** \`${relPath}\`\n\n---\n${clipped}${closingSeparatorPrefix}---${note}`);
|
|
1020
1021
|
},
|
|
1021
1022
|
};
|
|
@@ -77,6 +77,8 @@ Taskdoc is a **task contract** and the task's **team-shared source of current tr
|
|
|
77
77
|
- Does not reset dialog rounds
|
|
78
78
|
- Changes visible to all teammates
|
|
79
79
|
- When writing `progress`, assume teammates will skim it to synchronize on the current task truth rather than read your private process log
|
|
80
|
+
- Do not keep blindly calling `mind_more` until `progress` becomes a chronology; when the bulletin board starts accumulating duplicates, stale entries, or noisy history, use `change_mind` to condense it around facts that are still effective now
|
|
81
|
+
- Detailed investigations, long logs, full plans, acceptance records, and expanded rationale belong in formal rtws documentation; Taskdoc should keep only the key point, current conclusion, next step, and a location pointer such as path/section/command
|
|
80
82
|
|
|
81
83
|
## Tool Overview
|
|
82
84
|
|
|
@@ -129,8 +131,10 @@ Taskdoc is a **task contract** and the task's **team-shared source of current tr
|
|
|
129
131
|
- Keep concise: reminders are often 1-3 items; prefer `update_reminder` to compress/merge
|
|
130
132
|
- Separate carriers: information that must synchronize the team's current effective state, key decisions, next steps, or still-active blockers belongs in `progress`, the quasi-real-time task bulletin board; reminders keep local resume details
|
|
131
133
|
- Team-facing: keep `progress` scannable and centered on what is still effective now; do not let it degrade into a personal log, raw chronology, scratchpad, or stale history pile. Use `mind_more` for small additions and `change_mind` when cleanup/reordering/compression is needed
|
|
134
|
+
- Condense when needed: `mind_more` is not the default bookkeeping move. If one topic already has several phase notes, prefer `change_mind` to merge them into the current summary; put the detailed expansion in formal rtws documentation and keep a document pointer in Taskdoc
|
|
132
135
|
- Collapse before clearing: the Main Dialog first records undocumented discussion details the next course needs to know into the appropriate Taskdoc sections, then creates a structured continuation-package reminder; a Side Dialog must not maintain Taskdoc or draft Taskdoc update proposals, and should directly maintain sufficiently detailed continuation-package reminders. If the current course is already under system remediation, rough multi-reminder carry-over is acceptable but must be reconciled first in the new course
|
|
133
136
|
- Avoid raw-material dumps: do not paste long logs or large tool outputs into reminders
|
|
137
|
+
- Documentation layering: Taskdoc says “what the team should sync on / do next now”; formal rtws documentation carries “why, how, detailed evidence, and the full process”. When Taskdoc references formal rtws documentation, use a stable path/section name/relevant command instead of copying the full content
|
|
134
138
|
|
|
135
139
|
### 4. What Belongs in `progress`
|
|
136
140
|
|
|
@@ -139,16 +143,18 @@ Taskdoc is a **task contract** and the task's **team-shared source of current tr
|
|
|
139
143
|
- blockers that are confirmed and still active
|
|
140
144
|
- the next step the team should currently align on
|
|
141
145
|
- completed stage closures and remaining gaps
|
|
146
|
+
- a short summary of content already written to formal rtws documentation, plus a pointer to that document
|
|
142
147
|
- Poor fits for `progress`:
|
|
143
148
|
- “I just read file X”
|
|
144
149
|
- “I might try a small idea next”
|
|
145
150
|
- scratch notes only useful to the current speaker
|
|
146
151
|
- historical traces whose current validity is unclear
|
|
152
|
+
- detailed expansions, long logs, full plans, or acceptance-record text that belongs in formal rtws documentation
|
|
147
153
|
|
|
148
154
|
## Limitations and Notes
|
|
149
155
|
|
|
150
156
|
1. `dialog` reminders end with the dialog; `personal` reminders stay visible in all later dialogs you lead
|
|
151
|
-
2. Use `mind_more` for small Taskdoc additions; use `change_mind` for full-section replacement and merge existing content first
|
|
157
|
+
2. Use `mind_more` for small Taskdoc additions; use `change_mind` for full-section replacement and merge existing content first. Do not treat `mind_more` as a chronology tool; when cleanup, stale-entry removal, or same-topic consolidation is needed, use `change_mind`
|
|
152
158
|
3. `mind_more` / `change_mind` do not reset dialog rounds
|
|
153
159
|
4. A continuation-package reminder should keep only details still not covered by Taskdoc but easy to lose during resume; in the Main Dialog, undocumented discussion details from current dialog history that the next course needs to know should be written to the appropriate Taskdoc sections first; in a Side Dialog under caution/critical remediation, maintain sufficiently detailed continuation-package reminders only
|
|
154
160
|
5. Do not turn `personal` reminders into a long-term fact dump; move durable knowledge into `personal_memory`
|
|
@@ -117,21 +117,23 @@ replyTellaskBack({
|
|
|
117
117
|
|
|
118
118
|
### Scenario Description
|
|
119
119
|
|
|
120
|
-
Announce the current effective state, key decisions, next step, and still-active blockers to the whole team rather than writing a private chronology.
|
|
120
|
+
Announce the current effective state, key decisions, next step, and still-active blockers to the whole team rather than writing a private chronology. If details have been organized into formal rtws documentation, `progress` should keep only the summary and document pointer.
|
|
121
121
|
|
|
122
122
|
### Example
|
|
123
123
|
|
|
124
124
|
```typescript
|
|
125
125
|
// Small additions that are still effective now
|
|
126
126
|
mind_more({
|
|
127
|
-
items: [
|
|
127
|
+
items: [
|
|
128
|
+
'- Next: verify control / team_mgmt manuals and tests are aligned (details: <doc-path>#<section>)',
|
|
129
|
+
],
|
|
128
130
|
});
|
|
129
131
|
|
|
130
|
-
// Full-section replacement when cleanup, reordering, or compression is needed
|
|
132
|
+
// Full-section replacement when cleanup, reordering, same-topic consolidation, or chronology compression is needed
|
|
131
133
|
change_mind({
|
|
132
134
|
selector: 'progress',
|
|
133
135
|
content:
|
|
134
|
-
'## Progress\n\n### Current Effective State\n- The memory-carrier boundary cleanup is complete; next we strengthen the Taskdoc bulletin-board semantics
|
|
136
|
+
'## Progress\n\n### Current Effective State\n- The memory-carrier boundary cleanup is complete; next we strengthen the Taskdoc bulletin-board semantics; details: <doc-path>#<section>\n\n### Decisions In Effect\n- `personal_memory` is no longer treated as a short-term junk drawer\n- `team_memory` now carries only long-lived team conventions and invariants\n\n### Next Step\n- Add stronger `progress` bulletin-board guidance in control / team_mgmt manuals\n\n### Still-Active Blockers\n- None',
|
|
135
137
|
});
|
|
136
138
|
```
|
|
137
139
|
|
|
@@ -193,7 +195,7 @@ recall_taskdoc({
|
|
|
193
195
|
|
|
194
196
|
### Scenario Description
|
|
195
197
|
|
|
196
|
-
Maintain taskdoc integrity and consistency, and keep `progress` as a team-scannable current-truth snapshot.
|
|
198
|
+
Maintain taskdoc integrity and consistency, and keep `progress` as a team-scannable current-truth snapshot; put detailed expansion in formal rtws documentation and keep only the summary plus location pointer in Taskdoc.
|
|
197
199
|
|
|
198
200
|
### Example
|
|
199
201
|
|
|
@@ -202,6 +204,6 @@ Maintain taskdoc integrity and consistency, and keep `progress` as a team-scanna
|
|
|
202
204
|
change_mind({
|
|
203
205
|
selector: 'progress',
|
|
204
206
|
content:
|
|
205
|
-
'## Progress\n\n### Current Effective State\n- The boundary wording has been propagated into handbook sources and tests
|
|
207
|
+
'## Progress\n\n### Current Effective State\n- The boundary wording has been propagated into handbook sources and tests; details: <doc-path>#<section>\n\n### Decisions In Effect\n- role assets / personal_memory / team_memory / Taskdoc-progress / reminders now have separated responsibilities\n\n### Next Step\n- Re-verify control manual wording, Taskdoc display text, and boundary tests\n\n### Still-Active Blockers\n- None',
|
|
206
208
|
});
|
|
207
209
|
```
|
|
@@ -175,7 +175,10 @@ Append entries to a Taskdoc section; defaults to `progress`, reducing full-secti
|
|
|
175
175
|
|
|
176
176
|
```typescript
|
|
177
177
|
mind_more({
|
|
178
|
-
items: [
|
|
178
|
+
items: [
|
|
179
|
+
'- Next: review verification results (details: <doc-path>#<section>)',
|
|
180
|
+
'- Blocker: API acceptance criteria pending',
|
|
181
|
+
],
|
|
179
182
|
});
|
|
180
183
|
```
|
|
181
184
|
|
|
@@ -183,7 +186,9 @@ mind_more({
|
|
|
183
186
|
|
|
184
187
|
- Append-only: it does not deduplicate, rewrite, or compress old content
|
|
185
188
|
- Good for adding one or two still-effective states, decisions, next steps, or blockers to `progress`
|
|
189
|
+
- Not for appending every investigation step, long log, full plan, or acceptance record as a chronology; those details belong in formal rtws documentation, while Taskdoc keeps the summary and document pointer
|
|
186
190
|
- If stale entries must be removed, reordered, or compressed, use `change_mind` for a full-section replacement
|
|
191
|
+
- When one topic already has several phase notes, prefer `change_mind` to merge them into a concise current announcement instead of continuing to call `mind_more`
|
|
187
192
|
|
|
188
193
|
### 7. recall_taskdoc
|
|
189
194
|
|
|
@@ -257,7 +262,9 @@ update_reminder({
|
|
|
257
262
|
|
|
258
263
|
```typescript
|
|
259
264
|
mind_more({
|
|
260
|
-
items: [
|
|
265
|
+
items: [
|
|
266
|
+
'- Next: strengthen the bulletin-board semantics of Taskdoc `progress` (details: <doc-path>#<section>)',
|
|
267
|
+
],
|
|
261
268
|
});
|
|
262
269
|
```
|
|
263
270
|
|
|
@@ -267,7 +274,7 @@ mind_more({
|
|
|
267
274
|
change_mind({
|
|
268
275
|
selector: 'progress',
|
|
269
276
|
content:
|
|
270
|
-
'## Progress\n\n### Current Effective State\n- The handbook boundary split is now agreed: role assets / personal long-lived experience / Taskdoc-progress / reminders
|
|
277
|
+
'## Progress\n\n### Current Effective State\n- The handbook boundary split is now agreed: role assets / personal long-lived experience / Taskdoc-progress / reminders; details: <doc-path>#<section>\n\n### Decisions In Effect\n- `persona / knowhow / pitfalls` no longer absorb daily member experience\n- `personal_memory` is reserved for one member\\'s reusable long-lived experience\n\n### Next Step\n- Strengthen the bulletin-board semantics of Taskdoc `progress`\n\n### Still-Active Blockers\n- None',
|
|
271
278
|
});
|
|
272
279
|
```
|
|
273
280
|
|
|
@@ -77,6 +77,8 @@
|
|
|
77
77
|
- 不重置对话轮次
|
|
78
78
|
- 变更对所有队友可见
|
|
79
79
|
- 写入 `progress` 时,应默认假设全队成员会用它快速同步“当前任务真相”,而不是阅读你的个人过程记录
|
|
80
|
+
- 不要无脑连续使用 `mind_more` 把 `progress` 写成流水账;当公告牌开始堆积、重复或含过期信息时,用 `change_mind` 按当前仍有效的事实压缩整理
|
|
81
|
+
- 细节展开、调查过程、长日志、方案全文和验收记录应落进 rtws 正式文档;差遣牒只保留要点、当前结论、下一步,以及指向正式文档的路径/章节/命令等定位 pointer
|
|
80
82
|
|
|
81
83
|
## 工具概览
|
|
82
84
|
|
|
@@ -129,8 +131,10 @@
|
|
|
129
131
|
- 保持简洁:默认提醒项常见 1–3 条,优先 `update_reminder` 压缩/合并
|
|
130
132
|
- 区分载体:需要向全队同步的当前有效状态、关键决策、下一步与仍成立阻塞,写入 `progress` 这一准实时任务公告牌;提醒项只留个人/当前对话恢复所需细节
|
|
131
133
|
- 面向全队:`progress` 应保持可扫读、以“当前仍有效”为准,不要退化成个人日志、流水账、临时便签或历史残影堆积;少量新增用 `mind_more`,需要清旧/重排/压缩时用 `change_mind`
|
|
134
|
+
- 按需整理:`mind_more` 不是默认记账动作。若同一主题已有多条阶段性记录,优先用 `change_mind` 合并成当前摘要;把细节放进 rtws 正式文档,并在差遣牒里保留文档定位 pointer
|
|
132
135
|
- 换程前收束:主线对话先把尚未落实到文档、且下一程需要知会的讨论细节写入差遣牒合适章节,再整理结构化接续包提醒项;支线对话不要维护差遣牒,也不要整理差遣牒更新提案,直接维护足够详尽的接续包提醒项。若系统已把当前程切到吃紧/告急处置态,则先保留多条粗略提醒项过桥也可以;当前程只做落文档/保信息 + `clear_mind`(支线只做保信息 + `clear_mind`),系统真正开启新一程后第一步再收敛
|
|
133
136
|
- 拒绝原料堆积:不要把长日志/大段 tool output 直接塞进提醒项
|
|
137
|
+
- 文档分层:差遣牒写“现在应如何同步/推进”,正式文档写“为什么、怎么做、详细证据和完整过程”。差遣牒需要引用正式文档时,写稳定路径/章节名/相关命令,而不是复制整段内容
|
|
134
138
|
|
|
135
139
|
### 4. `progress` 内容取舍
|
|
136
140
|
|
|
@@ -139,16 +143,18 @@
|
|
|
139
143
|
- 当前已确认、仍成立的 blocker
|
|
140
144
|
- 当前全队应共识的下一步
|
|
141
145
|
- 当前阶段性闭环与尚未闭环的 gap
|
|
146
|
+
- 已落正式文档的关键内容摘要,以及定位该文档的 pointer
|
|
142
147
|
- 不适合写进 `progress`:
|
|
143
148
|
- “我刚刚看了什么文件”
|
|
144
149
|
- “我准备先试一个小想法”
|
|
145
150
|
- 只对当前说话者自己有用的临时便签
|
|
146
151
|
- 无法判断是否仍然有效的历史痕迹
|
|
152
|
+
- 可在 rtws 正式文档中承载的细节展开、长日志、完整方案或验收记录全文
|
|
147
153
|
|
|
148
154
|
## 限制与注意事项
|
|
149
155
|
|
|
150
156
|
1. `dialog` 提醒会随对话结束而结束;`personal` 提醒会在所有由你主理的后续对话里继续可见
|
|
151
|
-
2. 差遣牒少量新增可用 `mind_more` 追加;整段替换用 `change_mind
|
|
157
|
+
2. 差遣牒少量新增可用 `mind_more` 追加;整段替换用 `change_mind`,请确保合并已有内容。不要把 `mind_more` 当流水账工具;需要整理、去旧、合并同主题记录时直接 `change_mind`
|
|
152
158
|
3. `mind_more` / `change_mind` 不重置对话轮次
|
|
153
159
|
4. 接续包提醒项只保留差遣牒仍未覆盖、但恢复工作容易丢的细节;主线对话应先把当前对话历史中应由下一程知会的未落文档讨论细节写入差遣牒合适章节;支线对话在吃紧/告急时只维护足够详尽的接续包提醒项
|
|
154
160
|
5. 不要把 `personal` 提醒堆成长期事实仓库;耐久知识应迁到 `personal_memory`
|
|
@@ -116,21 +116,21 @@ replyTellaskBack({
|
|
|
116
116
|
|
|
117
117
|
### 场景描述
|
|
118
118
|
|
|
119
|
-
|
|
119
|
+
把当前有效状态、关键决策、下一步与仍成立阻塞公告给全队,而不是写个人流水账。若细节已整理到 rtws 正式文档,`progress` 只写摘要和文档定位 pointer。
|
|
120
120
|
|
|
121
121
|
### 示例
|
|
122
122
|
|
|
123
123
|
```typescript
|
|
124
124
|
// 少量新增当前仍有效的公告条目
|
|
125
125
|
mind_more({
|
|
126
|
-
items: ['- 下一步:复核 control / team_mgmt
|
|
126
|
+
items: ['- 下一步:复核 control / team_mgmt 手册与测试是否对齐(详见 <文档路径>#<章节>)'],
|
|
127
127
|
});
|
|
128
128
|
|
|
129
|
-
//
|
|
129
|
+
// 需要清理旧项、重排、同主题合并或压缩流水账时,整章替换
|
|
130
130
|
change_mind({
|
|
131
131
|
selector: 'progress',
|
|
132
132
|
content:
|
|
133
|
-
'## Progress\n\n### 当前有效状态\n- 已完成三类记忆载体边界收口,准备补 Taskdoc
|
|
133
|
+
'## Progress\n\n### 当前有效状态\n- 已完成三类记忆载体边界收口,准备补 Taskdoc 公告牌属性;细节见 <文档路径>#<章节>\n\n### 已生效决策\n- `personal_memory` 不再作为短期杂物柜\n- `team_memory` 只承接团队长期共识与不变量\n\n### 下一步\n- 在 control / team_mgmt 手册中补强 `progress` 的公告牌语义\n\n### 仍成立阻塞\n- 无',
|
|
134
134
|
});
|
|
135
135
|
```
|
|
136
136
|
|
|
@@ -192,7 +192,7 @@ recall_taskdoc({
|
|
|
192
192
|
|
|
193
193
|
### 场景描述
|
|
194
194
|
|
|
195
|
-
维护差遣牒的完整性和一致性,并确保 `progress`
|
|
195
|
+
维护差遣牒的完整性和一致性,并确保 `progress` 始终是可供全队扫读的当前真相快照;细节展开放入 rtws 正式文档,差遣牒只保留摘要和定位 pointer。
|
|
196
196
|
|
|
197
197
|
### 示例
|
|
198
198
|
|
|
@@ -201,6 +201,6 @@ recall_taskdoc({
|
|
|
201
201
|
change_mind({
|
|
202
202
|
selector: 'progress',
|
|
203
203
|
content:
|
|
204
|
-
'## Progress\n\n### 当前有效状态\n-
|
|
204
|
+
'## Progress\n\n### 当前有效状态\n- 边界口径已统一到手册源头与测试;细节见 <文档路径>#<章节>\n\n### 已生效决策\n- 角色级资产 / personal_memory / team_memory / Taskdoc-progress / reminders 的职责已经切开\n\n### 下一步\n- 复验 control 手册、Taskdoc 展示文案与边界测试\n\n### 仍成立阻塞\n- 无',
|
|
205
205
|
});
|
|
206
206
|
```
|
|
@@ -175,7 +175,7 @@ updated_at: <更新时间戳>
|
|
|
175
175
|
|
|
176
176
|
```typescript
|
|
177
177
|
mind_more({
|
|
178
|
-
items: ['-
|
|
178
|
+
items: ['- 下一步:复核验证结果(详见 <文档路径>#<章节>)', '- 阻塞:等待 API 验收口径确认'],
|
|
179
179
|
});
|
|
180
180
|
```
|
|
181
181
|
|
|
@@ -183,7 +183,9 @@ mind_more({
|
|
|
183
183
|
|
|
184
184
|
- 只追加,不会自动去重、改写或压缩旧内容
|
|
185
185
|
- 适合给 `progress` 补一两条当前仍有效的状态、决策、下一步或阻塞
|
|
186
|
+
- 不适合把每一步调查过程、长日志、完整方案或验收记录当流水账追加进去;这些细节应写入 rtws 正式文档,差遣牒只写摘要和文档定位 pointer
|
|
186
187
|
- 若需要删除陈旧项、重排结构或压缩公告牌,仍使用 `change_mind` 做整章替换
|
|
188
|
+
- 当同一主题已经有多条阶段记录时,优先 `change_mind` 合并成当前仍有效的简明公告,而不是继续 `mind_more`
|
|
187
189
|
|
|
188
190
|
### 7. recall_taskdoc
|
|
189
191
|
|
|
@@ -255,7 +257,7 @@ update_reminder({
|
|
|
255
257
|
|
|
256
258
|
```typescript
|
|
257
259
|
mind_more({
|
|
258
|
-
items: ['- 下一步:补齐 Taskdoc `progress`
|
|
260
|
+
items: ['- 下一步:补齐 Taskdoc `progress` 的公告牌属性说明(详见 <文档路径>#<章节>)'],
|
|
259
261
|
});
|
|
260
262
|
```
|
|
261
263
|
|
|
@@ -265,7 +267,7 @@ mind_more({
|
|
|
265
267
|
change_mind({
|
|
266
268
|
selector: 'progress',
|
|
267
269
|
content:
|
|
268
|
-
'## Progress\n\n### 当前有效状态\n- 手册边界方案已确定:角色级资产 / 个人长期经验 / Taskdoc-progress / reminders
|
|
270
|
+
'## Progress\n\n### 当前有效状态\n- 手册边界方案已确定:角色级资产 / 个人长期经验 / Taskdoc-progress / reminders 分流;细节见 <文档路径>#<章节>\n\n### 已生效决策\n- `persona / knowhow / pitfalls` 不承接成员日常经验\n- `personal_memory` 只承接成员自己的长期可复用经验\n\n### 下一步\n- 补齐 Taskdoc `progress` 的公告牌属性说明\n\n### 仍成立阻塞\n- 无',
|
|
269
271
|
});
|
|
270
272
|
```
|
|
271
273
|
|
|
@@ -189,7 +189,7 @@ async function updateTaskPackageByChangeMindTarget(params) {
|
|
|
189
189
|
await ensureTaskPackage(taskPackageDirFullPath, updatedBy);
|
|
190
190
|
const filePath = taskPackageFilePathForChangeMindTarget(taskPackageDirFullPath, target);
|
|
191
191
|
await fs.promises.mkdir(path.dirname(filePath), { recursive: true });
|
|
192
|
-
await
|
|
192
|
+
await writeMarkdownFileWithCanonicalEnding(filePath, content);
|
|
193
193
|
}
|
|
194
194
|
async function appendTaskPackageByChangeMindTarget(params) {
|
|
195
195
|
const { taskPackageDirFullPath, target, content, sep, updatedBy } = params;
|
|
@@ -198,7 +198,16 @@ async function appendTaskPackageByChangeMindTarget(params) {
|
|
|
198
198
|
await fs.promises.mkdir(path.dirname(filePath), { recursive: true });
|
|
199
199
|
const current = await readTextFileIfPresent(filePath);
|
|
200
200
|
const next = current === null || current.trim() === '' ? content : joinForAppend(current, content, sep);
|
|
201
|
-
await
|
|
201
|
+
await writeMarkdownFileWithCanonicalEnding(filePath, next);
|
|
202
|
+
}
|
|
203
|
+
async function writeMarkdownFileWithCanonicalEnding(filePath, content) {
|
|
204
|
+
await fs.promises.writeFile(filePath, withCanonicalMarkdownFileEnding(content), 'utf8');
|
|
205
|
+
}
|
|
206
|
+
function withCanonicalMarkdownFileEnding(content) {
|
|
207
|
+
const stripped = stripTrailingMarkdownFileNewlines(content);
|
|
208
|
+
if (stripped === '')
|
|
209
|
+
return '';
|
|
210
|
+
return `${stripped}\n`;
|
|
202
211
|
}
|
|
203
212
|
function taskPackageFilePathForChangeMindTarget(taskPackageDirFullPath, target) {
|
|
204
213
|
switch (target.kind) {
|
|
@@ -271,18 +280,23 @@ async function readTaskPackageSections(taskPackageDirFullPath) {
|
|
|
271
280
|
return { goals, constraints, progress };
|
|
272
281
|
}
|
|
273
282
|
function formatSectionBodyI18n(state) {
|
|
274
|
-
// Injection must be deterministic and treat section bodies as opaque markdown
|
|
283
|
+
// Injection must be deterministic and treat section bodies as opaque markdown,
|
|
284
|
+
// except for file-final newlines that only encode on-disk formatting.
|
|
275
285
|
// If a required file is missing, inject an empty body (status should be shown elsewhere).
|
|
276
286
|
if (state.kind === 'present')
|
|
277
|
-
return state.content;
|
|
287
|
+
return stripTrailingMarkdownFileNewlines(state.content);
|
|
278
288
|
return '';
|
|
279
289
|
}
|
|
280
290
|
function formatBearInMindBody(state) {
|
|
281
291
|
if (state.kind !== 'present')
|
|
282
292
|
return null;
|
|
283
|
-
|
|
293
|
+
const content = stripTrailingMarkdownFileNewlines(state.content);
|
|
294
|
+
if (content.trim() === '')
|
|
284
295
|
return null;
|
|
285
|
-
return
|
|
296
|
+
return content;
|
|
297
|
+
}
|
|
298
|
+
function stripTrailingMarkdownFileNewlines(content) {
|
|
299
|
+
return content.replace(/(?:\r\n?|\n)+$/u, '');
|
|
286
300
|
}
|
|
287
301
|
function formatEffectiveTaskDocFromSections(language, sections, bearInMind) {
|
|
288
302
|
// Deterministic framing only; section bodies are treated as opaque markdown.
|
|
@@ -470,7 +484,7 @@ async function updateTaskPackageSection(params) {
|
|
|
470
484
|
const { taskPackageDirFullPath, section, content, updatedBy } = params;
|
|
471
485
|
await ensureTaskPackage(taskPackageDirFullPath, updatedBy);
|
|
472
486
|
const filePath = path.join(taskPackageDirFullPath, taskPackageFilenameForSection(section));
|
|
473
|
-
await
|
|
487
|
+
await writeMarkdownFileWithCanonicalEnding(filePath, content);
|
|
474
488
|
}
|
|
475
489
|
async function readTaskPackageExtraSectionsIndex(taskPackageDirFullPath) {
|
|
476
490
|
const maxEntries = 64;
|