dominds 1.9.2 → 1.9.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/dist/docs/memory-system.md +8 -1
- package/dist/docs/memory-system.zh.md +8 -1
- package/dist/docs/txt-editing-tools.md +2 -0
- package/dist/docs/txt-editing-tools.zh.md +1 -0
- package/dist/llm/kernel-driver/tellask-special.js +1 -3
- package/dist/minds/load.js +1 -1
- package/dist/minds/system-prompt-parts.js +7 -4
- package/dist/minds/system-prompt.js +2 -0
- package/dist/runtime/driver-messages.js +34 -35
- package/dist/runtime/inter-dialog-format.d.ts +10 -0
- package/dist/runtime/inter-dialog-format.js +21 -0
- package/dist/server/websocket-handler.js +21 -3
- package/dist/tools/app-reminders.js +50 -21
- package/dist/tools/builtins.js +34 -10
- package/dist/tools/ctrl.js +38 -8
- package/dist/tools/manual/spec.js +5 -6
- package/dist/tools/os.js +133 -32
- package/dist/tools/pending-tellask-reminder.js +36 -13
- package/dist/tools/plan.js +5 -4
- package/dist/tools/prompts/os/en/tools.md +7 -0
- package/dist/tools/prompts/os/zh/tools.md +7 -0
- package/dist/tools/prompts/team_mgmt/en/index.md +1 -0
- package/dist/tools/prompts/team_mgmt/en/principles.md +1 -0
- package/dist/tools/prompts/team_mgmt/en/scenarios.md +2 -0
- package/dist/tools/prompts/team_mgmt/zh/index.md +1 -0
- package/dist/tools/prompts/team_mgmt/zh/principles.md +1 -0
- package/dist/tools/prompts/team_mgmt/zh/scenarios.md +2 -0
- package/dist/tools/prompts/ws_mod/en/index.md +1 -0
- package/dist/tools/prompts/ws_mod/en/principles.md +1 -0
- package/dist/tools/prompts/ws_mod/zh/index.md +1 -0
- package/dist/tools/prompts/ws_mod/zh/principles.md +1 -0
- package/dist/tools/prompts/ws_mod.en.md +4 -0
- package/dist/tools/prompts/ws_mod.zh.md +4 -0
- package/dist/tools/team_mgmt.js +2 -2
- package/dist/tools/toolset-manual.d.ts +1 -1
- package/dist/tools/toolset-manual.js +73 -18
- package/dist/tools/txt.js +21 -11
- package/dist/utils/taskdoc.js +2 -0
- package/package.json +2 -2
- package/webapp/dist/assets/{_basePickBy-9Z1lbVTN.js → _basePickBy-D694K6Gh.js} +3 -3
- package/webapp/dist/assets/{_basePickBy-9Z1lbVTN.js.map → _basePickBy-D694K6Gh.js.map} +1 -1
- package/webapp/dist/assets/{_baseUniq-C3pRnD57.js → _baseUniq-ArneQk-G.js} +2 -2
- package/webapp/dist/assets/{_baseUniq-C3pRnD57.js.map → _baseUniq-ArneQk-G.js.map} +1 -1
- package/webapp/dist/assets/{arc-BvNng3O_.js → arc-8u9ipLr2.js} +2 -2
- package/webapp/dist/assets/{arc-BvNng3O_.js.map → arc-8u9ipLr2.js.map} +1 -1
- package/webapp/dist/assets/{architectureDiagram-2XIMDMQ5-BF8vwQ4e.js → architectureDiagram-2XIMDMQ5-DFV-xGAa.js} +7 -7
- package/webapp/dist/assets/{architectureDiagram-2XIMDMQ5-BF8vwQ4e.js.map → architectureDiagram-2XIMDMQ5-DFV-xGAa.js.map} +1 -1
- package/webapp/dist/assets/{blockDiagram-WCTKOSBZ-C7kfjZhf.js → blockDiagram-WCTKOSBZ-pk6LU06K.js} +7 -7
- package/webapp/dist/assets/{blockDiagram-WCTKOSBZ-C7kfjZhf.js.map → blockDiagram-WCTKOSBZ-pk6LU06K.js.map} +1 -1
- package/webapp/dist/assets/{c4Diagram-IC4MRINW-CaJ6bX75.js → c4Diagram-IC4MRINW-D4SBLYjK.js} +3 -3
- package/webapp/dist/assets/{c4Diagram-IC4MRINW-CaJ6bX75.js.map → c4Diagram-IC4MRINW-D4SBLYjK.js.map} +1 -1
- package/webapp/dist/assets/{channel-DDuIUO0R.js → channel-D8M5j8c2.js} +2 -2
- package/webapp/dist/assets/{channel-DDuIUO0R.js.map → channel-D8M5j8c2.js.map} +1 -1
- package/webapp/dist/assets/{chunk-4BX2VUAB-BQPkQh6v.js → chunk-4BX2VUAB-B-6IvMRI.js} +2 -2
- package/webapp/dist/assets/{chunk-4BX2VUAB-BQPkQh6v.js.map → chunk-4BX2VUAB-B-6IvMRI.js.map} +1 -1
- package/webapp/dist/assets/{chunk-55IACEB6-C2eZTkZ1.js → chunk-55IACEB6-DjEvYtPp.js} +2 -2
- package/webapp/dist/assets/{chunk-55IACEB6-C2eZTkZ1.js.map → chunk-55IACEB6-DjEvYtPp.js.map} +1 -1
- package/webapp/dist/assets/{chunk-FMBD7UC4-aXp5zApD.js → chunk-FMBD7UC4-CrfwnW9e.js} +2 -2
- package/webapp/dist/assets/{chunk-FMBD7UC4-aXp5zApD.js.map → chunk-FMBD7UC4-CrfwnW9e.js.map} +1 -1
- package/webapp/dist/assets/{chunk-JSJVCQXG-DXyaccrz.js → chunk-JSJVCQXG-DroABPma.js} +2 -2
- package/webapp/dist/assets/{chunk-JSJVCQXG-DXyaccrz.js.map → chunk-JSJVCQXG-DroABPma.js.map} +1 -1
- package/webapp/dist/assets/{chunk-KX2RTZJC-C-u000c0.js → chunk-KX2RTZJC--UaFwmvv.js} +2 -2
- package/webapp/dist/assets/{chunk-KX2RTZJC-C-u000c0.js.map → chunk-KX2RTZJC--UaFwmvv.js.map} +1 -1
- package/webapp/dist/assets/{chunk-NQ4KR5QH-BoYRoo4A.js → chunk-NQ4KR5QH-hGQ1BQy3.js} +4 -4
- package/webapp/dist/assets/{chunk-NQ4KR5QH-BoYRoo4A.js.map → chunk-NQ4KR5QH-hGQ1BQy3.js.map} +1 -1
- package/webapp/dist/assets/{chunk-QZHKN3VN-BAc_2ceG.js → chunk-QZHKN3VN-L1f-RVf4.js} +2 -2
- package/webapp/dist/assets/{chunk-QZHKN3VN-BAc_2ceG.js.map → chunk-QZHKN3VN-L1f-RVf4.js.map} +1 -1
- package/webapp/dist/assets/{chunk-WL4C6EOR-D6ws69Jx.js → chunk-WL4C6EOR-BS6MGl-Y.js} +6 -6
- package/webapp/dist/assets/{chunk-WL4C6EOR-D6ws69Jx.js.map → chunk-WL4C6EOR-BS6MGl-Y.js.map} +1 -1
- package/webapp/dist/assets/{classDiagram-VBA2DB6C-BIRrKhqs.js → classDiagram-VBA2DB6C-wDVeUi90.js} +7 -7
- package/webapp/dist/assets/{classDiagram-VBA2DB6C-BIRrKhqs.js.map → classDiagram-VBA2DB6C-wDVeUi90.js.map} +1 -1
- package/webapp/dist/assets/{classDiagram-v2-RAHNMMFH-BIRrKhqs.js → classDiagram-v2-RAHNMMFH-wDVeUi90.js} +7 -7
- package/webapp/dist/assets/{classDiagram-v2-RAHNMMFH-BIRrKhqs.js.map → classDiagram-v2-RAHNMMFH-wDVeUi90.js.map} +1 -1
- package/webapp/dist/assets/{clone-DweFyVW6.js → clone-C2MtRhfG.js} +2 -2
- package/webapp/dist/assets/{clone-DweFyVW6.js.map → clone-C2MtRhfG.js.map} +1 -1
- package/webapp/dist/assets/{cose-bilkent-S5V4N54A-vgovmGKM.js → cose-bilkent-S5V4N54A-CEf3Y19l.js} +2 -2
- package/webapp/dist/assets/{cose-bilkent-S5V4N54A-vgovmGKM.js.map → cose-bilkent-S5V4N54A-CEf3Y19l.js.map} +1 -1
- package/webapp/dist/assets/{dagre-KLK3FWXG-B-Ax3qBf.js → dagre-KLK3FWXG-Dy_y44Tz.js} +7 -7
- package/webapp/dist/assets/{dagre-KLK3FWXG-B-Ax3qBf.js.map → dagre-KLK3FWXG-Dy_y44Tz.js.map} +1 -1
- package/webapp/dist/assets/{diagram-E7M64L7V-B1sUlvtn.js → diagram-E7M64L7V-Bvv5WU0i.js} +8 -8
- package/webapp/dist/assets/{diagram-E7M64L7V-B1sUlvtn.js.map → diagram-E7M64L7V-Bvv5WU0i.js.map} +1 -1
- package/webapp/dist/assets/{diagram-IFDJBPK2-3IlyK_xp.js → diagram-IFDJBPK2-DgKslRxt.js} +7 -7
- package/webapp/dist/assets/{diagram-IFDJBPK2-3IlyK_xp.js.map → diagram-IFDJBPK2-DgKslRxt.js.map} +1 -1
- package/webapp/dist/assets/{diagram-P4PSJMXO-C3x0JkgF.js → diagram-P4PSJMXO-DKuN0W-K.js} +7 -7
- package/webapp/dist/assets/{diagram-P4PSJMXO-C3x0JkgF.js.map → diagram-P4PSJMXO-DKuN0W-K.js.map} +1 -1
- package/webapp/dist/assets/{erDiagram-INFDFZHY-mEp6kC6i.js → erDiagram-INFDFZHY-Buc2e1H3.js} +5 -5
- package/webapp/dist/assets/{erDiagram-INFDFZHY-mEp6kC6i.js.map → erDiagram-INFDFZHY-Buc2e1H3.js.map} +1 -1
- package/webapp/dist/assets/{flowDiagram-PKNHOUZH-AsG_wdLN.js → flowDiagram-PKNHOUZH-J69A4hB0.js} +7 -7
- package/webapp/dist/assets/{flowDiagram-PKNHOUZH-AsG_wdLN.js.map → flowDiagram-PKNHOUZH-J69A4hB0.js.map} +1 -1
- package/webapp/dist/assets/{ganttDiagram-A5KZAMGK-zv3UhEAO.js → ganttDiagram-A5KZAMGK-B_EUDSCl.js} +3 -3
- package/webapp/dist/assets/{ganttDiagram-A5KZAMGK-zv3UhEAO.js.map → ganttDiagram-A5KZAMGK-B_EUDSCl.js.map} +1 -1
- package/webapp/dist/assets/{gitGraphDiagram-K3NZZRJ6-C1yyISy7.js → gitGraphDiagram-K3NZZRJ6-B1111A11.js} +8 -8
- package/webapp/dist/assets/{gitGraphDiagram-K3NZZRJ6-C1yyISy7.js.map → gitGraphDiagram-K3NZZRJ6-B1111A11.js.map} +1 -1
- package/webapp/dist/assets/{graph-CkQycYq_.js → graph-CdxqCYb0.js} +3 -3
- package/webapp/dist/assets/{graph-CkQycYq_.js.map → graph-CdxqCYb0.js.map} +1 -1
- package/webapp/dist/assets/{index-CCGi5dDE.js → index-BHe1oHIa.js} +181 -49
- package/webapp/dist/assets/{index-CCGi5dDE.js.map → index-BHe1oHIa.js.map} +1 -1
- package/webapp/dist/assets/{infoDiagram-LFFYTUFH-Dw1wAgpl.js → infoDiagram-LFFYTUFH-B0NHDULu.js} +6 -6
- package/webapp/dist/assets/{infoDiagram-LFFYTUFH-Dw1wAgpl.js.map → infoDiagram-LFFYTUFH-B0NHDULu.js.map} +1 -1
- package/webapp/dist/assets/{ishikawaDiagram-PHBUUO56-DY9fHLYz.js → ishikawaDiagram-PHBUUO56-zFZuCrGV.js} +2 -2
- package/webapp/dist/assets/{ishikawaDiagram-PHBUUO56-DY9fHLYz.js.map → ishikawaDiagram-PHBUUO56-zFZuCrGV.js.map} +1 -1
- package/webapp/dist/assets/{journeyDiagram-4ABVD52K-CSGjRykr.js → journeyDiagram-4ABVD52K-C-Y3JIvI.js} +5 -5
- package/webapp/dist/assets/{journeyDiagram-4ABVD52K-CSGjRykr.js.map → journeyDiagram-4ABVD52K-C-Y3JIvI.js.map} +1 -1
- package/webapp/dist/assets/{kanban-definition-K7BYSVSG-DDCQetMc.js → kanban-definition-K7BYSVSG-CAWm_s77.js} +3 -3
- package/webapp/dist/assets/{kanban-definition-K7BYSVSG-DDCQetMc.js.map → kanban-definition-K7BYSVSG-CAWm_s77.js.map} +1 -1
- package/webapp/dist/assets/{layout-DpuTr6cl.js → layout-DAf8AacP.js} +5 -5
- package/webapp/dist/assets/{layout-DpuTr6cl.js.map → layout-DAf8AacP.js.map} +1 -1
- package/webapp/dist/assets/{linear-BQv5LuhW.js → linear-5V_bWmGQ.js} +2 -2
- package/webapp/dist/assets/{linear-BQv5LuhW.js.map → linear-5V_bWmGQ.js.map} +1 -1
- package/webapp/dist/assets/{mindmap-definition-YRQLILUH-C5ajM9Hr.js → mindmap-definition-YRQLILUH-CbZFlmPZ.js} +4 -4
- package/webapp/dist/assets/{mindmap-definition-YRQLILUH-C5ajM9Hr.js.map → mindmap-definition-YRQLILUH-CbZFlmPZ.js.map} +1 -1
- package/webapp/dist/assets/{pieDiagram-SKSYHLDU-Daqms3DT.js → pieDiagram-SKSYHLDU-BdjfUPSq.js} +8 -8
- package/webapp/dist/assets/{pieDiagram-SKSYHLDU-Daqms3DT.js.map → pieDiagram-SKSYHLDU-BdjfUPSq.js.map} +1 -1
- package/webapp/dist/assets/{quadrantDiagram-337W2JSQ-BMNWp18J.js → quadrantDiagram-337W2JSQ-B_roS40E.js} +3 -3
- package/webapp/dist/assets/{quadrantDiagram-337W2JSQ-BMNWp18J.js.map → quadrantDiagram-337W2JSQ-B_roS40E.js.map} +1 -1
- package/webapp/dist/assets/{requirementDiagram-Z7DCOOCP-C1Mc4MX-.js → requirementDiagram-Z7DCOOCP-Cte4tBaS.js} +4 -4
- package/webapp/dist/assets/{requirementDiagram-Z7DCOOCP-C1Mc4MX-.js.map → requirementDiagram-Z7DCOOCP-Cte4tBaS.js.map} +1 -1
- package/webapp/dist/assets/{sankeyDiagram-WA2Y5GQK-DTHGhOsp.js → sankeyDiagram-WA2Y5GQK-_7BuCxMO.js} +2 -2
- package/webapp/dist/assets/{sankeyDiagram-WA2Y5GQK-DTHGhOsp.js.map → sankeyDiagram-WA2Y5GQK-_7BuCxMO.js.map} +1 -1
- package/webapp/dist/assets/{sequenceDiagram-2WXFIKYE-C6cA5ncc.js → sequenceDiagram-2WXFIKYE-DIrNFVXO.js} +4 -4
- package/webapp/dist/assets/{sequenceDiagram-2WXFIKYE-C6cA5ncc.js.map → sequenceDiagram-2WXFIKYE-DIrNFVXO.js.map} +1 -1
- package/webapp/dist/assets/{stateDiagram-RAJIS63D-DRDqVPKY.js → stateDiagram-RAJIS63D-CleFEXbm.js} +9 -9
- package/webapp/dist/assets/{stateDiagram-RAJIS63D-DRDqVPKY.js.map → stateDiagram-RAJIS63D-CleFEXbm.js.map} +1 -1
- package/webapp/dist/assets/{stateDiagram-v2-FVOUBMTO-B-pby7Ke.js → stateDiagram-v2-FVOUBMTO-BPhDPWWG.js} +5 -5
- package/webapp/dist/assets/{stateDiagram-v2-FVOUBMTO-B-pby7Ke.js.map → stateDiagram-v2-FVOUBMTO-BPhDPWWG.js.map} +1 -1
- package/webapp/dist/assets/{timeline-definition-YZTLITO2-C-m1bG_Z.js → timeline-definition-YZTLITO2-DrrU-OCU.js} +3 -3
- package/webapp/dist/assets/{timeline-definition-YZTLITO2-C-m1bG_Z.js.map → timeline-definition-YZTLITO2-DrrU-OCU.js.map} +1 -1
- package/webapp/dist/assets/{treemap-KZPCXAKY-BWvLuAyU.js → treemap-KZPCXAKY-DShBAWxS.js} +5 -5
- package/webapp/dist/assets/{treemap-KZPCXAKY-BWvLuAyU.js.map → treemap-KZPCXAKY-DShBAWxS.js.map} +1 -1
- package/webapp/dist/assets/{vennDiagram-LZ73GAT5-C8gZYuUq.js → vennDiagram-LZ73GAT5-DNQztUY0.js} +2 -2
- package/webapp/dist/assets/{vennDiagram-LZ73GAT5-C8gZYuUq.js.map → vennDiagram-LZ73GAT5-DNQztUY0.js.map} +1 -1
- package/webapp/dist/assets/{xychartDiagram-JWTSCODW-Bb3azvDM.js → xychartDiagram-JWTSCODW-q8D6fe1E.js} +3 -3
- package/webapp/dist/assets/{xychartDiagram-JWTSCODW-Bb3azvDM.js.map → xychartDiagram-JWTSCODW-q8D6fe1E.js.map} +1 -1
- package/webapp/dist/index.html +1 -1
package/dist/tools/ctrl.js
CHANGED
|
@@ -90,6 +90,35 @@ function isJsonValue(value) {
|
|
|
90
90
|
function isJsonObject(value) {
|
|
91
91
|
return isRecord(value) && Object.values(value).every((item) => isJsonValue(item));
|
|
92
92
|
}
|
|
93
|
+
function getManagerTool(meta) {
|
|
94
|
+
if (!isRecord(meta)) {
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
const manager = meta['manager'];
|
|
98
|
+
if (!isRecord(manager)) {
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
const tool = manager['tool'];
|
|
102
|
+
return typeof tool === 'string' && tool.trim().length > 0 ? tool.trim() : undefined;
|
|
103
|
+
}
|
|
104
|
+
function getDeleteAltInstruction(meta) {
|
|
105
|
+
if (!isRecord(meta)) {
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
108
|
+
const deleteValue = meta['delete'];
|
|
109
|
+
if (!isRecord(deleteValue)) {
|
|
110
|
+
return undefined;
|
|
111
|
+
}
|
|
112
|
+
const altInstruction = deleteValue['altInstruction'];
|
|
113
|
+
return typeof altInstruction === 'string' && altInstruction.trim().length > 0
|
|
114
|
+
? altInstruction.trim()
|
|
115
|
+
: undefined;
|
|
116
|
+
}
|
|
117
|
+
function formatManualDeleteBlockedError(language, altInstruction) {
|
|
118
|
+
return language === 'zh'
|
|
119
|
+
? `错误:该提醒项不能用 delete_reminder 删除;请改为执行:${altInstruction}`
|
|
120
|
+
: `Error: This reminder cannot be deleted via delete_reminder. Use instead: ${altInstruction}`;
|
|
121
|
+
}
|
|
93
122
|
function listNumberedReminderIndices(reminders) {
|
|
94
123
|
const indices = [];
|
|
95
124
|
for (let index = 0; index < reminders.length; index += 1) {
|
|
@@ -289,6 +318,10 @@ exports.deleteReminderTool = {
|
|
|
289
318
|
if (targetIndex < 0) {
|
|
290
319
|
return t.reminderDoesNotExist(String(reminderNoValue), numberedReminders.length);
|
|
291
320
|
}
|
|
321
|
+
const deleteAltInstruction = getDeleteAltInstruction(targetReminder.meta);
|
|
322
|
+
if (deleteAltInstruction !== undefined) {
|
|
323
|
+
return formatManualDeleteBlockedError(language, deleteAltInstruction);
|
|
324
|
+
}
|
|
292
325
|
dlg.deleteReminder(targetIndex);
|
|
293
326
|
return (0, tool_result_messages_1.formatToolActionResult)(language, 'deleted');
|
|
294
327
|
},
|
|
@@ -390,14 +423,11 @@ exports.updateReminderTool = {
|
|
|
390
423
|
// `reminder.meta` is persisted JSON. Runtime shape checks are unavoidable here because tools
|
|
391
424
|
// may attach arbitrary metadata for reminder ownership/management.
|
|
392
425
|
const meta = reminder?.meta;
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
? `错误:该提醒项由工具 ${managedByTool} 管理,不能用 update_reminder 修改;请使用 ${managedByTool} 更新。`
|
|
399
|
-
: `Error: This reminder is managed by tool ${managedByTool}. Do not edit it via update_reminder; use ${managedByTool} instead.`;
|
|
400
|
-
}
|
|
426
|
+
const managerTool = getManagerTool(meta);
|
|
427
|
+
if (managerTool !== undefined) {
|
|
428
|
+
return language === 'zh'
|
|
429
|
+
? `错误:该提醒项由工具 ${managerTool} 管理,不能用 update_reminder 修改;请使用 ${managerTool} 更新。`
|
|
430
|
+
: `Error: This reminder is managed by tool ${managerTool}. Do not edit it via update_reminder; use ${managerTool} instead.`;
|
|
401
431
|
}
|
|
402
432
|
const contentValue = args['content'];
|
|
403
433
|
const reminderContent = typeof contentValue === 'string' ? contentValue.trim() : '';
|
|
@@ -82,15 +82,14 @@ function shouldIncludeSchemaToolsSection(spec) {
|
|
|
82
82
|
* No heuristics — `toolsetId` is an explicit parameter.
|
|
83
83
|
*/
|
|
84
84
|
function builtinManualTopicPaths(toolsetId, language) {
|
|
85
|
-
const suffix = language === 'en' ? '.en' : '';
|
|
86
85
|
const langDir = language;
|
|
87
86
|
const baseDir = `prompts/${toolsetId}`;
|
|
88
87
|
return {
|
|
89
|
-
index: path.join(baseDir, langDir,
|
|
90
|
-
principles: path.join(baseDir, langDir,
|
|
91
|
-
tools: path.join(baseDir, langDir,
|
|
92
|
-
scenarios: path.join(baseDir, langDir,
|
|
93
|
-
errors: path.join(baseDir, langDir,
|
|
88
|
+
index: path.join(baseDir, langDir, 'index.md'),
|
|
89
|
+
principles: path.join(baseDir, langDir, 'principles.md'),
|
|
90
|
+
tools: path.join(baseDir, langDir, 'tools.md'),
|
|
91
|
+
scenarios: path.join(baseDir, langDir, 'scenarios.md'),
|
|
92
|
+
errors: path.join(baseDir, langDir, 'errors.md'),
|
|
94
93
|
};
|
|
95
94
|
}
|
|
96
95
|
/**
|
package/dist/tools/os.js
CHANGED
|
@@ -132,6 +132,55 @@ class HeadTailByteBuffer {
|
|
|
132
132
|
}
|
|
133
133
|
// Global registry for daemon processes
|
|
134
134
|
const daemonProcesses = new Map();
|
|
135
|
+
let trackedDaemonShutdownSigtermSent = false;
|
|
136
|
+
let trackedDaemonShutdownSigkillSent = false;
|
|
137
|
+
function resolveBestEffortDaemonSignalTarget(daemon) {
|
|
138
|
+
if (process.platform !== 'win32' && daemon.processGroupId !== undefined) {
|
|
139
|
+
return -daemon.processGroupId;
|
|
140
|
+
}
|
|
141
|
+
return daemon.pid;
|
|
142
|
+
}
|
|
143
|
+
function signalTrackedDaemonsForProcessShutdown(signal) {
|
|
144
|
+
const alreadySent = signal === 'SIGTERM' ? trackedDaemonShutdownSigtermSent : trackedDaemonShutdownSigkillSent;
|
|
145
|
+
if (alreadySent)
|
|
146
|
+
return;
|
|
147
|
+
if (signal === 'SIGTERM') {
|
|
148
|
+
trackedDaemonShutdownSigtermSent = true;
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
trackedDaemonShutdownSigkillSent = true;
|
|
152
|
+
}
|
|
153
|
+
for (const daemon of daemonProcesses.values()) {
|
|
154
|
+
const signalTarget = resolveBestEffortDaemonSignalTarget(daemon);
|
|
155
|
+
try {
|
|
156
|
+
process.kill(signalTarget, signal);
|
|
157
|
+
}
|
|
158
|
+
catch (error) {
|
|
159
|
+
console.error('[os] failed to signal tracked daemon during process shutdown', {
|
|
160
|
+
pid: daemon.pid,
|
|
161
|
+
processGroupId: daemon.processGroupId ?? null,
|
|
162
|
+
signal,
|
|
163
|
+
error: error instanceof Error ? error.message : String(error),
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
if (signal === 'SIGKILL') {
|
|
168
|
+
daemonProcesses.clear();
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
process.once('beforeExit', () => {
|
|
172
|
+
signalTrackedDaemonsForProcessShutdown('SIGTERM');
|
|
173
|
+
});
|
|
174
|
+
process.once('exit', () => {
|
|
175
|
+
signalTrackedDaemonsForProcessShutdown('SIGTERM');
|
|
176
|
+
signalTrackedDaemonsForProcessShutdown('SIGKILL');
|
|
177
|
+
});
|
|
178
|
+
process.once('SIGINT', () => {
|
|
179
|
+
signalTrackedDaemonsForProcessShutdown('SIGTERM');
|
|
180
|
+
});
|
|
181
|
+
process.once('SIGTERM', () => {
|
|
182
|
+
signalTrackedDaemonsForProcessShutdown('SIGTERM');
|
|
183
|
+
});
|
|
135
184
|
function getOsToolMessages(language) {
|
|
136
185
|
if (language === 'zh') {
|
|
137
186
|
return {
|
|
@@ -249,7 +298,17 @@ function parseStopDaemonArgs(args) {
|
|
|
249
298
|
if (typeof pid !== 'number') {
|
|
250
299
|
throw new Error('stop_daemon.pid must be a number');
|
|
251
300
|
}
|
|
252
|
-
|
|
301
|
+
const entirePg = args.entire_pg;
|
|
302
|
+
if (entirePg !== undefined && typeof entirePg !== 'boolean') {
|
|
303
|
+
throw new Error('stop_daemon.entire_pg must be a boolean if provided');
|
|
304
|
+
}
|
|
305
|
+
if (process.platform === 'win32' && entirePg === true) {
|
|
306
|
+
throw new Error('stop_daemon.entire_pg=true is unsupported on Windows');
|
|
307
|
+
}
|
|
308
|
+
return {
|
|
309
|
+
pid,
|
|
310
|
+
entirePg: entirePg ?? process.platform !== 'win32',
|
|
311
|
+
};
|
|
253
312
|
}
|
|
254
313
|
function parseGetDaemonOutputArgs(args) {
|
|
255
314
|
const pid = args.pid;
|
|
@@ -356,6 +415,10 @@ const stopDaemonSchema = {
|
|
|
356
415
|
type: 'number',
|
|
357
416
|
description: 'Process ID of the daemon to stop',
|
|
358
417
|
},
|
|
418
|
+
entire_pg: {
|
|
419
|
+
type: 'boolean',
|
|
420
|
+
description: 'Whether to signal the entire process group instead of only the tracked PID (default: true on Unix-like systems; false on Windows)',
|
|
421
|
+
},
|
|
359
422
|
},
|
|
360
423
|
required: ['pid'],
|
|
361
424
|
additionalProperties: false,
|
|
@@ -377,44 +440,70 @@ const getDaemonOutputSchema = {
|
|
|
377
440
|
additionalProperties: false,
|
|
378
441
|
};
|
|
379
442
|
// Format daemon status for reminder display
|
|
380
|
-
function formatDaemonStatus(daemon) {
|
|
443
|
+
function formatDaemonStatus(daemon, language) {
|
|
381
444
|
const uptime = Math.floor((Date.now() - daemon.startTime.getTime()) / 1000);
|
|
382
|
-
const status =
|
|
383
|
-
?
|
|
384
|
-
|
|
445
|
+
const status = language === 'zh'
|
|
446
|
+
? daemon.isRunning
|
|
447
|
+
? '运行中'
|
|
448
|
+
: `已退出(code: ${daemon.exitCode}, signal: ${daemon.exitSignal})`
|
|
449
|
+
: daemon.isRunning
|
|
450
|
+
? 'running'
|
|
451
|
+
: `exited (code: ${daemon.exitCode}, signal: ${daemon.exitSignal})`;
|
|
385
452
|
const stdoutInfo = daemon.stdoutBuffer.getScrollInfo();
|
|
386
453
|
const stderrInfo = daemon.stderrBuffer.getScrollInfo();
|
|
387
454
|
let scrollNotice = '';
|
|
388
455
|
if (stdoutInfo.hasScrolledContent || stderrInfo.hasScrolledContent) {
|
|
389
456
|
const scrolledLines = stdoutInfo.linesScrolledOut + stderrInfo.linesScrolledOut;
|
|
390
|
-
scrollNotice =
|
|
457
|
+
scrollNotice =
|
|
458
|
+
language === 'zh'
|
|
459
|
+
? `\n注意:已有 ${scrolledLines} 行滚出当前保留缓冲区`
|
|
460
|
+
: `\nNote: ${scrolledLines} lines have scrolled out of the retained buffer`;
|
|
391
461
|
}
|
|
392
462
|
const stdoutContent = daemon.stdoutBuffer.isEmpty()
|
|
393
|
-
?
|
|
463
|
+
? language === 'zh'
|
|
464
|
+
? '(无输出)'
|
|
465
|
+
: '(no output)'
|
|
394
466
|
: daemon.stdoutBuffer.getContent();
|
|
395
467
|
const stderrContent = daemon.stderrBuffer.isEmpty()
|
|
396
|
-
?
|
|
468
|
+
? language === 'zh'
|
|
469
|
+
? '(无 stderr 输出)'
|
|
470
|
+
: '(no stderr output)'
|
|
397
471
|
: daemon.stderrBuffer.getContent();
|
|
398
472
|
const fenceConsole = '```console';
|
|
399
473
|
const fenceEnd = '```';
|
|
400
|
-
return
|
|
401
|
-
|
|
474
|
+
return language === 'zh'
|
|
475
|
+
? `后台进程 PID: ${daemon.pid}
|
|
476
|
+
命令: ${daemon.command}
|
|
402
477
|
Shell: ${daemon.shell}
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
478
|
+
生命周期状态: ${status}
|
|
479
|
+
已运行: ${uptime}s
|
|
480
|
+
启动时间: ${(0, time_1.formatUnifiedTimestamp)(daemon.startTime)}${scrollNotice}
|
|
406
481
|
|
|
407
|
-
|
|
482
|
+
stdout 缓冲区快照:
|
|
408
483
|
${fenceConsole}
|
|
409
484
|
${stdoutContent}
|
|
410
485
|
${fenceEnd}
|
|
411
486
|
|
|
412
|
-
|
|
487
|
+
stderr 缓冲区快照:
|
|
413
488
|
${fenceConsole}
|
|
414
489
|
${stderrContent}
|
|
490
|
+
${fenceEnd}`
|
|
491
|
+
: `Daemon PID: ${daemon.pid}
|
|
492
|
+
Command: ${daemon.command}
|
|
493
|
+
Shell: ${daemon.shell}
|
|
494
|
+
Lifecycle status: ${status}
|
|
495
|
+
Uptime: ${uptime}s
|
|
496
|
+
Started at: ${(0, time_1.formatUnifiedTimestamp)(daemon.startTime)}${scrollNotice}
|
|
497
|
+
|
|
498
|
+
Stdout buffer snapshot:
|
|
499
|
+
${fenceConsole}
|
|
500
|
+
${stdoutContent}
|
|
415
501
|
${fenceEnd}
|
|
416
502
|
|
|
417
|
-
|
|
503
|
+
Stderr buffer snapshot:
|
|
504
|
+
${fenceConsole}
|
|
505
|
+
${stderrContent}
|
|
506
|
+
${fenceEnd}`;
|
|
418
507
|
}
|
|
419
508
|
// ReminderOwner implementation for shell command tool
|
|
420
509
|
exports.shellCmdReminderOwner = {
|
|
@@ -432,7 +521,7 @@ exports.shellCmdReminderOwner = {
|
|
|
432
521
|
// Check if process has exited
|
|
433
522
|
if (!daemon.isRunning) {
|
|
434
523
|
// Process has exited, provide final status and drop reminder
|
|
435
|
-
const finalStatus = formatDaemonStatus(daemon);
|
|
524
|
+
const finalStatus = formatDaemonStatus(daemon, (0, work_language_1.getWorkLanguage)());
|
|
436
525
|
daemonProcesses.delete(pid);
|
|
437
526
|
return {
|
|
438
527
|
treatment: 'update',
|
|
@@ -457,7 +546,7 @@ exports.shellCmdReminderOwner = {
|
|
|
457
546
|
daemon.exitSignal = 'UNKNOWN';
|
|
458
547
|
}
|
|
459
548
|
// Update the reminder with current daemon status
|
|
460
|
-
const updatedContent = formatDaemonStatus(daemon);
|
|
549
|
+
const updatedContent = formatDaemonStatus(daemon, (0, work_language_1.getWorkLanguage)());
|
|
461
550
|
return {
|
|
462
551
|
treatment: 'update',
|
|
463
552
|
updatedContent,
|
|
@@ -477,11 +566,11 @@ exports.shellCmdReminderOwner = {
|
|
|
477
566
|
role: 'user',
|
|
478
567
|
content: language === 'zh'
|
|
479
568
|
? `${prefix} 后台进程状态提醒 #${index + 1}
|
|
480
|
-
|
|
569
|
+
这是系统维护的后台进程状态快照。把它当成环境信号,不是你自己写的工作便签。若它没有实质改变你的判断/计划/风险,则禁止做任何用户可见回应(禁止写“静默吸收”“已收到”等占位语句);只有它实际影响后续动作时,才在下一条有实质内容的回复中体现相关事实。该提醒会随进程生命周期自动更新或删除。
|
|
481
570
|
---
|
|
482
571
|
${reminder.content}`
|
|
483
572
|
: `${prefix} Background process status reminder #${index + 1}
|
|
484
|
-
|
|
573
|
+
This is a system-maintained background process snapshot. Treat it as an environment signal, not a self-authored work note. If it does not materially change your judgment/plan/risk, make no user-visible reply at all (do not send filler like “silently noted” or “received”); only reflect it inside the next substantive reply when it actually affects the next action. This reminder will update or disappear automatically with the process lifecycle.
|
|
485
574
|
---
|
|
486
575
|
${reminder.content}`,
|
|
487
576
|
};
|
|
@@ -507,20 +596,20 @@ This daemon process has finished its lifecycle and is no longer running. This re
|
|
|
507
596
|
: uptime < 3600
|
|
508
597
|
? `${Math.floor(uptime / 60)}m ${uptime % 60}s`
|
|
509
598
|
: `${Math.floor(uptime / 3600)}h ${Math.floor((uptime % 3600) / 60)}m`;
|
|
510
|
-
const statusInfo = formatDaemonStatus(daemon);
|
|
599
|
+
const statusInfo = formatDaemonStatus(daemon, language);
|
|
511
600
|
return {
|
|
512
601
|
type: 'environment_msg',
|
|
513
602
|
role: 'user',
|
|
514
603
|
content: language === 'zh'
|
|
515
|
-
? `🔄 ${prefix}
|
|
516
|
-
|
|
604
|
+
? `🔄 ${prefix} 运行中后台进程状态 #${index + 1} - PID ${pid}(已运行 ${uptimeStr})
|
|
605
|
+
这是系统维护的状态快照,不是新的用户诉求,也不是默认需要单独汇报的事项。若下面的信息没有实质改变你的判断、计划、风险,且不需要调用守护进程相关工具,则禁止做任何用户可见回应;若它有实质影响,只在下一条有实质内容的回复中体现,禁止单独发送“静默吸收”“已收到”等占位语句。
|
|
517
606
|
|
|
518
|
-
|
|
607
|
+
**状态快照:**
|
|
519
608
|
${statusInfo}`
|
|
520
|
-
: `🔄 ${prefix} Active daemon
|
|
521
|
-
|
|
609
|
+
: `🔄 ${prefix} Active daemon state #${index + 1} - PID ${pid} (uptime: ${uptimeStr})
|
|
610
|
+
This is a system-maintained snapshot, not a new user request and not something that normally deserves a standalone mention. If the information below does not materially change your judgment, plan, risk, or require a daemon-management action, make no user-visible reply at all; if it does matter, reflect it only inside the next substantive reply instead of sending filler like “silently noted” or “received”.
|
|
522
611
|
|
|
523
|
-
**
|
|
612
|
+
**State snapshot:**
|
|
524
613
|
${statusInfo}`,
|
|
525
614
|
};
|
|
526
615
|
},
|
|
@@ -546,6 +635,7 @@ exports.shellCmdTool = {
|
|
|
546
635
|
return new Promise((resolve) => {
|
|
547
636
|
const childProcess = (0, child_process_1.spawn)(spawnSpec.command, spawnSpec.args, {
|
|
548
637
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
638
|
+
detached: process.platform !== 'win32',
|
|
549
639
|
});
|
|
550
640
|
const pid = childProcess.pid;
|
|
551
641
|
const startTime = new Date();
|
|
@@ -564,6 +654,7 @@ exports.shellCmdTool = {
|
|
|
564
654
|
command,
|
|
565
655
|
shell: spawnSpec.shellLabel,
|
|
566
656
|
process: childProcess,
|
|
657
|
+
processGroupId: process.platform === 'win32' ? undefined : pid,
|
|
567
658
|
startTime,
|
|
568
659
|
stdoutBuffer,
|
|
569
660
|
stderrBuffer,
|
|
@@ -574,11 +665,14 @@ exports.shellCmdTool = {
|
|
|
574
665
|
// Add reminder for daemon process
|
|
575
666
|
const reminderContent = `[Daemon PID ${pid} - This content should not be visible, check dynamic rendering]`;
|
|
576
667
|
dlg.addReminder(reminderContent, exports.shellCmdReminderOwner, {
|
|
577
|
-
|
|
668
|
+
kind: 'daemon',
|
|
578
669
|
pid,
|
|
579
670
|
command,
|
|
580
671
|
shell: spawnSpec.shellLabel,
|
|
581
672
|
startTime: (0, time_1.formatUnifiedTimestamp)(startTime),
|
|
673
|
+
delete: {
|
|
674
|
+
altInstruction: `stop_daemon({ "pid": ${pid} })`,
|
|
675
|
+
},
|
|
582
676
|
});
|
|
583
677
|
resolve(t.daemonStarted(pid, timeoutSeconds, command));
|
|
584
678
|
}, timeoutSeconds * 1000);
|
|
@@ -1308,19 +1402,26 @@ exports.stopDaemonTool = {
|
|
|
1308
1402
|
async call(dlg, caller, args) {
|
|
1309
1403
|
const language = (0, work_language_1.getWorkLanguage)();
|
|
1310
1404
|
const t = getOsToolMessages(language);
|
|
1311
|
-
const { pid } = parseStopDaemonArgs(args);
|
|
1405
|
+
const { pid, entirePg } = parseStopDaemonArgs(args);
|
|
1312
1406
|
const daemon = daemonProcesses.get(pid);
|
|
1313
1407
|
if (!daemon) {
|
|
1314
1408
|
return t.noDaemonFound(pid);
|
|
1315
1409
|
}
|
|
1316
1410
|
try {
|
|
1317
|
-
|
|
1318
|
-
|
|
1411
|
+
let signalTarget = pid;
|
|
1412
|
+
if (entirePg) {
|
|
1413
|
+
if (daemon.processGroupId === undefined) {
|
|
1414
|
+
throw new Error('daemon has no isolated process group; rerun it after this update, or retry with entire_pg=false');
|
|
1415
|
+
}
|
|
1416
|
+
signalTarget = -daemon.processGroupId;
|
|
1417
|
+
}
|
|
1418
|
+
// Kill the tracked process or its entire process group.
|
|
1419
|
+
process.kill(signalTarget, 'SIGTERM');
|
|
1319
1420
|
// Wait a bit for graceful shutdown
|
|
1320
1421
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
1321
1422
|
// Force kill if still running
|
|
1322
1423
|
try {
|
|
1323
|
-
process.kill(
|
|
1424
|
+
process.kill(signalTarget, 'SIGKILL');
|
|
1324
1425
|
}
|
|
1325
1426
|
catch (e) {
|
|
1326
1427
|
// Process already terminated
|
|
@@ -22,19 +22,42 @@ function isPendingTellaskReminderMeta(value) {
|
|
|
22
22
|
return false;
|
|
23
23
|
return true;
|
|
24
24
|
}
|
|
25
|
-
function
|
|
25
|
+
function callKindLabel(language, view) {
|
|
26
|
+
if (view.callType === 'A') {
|
|
27
|
+
return language === 'zh' ? '回问诉请' : 'TellaskBack';
|
|
28
|
+
}
|
|
26
29
|
if (language === 'zh') {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
switch (view.callName) {
|
|
31
|
+
case 'tellask':
|
|
32
|
+
return '长线诉请';
|
|
33
|
+
case 'tellaskSessionless':
|
|
34
|
+
return '一次性诉请';
|
|
35
|
+
case 'freshBootsReasoning':
|
|
36
|
+
return '扪心自问(FBR)';
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
switch (view.callName) {
|
|
40
|
+
case 'tellask':
|
|
41
|
+
return 'Tellask Session';
|
|
42
|
+
case 'tellaskSessionless':
|
|
43
|
+
return 'Fresh Tellask';
|
|
44
|
+
case 'freshBootsReasoning':
|
|
45
|
+
return 'Fresh Boots Reasoning (FBR)';
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function pendingTargetLabel(language, view) {
|
|
49
|
+
if (view.callType === 'A') {
|
|
50
|
+
return language === 'zh'
|
|
51
|
+
? `上游诉请者 @${view.targetAgentId}`
|
|
52
|
+
: `upstream requester @${view.targetAgentId}`;
|
|
53
|
+
}
|
|
54
|
+
switch (view.callName) {
|
|
55
|
+
case 'freshBootsReasoning':
|
|
56
|
+
return language === 'zh' ? '本对话自身' : 'this dialog itself';
|
|
57
|
+
case 'tellask':
|
|
58
|
+
case 'tellaskSessionless':
|
|
59
|
+
return `@${view.targetAgentId}`;
|
|
32
60
|
}
|
|
33
|
-
if (callType === 'A')
|
|
34
|
-
return 'TellaskBack';
|
|
35
|
-
if (callType === 'B')
|
|
36
|
-
return 'Tellask Session';
|
|
37
|
-
return 'Fresh Tellask';
|
|
38
61
|
}
|
|
39
62
|
function summarizeTellask(view) {
|
|
40
63
|
const mentionPrefix = Array.isArray(view.mentionList) ? view.mentionList.join(' ') : '';
|
|
@@ -75,8 +98,8 @@ function buildReminderContent(language, pending) {
|
|
|
75
98
|
: 'Only the Tellasks listed below are still in flight; besides them, no other Tellasks are currently executing. This reminder is auto-added/refreshed and not auto-deleted.';
|
|
76
99
|
const lines = pending.map((p, idx) => {
|
|
77
100
|
const base = language === 'zh'
|
|
78
|
-
? `${idx + 1}.
|
|
79
|
-
: `${idx + 1}.
|
|
101
|
+
? `${idx + 1}. ${pendingTargetLabel(language, p)} | ${callKindLabel(language, p)} | ${summarizeTellask(p)}`
|
|
102
|
+
: `${idx + 1}. ${pendingTargetLabel(language, p)} | ${callKindLabel(language, p)} | ${summarizeTellask(p)}`;
|
|
80
103
|
if (!p.sessionSlug)
|
|
81
104
|
return base;
|
|
82
105
|
return language === 'zh'
|
package/dist/tools/plan.js
CHANGED
|
@@ -130,10 +130,11 @@ exports.updatePlanTool = {
|
|
|
130
130
|
kind: 'plan',
|
|
131
131
|
schemaVersion: 1,
|
|
132
132
|
updatedAt: now,
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
133
|
+
manager: {
|
|
134
|
+
tool: 'update_plan',
|
|
135
|
+
},
|
|
136
|
+
update: {
|
|
137
|
+
altInstruction: 'update_plan({ "plan": [ { "step": "...", "status": "in_progress" } ] })',
|
|
137
138
|
},
|
|
138
139
|
};
|
|
139
140
|
let existingIndex;
|
|
@@ -48,6 +48,7 @@ Stop daemon process.
|
|
|
48
48
|
**Parameters:**
|
|
49
49
|
|
|
50
50
|
- `pid` (required): Daemon process ID (number)
|
|
51
|
+
- `entire_pg` (optional): Whether to signal the entire process group (default: `true` on Unix-like systems, `false` on Windows; Windows does not support explicitly passing `true`)
|
|
51
52
|
|
|
52
53
|
**Returns:**
|
|
53
54
|
|
|
@@ -151,6 +152,12 @@ shell_cmd({
|
|
|
151
152
|
stop_daemon({
|
|
152
153
|
pid: 12345,
|
|
153
154
|
});
|
|
155
|
+
|
|
156
|
+
// On Unix-like systems, you can explicitly terminate the whole process group
|
|
157
|
+
stop_daemon({
|
|
158
|
+
pid: 12345,
|
|
159
|
+
entire_pg: true,
|
|
160
|
+
});
|
|
154
161
|
```
|
|
155
162
|
|
|
156
163
|
### Get Daemon Process Output
|
|
@@ -48,6 +48,7 @@ executed_at: <执行时间戳>
|
|
|
48
48
|
**参数:**
|
|
49
49
|
|
|
50
50
|
- `pid`(必需):守护进程 PID(数字)
|
|
51
|
+
- `entire_pg`(可选):是否对整个进程组发终止信号(默认:Linux/macOS 为 `true`,Windows 为 `false`;Windows 不支持显式传 `true`)
|
|
51
52
|
|
|
52
53
|
**返回:**
|
|
53
54
|
|
|
@@ -151,6 +152,12 @@ shell_cmd({
|
|
|
151
152
|
stop_daemon({
|
|
152
153
|
pid: 12345,
|
|
153
154
|
});
|
|
155
|
+
|
|
156
|
+
// Unix-like 平台可显式要求终止整个进程组
|
|
157
|
+
stop_daemon({
|
|
158
|
+
pid: 12345,
|
|
159
|
+
entire_pg: true,
|
|
160
|
+
});
|
|
154
161
|
```
|
|
155
162
|
|
|
156
163
|
### 获取守护进程输出
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
team_mgmt is Dominds' toolset for managing `.minds/` (team configuration and rtws memory), using **prepare-first + single apply** architecture:
|
|
28
28
|
|
|
29
29
|
- **Incremental edits (preferred)**: Use `team_mgmt_prepare_*` to generate reviewable YAML + diff + `hunk_id`, then write via `team_mgmt_apply_file_modification`
|
|
30
|
+
- **Hard ordering rule for the LLM**: `team_mgmt_prepare_*` only creates an in-memory preview and does not write the file; before `apply`, re-reading still returns the old content. If you want further edits based on the prepared result, you must call `team_mgmt_apply_file_modification` first, then read/prepare the next change
|
|
30
31
|
- **Only operates in `.minds/`**: This toolset only operates within the `.minds/` subtree and should not touch other rtws files
|
|
31
32
|
- **Shell guardrail**: toolset `os` includes `shell_cmd` / `stop_daemon` / `get_daemon_output`; any member with these shell tools must be listed in top-level `shell_specialists`
|
|
32
33
|
- **Member assets recommended**: strongly recommend `persona/knowledge/lessons` files for every `members.<id>` to define ownership, boundaries, and reusable lessons
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
|
|
28
28
|
- **Incremental edits (preferred)**: Use `team_mgmt_prepare_*` to generate reviewable YAML + diff + `hunk_id`, then write via `team_mgmt_apply_file_modification({ "hunk_id": "<hunk_id>" })`
|
|
29
29
|
- **Parallelism constraint**: Multiple function tool calls in one generation step may run in parallel; **prepare → apply must be two steps**
|
|
30
|
+
- **LLM persistence semantics**: `team_mgmt_prepare_*` only stores a pending in-memory preview and does not modify the file before apply; a `team_mgmt_read_file` before apply still returns the old content. If you only want to revise that pending preview, overwrite the same hunk with `existing_hunk_id`; if you want the next edit based on this change, apply the current hunk first, then read/prepare again
|
|
30
31
|
- **Minimum shell privilege**: toolset `os` includes `shell_cmd` / `stop_daemon` / `get_daemon_output`; grant it only to a small specialist set and list those member ids in top-level `shell_specialists`
|
|
31
32
|
- **Exception (create)**: `team_mgmt_create_new_file` only creates a new file (empty content allowed). It does not do incremental edits and does not use prepare/apply; it refuses to overwrite existing files
|
|
32
33
|
- **Exception (overwrite)**: `team_mgmt_overwrite_entire_file` writes immediately (no prepare/apply). It requires `known_old_total_lines/known_old_total_bytes` guardrails; use `team_mgmt_read_file` to read `total_lines/size_bytes` from the YAML header
|
|
@@ -52,6 +52,8 @@ Call the function tool `team_mgmt_apply_file_modification` with:
|
|
|
52
52
|
{ "hunk_id": "<hunk_id>" }
|
|
53
53
|
```
|
|
54
54
|
|
|
55
|
+
Important: before this apply, the prepared diff is not persisted yet; re-reading the file still returns the old content. If you want the next edit based on this change, apply the current hunk first, then prepare the next one.
|
|
56
|
+
|
|
55
57
|
### 4. Create New Mind File
|
|
56
58
|
|
|
57
59
|
```text
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
team_mgmt 是 Dominds 用于管理 `.minds/`(团队配置与 rtws 记忆)的工具集,采用 **prepare-first + single apply** 架构:
|
|
28
28
|
|
|
29
29
|
- **增量编辑(推荐)**:用 `team_mgmt_prepare_*` 先生成可复核的 YAML + diff + `hunk_id`,再用 `team_mgmt_apply_file_modification` 显式写入
|
|
30
|
+
- **LLM 顺序硬约束**:`team_mgmt_prepare_*` 只生成内存中的预览,不会写盘;在 `apply` 之前再次读取文件仍只能读到旧内容。若要基于本次改动继续修改,必须先 `team_mgmt_apply_file_modification`,再重新 read/prepare 新改动
|
|
30
31
|
- **只操作 `.minds/`**:该 toolset 只允许操作 `.minds/` 子树,不会也不应触碰 rtws 其他文件
|
|
31
32
|
- **shell 权限约束**:`os` toolset 包含 `shell_cmd` / `stop_daemon` / `get_daemon_output`;任何拿到这些工具的成员都必须出现在顶层 `shell_specialists`
|
|
32
33
|
- **成员资产推荐**:强烈建议为每个 `members.<id>` 配置 `persona/knowledge/lessons` 资产文件,显式定义角色职责、边界和经验复用
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
|
|
28
28
|
- **增量编辑(推荐)**:用 `team_mgmt_prepare_*` 先生成可复核的 YAML + diff + `hunk_id`,再用 `team_mgmt_apply_file_modification({ "hunk_id": "<hunk_id>" })` 显式写入
|
|
29
29
|
- **并行约束**:同一轮生成中的多个工具调用可能并行执行;**prepare → apply 必须分两轮**
|
|
30
|
+
- **LLM 落盘语义**:`team_mgmt_prepare_*` 只保存待应用的内存预览,apply 前不会改动文件;此时再次 `team_mgmt_read_file` 看到的仍是旧内容。若只是修订同一个未落盘预览,可用同一 prepare 工具加 `existing_hunk_id` 覆写;若想继续下一笔修改,必须先 apply 当前 hunk,再重新 read/prepare
|
|
30
31
|
- **shell 最小授权**:`os` toolset 包含 `shell_cmd` / `stop_daemon` / `get_daemon_output`;只授予少数专员成员,并在顶层 `shell_specialists` 显式列出这些成员 id
|
|
31
32
|
- **例外(创建)**:`team_mgmt_create_new_file` 只负责创建新文件(允许空内容),不做增量编辑、不走 prepare/apply;若文件已存在会拒绝(避免误用覆盖写入语义)
|
|
32
33
|
- **例外(整文件覆盖)**:`team_mgmt_overwrite_entire_file` 会直接写盘(不走 prepare/apply),必须提供 `known_old_total_lines/known_old_total_bytes` 作为对账护栏;建议先用 `team_mgmt_read_file` 从 YAML header 读取 `total_lines/size_bytes` 再填写
|
|
@@ -28,6 +28,7 @@ ws_mod is Dominds' text editing toolset, using **prepare-first + single apply**
|
|
|
28
28
|
|
|
29
29
|
- **prepare-first**: All incremental edits are planned first (output reviewable diff + evidence + hunk_id)
|
|
30
30
|
- **single apply**: All planned edits are persisted only through `apply_file_modification`
|
|
31
|
+
- **Hard ordering rule for the LLM**: Before apply, a prepared hunk exists only in memory; re-reading still returns the old file content. If you want further edits based on that prepared result, apply the current hunk first, then prepare again
|
|
31
32
|
- **Legacy tools removed**: `append_file` / `insert_after` / `insert_before` / `replace_block` / `apply_block_replace` are completely removed
|
|
32
33
|
|
|
33
34
|
## Quick Navigation
|
|
@@ -35,6 +35,7 @@ Therefore unified to:
|
|
|
35
35
|
|
|
36
36
|
- **prepare-first**: All incremental edits are planned first (output reviewable diff + evidence + hunk_id)
|
|
37
37
|
- **single apply**: All planned edits are persisted only through `apply_file_modification({ "hunk_id": "<hunk_id>" })`
|
|
38
|
+
- **LLM persistence semantics**: before apply, a prepared hunk exists only in memory and does not modify the file; a `read_file` at that point still returns the old content. If you only want to revise the same pending preview, overwrite it with the same prepare tool plus `existing_hunk_id`; if you want the next edit based on this change, apply the current hunk first, then read/prepare again
|
|
38
39
|
- **Legacy tools removed**: `append_file` / `insert_after` / `insert_before` / `replace_block` / `apply_block_replace` are completely removed (no aliases, no compat layer)
|
|
39
40
|
|
|
40
41
|
## 2. Goals & Non-Goals
|
|
@@ -28,6 +28,7 @@ ws_mod 是 Dominds 的文本编辑工具集,采用 **prepare-first + single ap
|
|
|
28
28
|
|
|
29
29
|
- **prepare-first**:所有增量编辑先规划(输出可审阅 diff + evidence + hunk_id)
|
|
30
30
|
- **single apply**:所有计划类编辑仅通过 `apply_file_modification` 落盘
|
|
31
|
+
- **LLM 顺序硬约束**:prepare 结果在 apply 前只存在于内存里;此时再次读取文件仍只能读到旧内容。若要基于该结果继续修改,必须先 apply 当前 hunk,再重新 prepare
|
|
31
32
|
- **移除旧工具**:`append_file` / `insert_after` / `insert_before` / `replace_block` / `apply_block_replace` 已彻底删除
|
|
32
33
|
|
|
33
34
|
## 快速导航
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
|
|
36
36
|
- **prepare-first**:所有增量编辑先规划(输出可审阅 diff + evidence + hunk_id)
|
|
37
37
|
- **single apply**:所有计划类编辑仅通过 `apply_file_modification({ "hunk_id": "<hunk_id>" })` 落盘
|
|
38
|
+
- **LLM 落盘语义**:prepare 结果在 apply 前只保存在内存中,不会改动文件;此时再次 `read_file` 看到的仍是旧内容。若只是修订同一个未落盘预览,可用同一 prepare 工具加 `existing_hunk_id` 覆写;若想继续下一笔修改,必须先 apply 当前 hunk,再重新 read/prepare
|
|
38
39
|
- **移除旧工具**:`append_file` / `insert_after` / `insert_before` / `replace_block` / `apply_block_replace` 已彻底删除(无 alias、无兼容层)
|
|
39
40
|
|
|
40
41
|
## 2. 目标与非目标
|
|
@@ -5,6 +5,7 @@ You have read/write access to the rtws (runtime workspace), but **all incrementa
|
|
|
5
5
|
## Principles
|
|
6
6
|
|
|
7
7
|
- Incremental edits: use `prepare_*` to generate an applyable hunk, then write via `apply_file_modification`.
|
|
8
|
+
- Hard ordering rule for the LLM: `prepare_*` only creates an in-memory preview and does not write the file; before `apply_file_modification`, re-reading still returns the old content. If you want further edits based on the prepared result, you must apply the current hunk first, then read/prepare the next change.
|
|
8
9
|
- Legacy tools are removed (no compatibility layer): `append_file` / `insert_after` / `insert_before` / `replace_block` / `apply_block_replace`.
|
|
9
10
|
- Constraint: paths under `*.tsk/` are encapsulated Taskdocs; file tools cannot access them.
|
|
10
11
|
- Parallelism constraint: multiple function tool calls in one generation step may run in parallel; **prepare → apply must be two steps**.
|
|
@@ -35,6 +36,7 @@ You have read/write access to the rtws (runtime workspace), but **all incrementa
|
|
|
35
36
|
- `prepare_*` generates `hunk_id` (TTL = 1 hour); apply can only use an unexpired hunk.
|
|
36
37
|
- Expired/unused hunks have no side effects; they are cleaned up automatically.
|
|
37
38
|
- Some prepare tools accept `existing_hunk_id` to overwrite the same prepared hunk; **custom new ids are not supported**.
|
|
39
|
+
- If you only want to revise the same not-yet-persisted preview, overwrite that hunk with the same prepare tool plus `existing_hunk_id`; if you want the next edit based on this change, apply the current hunk first, then prepare again.
|
|
38
40
|
|
|
39
41
|
## Apply semantics (context_match)
|
|
40
42
|
|
|
@@ -58,6 +60,8 @@ Call the function tool `apply_file_modification` with:
|
|
|
58
60
|
{ "hunk_id": "<hunk_id>" }
|
|
59
61
|
```
|
|
60
62
|
|
|
63
|
+
Before this step, the prepared diff is not persisted yet; a `read_file` at that point still returns the old content.
|
|
64
|
+
|
|
61
65
|
## Examples
|
|
62
66
|
|
|
63
67
|
- Append to EOF:
|