dominds 1.25.13 → 1.25.15

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.
Files changed (119) hide show
  1. package/dist/dialog-display-state.d.ts +4 -2
  2. package/dist/dialog-display-state.js +26 -6
  3. package/dist/llm/kernel-driver/drive.js +15 -0
  4. package/dist/llm/kernel-driver/flow.js +3 -0
  5. package/dist/llm/kernel-driver/sideDialog.js +1 -9
  6. package/dist/mcp/supervisor.js +2 -4
  7. package/dist/minds/system-prompt.js +4 -4
  8. package/dist/runtime/driver-messages.d.ts +5 -0
  9. package/dist/runtime/driver-messages.js +103 -59
  10. package/dist/server/api-routes.js +5 -8
  11. package/dist/server/dominds-self-update.js +584 -106
  12. package/dist/server/websocket-handler.js +5 -15
  13. package/dist/tools/app-reminders.js +6 -6
  14. package/dist/tools/cmd-runner-protocol.d.ts +1 -0
  15. package/dist/tools/cmd-runner-protocol.js +8 -1
  16. package/dist/tools/cmd-runner.js +33 -6
  17. package/dist/tools/mcp.js +2 -8
  18. package/dist/tools/os.js +27 -22
  19. package/dist/tools/pending-tellask-reminder.js +10 -10
  20. package/dist/tools/process-kill.d.ts +4 -0
  21. package/dist/tools/process-kill.js +48 -0
  22. package/dist/tools/prompts/os/en/tools.md +2 -2
  23. package/dist/tools/prompts/os/zh/tools.md +2 -2
  24. package/package.json +4 -4
  25. package/webapp/dist/assets/{_basePickBy-B1-brAPU.js → _basePickBy-bB-pfQPi.js} +3 -3
  26. package/webapp/dist/assets/{_basePickBy-B1-brAPU.js.map → _basePickBy-bB-pfQPi.js.map} +1 -1
  27. package/webapp/dist/assets/{_baseUniq-BuB0jmKD.js → _baseUniq-CGrWBZre.js} +2 -2
  28. package/webapp/dist/assets/{_baseUniq-BuB0jmKD.js.map → _baseUniq-CGrWBZre.js.map} +1 -1
  29. package/webapp/dist/assets/{arc-CvsBvjnB.js → arc-I9vbIaKk.js} +2 -2
  30. package/webapp/dist/assets/{arc-CvsBvjnB.js.map → arc-I9vbIaKk.js.map} +1 -1
  31. package/webapp/dist/assets/{architectureDiagram-2XIMDMQ5-B-xGuLbb.js → architectureDiagram-2XIMDMQ5-CrwjTxLz.js} +7 -7
  32. package/webapp/dist/assets/{architectureDiagram-2XIMDMQ5-B-xGuLbb.js.map → architectureDiagram-2XIMDMQ5-CrwjTxLz.js.map} +1 -1
  33. package/webapp/dist/assets/{blockDiagram-WCTKOSBZ-Bu53fwsa.js → blockDiagram-WCTKOSBZ-DTm0qfvP.js} +7 -7
  34. package/webapp/dist/assets/{blockDiagram-WCTKOSBZ-Bu53fwsa.js.map → blockDiagram-WCTKOSBZ-DTm0qfvP.js.map} +1 -1
  35. package/webapp/dist/assets/{c4Diagram-IC4MRINW-D9-FJ4LB.js → c4Diagram-IC4MRINW-DwRQtzZF.js} +3 -3
  36. package/webapp/dist/assets/{c4Diagram-IC4MRINW-D9-FJ4LB.js.map → c4Diagram-IC4MRINW-DwRQtzZF.js.map} +1 -1
  37. package/webapp/dist/assets/{channel-D1VPurpu.js → channel-BHLOwBnI.js} +2 -2
  38. package/webapp/dist/assets/{channel-D1VPurpu.js.map → channel-BHLOwBnI.js.map} +1 -1
  39. package/webapp/dist/assets/{chunk-4BX2VUAB-DB14wcWS.js → chunk-4BX2VUAB-C-uXnDVV.js} +2 -2
  40. package/webapp/dist/assets/{chunk-4BX2VUAB-DB14wcWS.js.map → chunk-4BX2VUAB-C-uXnDVV.js.map} +1 -1
  41. package/webapp/dist/assets/{chunk-55IACEB6-C5KCE85A.js → chunk-55IACEB6-Dq9BI2N6.js} +2 -2
  42. package/webapp/dist/assets/{chunk-55IACEB6-C5KCE85A.js.map → chunk-55IACEB6-Dq9BI2N6.js.map} +1 -1
  43. package/webapp/dist/assets/{chunk-FMBD7UC4-Bb6zm0iH.js → chunk-FMBD7UC4-DR9kFZOV.js} +2 -2
  44. package/webapp/dist/assets/{chunk-FMBD7UC4-Bb6zm0iH.js.map → chunk-FMBD7UC4-DR9kFZOV.js.map} +1 -1
  45. package/webapp/dist/assets/{chunk-JSJVCQXG-CJPrv6fM.js → chunk-JSJVCQXG-xnc6SVE5.js} +2 -2
  46. package/webapp/dist/assets/{chunk-JSJVCQXG-CJPrv6fM.js.map → chunk-JSJVCQXG-xnc6SVE5.js.map} +1 -1
  47. package/webapp/dist/assets/{chunk-KX2RTZJC-8J1Swk7E.js → chunk-KX2RTZJC-rUxlh4aS.js} +2 -2
  48. package/webapp/dist/assets/{chunk-KX2RTZJC-8J1Swk7E.js.map → chunk-KX2RTZJC-rUxlh4aS.js.map} +1 -1
  49. package/webapp/dist/assets/{chunk-NQ4KR5QH-DySHY4x9.js → chunk-NQ4KR5QH-BGU4PhTQ.js} +4 -4
  50. package/webapp/dist/assets/{chunk-NQ4KR5QH-DySHY4x9.js.map → chunk-NQ4KR5QH-BGU4PhTQ.js.map} +1 -1
  51. package/webapp/dist/assets/{chunk-QZHKN3VN-CTO5Z-4P.js → chunk-QZHKN3VN-CAlu4xE7.js} +2 -2
  52. package/webapp/dist/assets/{chunk-QZHKN3VN-CTO5Z-4P.js.map → chunk-QZHKN3VN-CAlu4xE7.js.map} +1 -1
  53. package/webapp/dist/assets/{chunk-WL4C6EOR-Ci_Ec8Ax.js → chunk-WL4C6EOR-zZXRkBBY.js} +6 -6
  54. package/webapp/dist/assets/{chunk-WL4C6EOR-Ci_Ec8Ax.js.map → chunk-WL4C6EOR-zZXRkBBY.js.map} +1 -1
  55. package/webapp/dist/assets/{classDiagram-VBA2DB6C-CxAxBvv7.js → classDiagram-VBA2DB6C-DI1CfOtL.js} +7 -7
  56. package/webapp/dist/assets/{classDiagram-VBA2DB6C-CxAxBvv7.js.map → classDiagram-VBA2DB6C-DI1CfOtL.js.map} +1 -1
  57. package/webapp/dist/assets/{classDiagram-v2-RAHNMMFH-CxAxBvv7.js → classDiagram-v2-RAHNMMFH-DI1CfOtL.js} +7 -7
  58. package/webapp/dist/assets/{classDiagram-v2-RAHNMMFH-CxAxBvv7.js.map → classDiagram-v2-RAHNMMFH-DI1CfOtL.js.map} +1 -1
  59. package/webapp/dist/assets/{clone-ePiNaiNY.js → clone-quTqCNPA.js} +2 -2
  60. package/webapp/dist/assets/{clone-ePiNaiNY.js.map → clone-quTqCNPA.js.map} +1 -1
  61. package/webapp/dist/assets/{cose-bilkent-S5V4N54A-j-Ex-Sef.js → cose-bilkent-S5V4N54A-BY28yO7Y.js} +2 -2
  62. package/webapp/dist/assets/{cose-bilkent-S5V4N54A-j-Ex-Sef.js.map → cose-bilkent-S5V4N54A-BY28yO7Y.js.map} +1 -1
  63. package/webapp/dist/assets/{dagre-KLK3FWXG-ihZ2wOCM.js → dagre-KLK3FWXG-DLyZ54D-.js} +7 -7
  64. package/webapp/dist/assets/{dagre-KLK3FWXG-ihZ2wOCM.js.map → dagre-KLK3FWXG-DLyZ54D-.js.map} +1 -1
  65. package/webapp/dist/assets/{diagram-E7M64L7V-Cp4GQGS7.js → diagram-E7M64L7V-CD-HWZAJ.js} +8 -8
  66. package/webapp/dist/assets/{diagram-E7M64L7V-Cp4GQGS7.js.map → diagram-E7M64L7V-CD-HWZAJ.js.map} +1 -1
  67. package/webapp/dist/assets/{diagram-IFDJBPK2-B70cgyS5.js → diagram-IFDJBPK2-BHOQ9HH2.js} +7 -7
  68. package/webapp/dist/assets/{diagram-IFDJBPK2-B70cgyS5.js.map → diagram-IFDJBPK2-BHOQ9HH2.js.map} +1 -1
  69. package/webapp/dist/assets/{diagram-P4PSJMXO-DMOv7eKE.js → diagram-P4PSJMXO-OEPgBDcD.js} +7 -7
  70. package/webapp/dist/assets/{diagram-P4PSJMXO-DMOv7eKE.js.map → diagram-P4PSJMXO-OEPgBDcD.js.map} +1 -1
  71. package/webapp/dist/assets/{erDiagram-INFDFZHY-BKpXWjIc.js → erDiagram-INFDFZHY-Dcgo204J.js} +5 -5
  72. package/webapp/dist/assets/{erDiagram-INFDFZHY-BKpXWjIc.js.map → erDiagram-INFDFZHY-Dcgo204J.js.map} +1 -1
  73. package/webapp/dist/assets/{flowDiagram-PKNHOUZH-DgrItj0h.js → flowDiagram-PKNHOUZH-CWLo3Lkf.js} +7 -7
  74. package/webapp/dist/assets/{flowDiagram-PKNHOUZH-DgrItj0h.js.map → flowDiagram-PKNHOUZH-CWLo3Lkf.js.map} +1 -1
  75. package/webapp/dist/assets/{ganttDiagram-A5KZAMGK-7-8hlYsT.js → ganttDiagram-A5KZAMGK-DWXL4ZD6.js} +3 -3
  76. package/webapp/dist/assets/{ganttDiagram-A5KZAMGK-7-8hlYsT.js.map → ganttDiagram-A5KZAMGK-DWXL4ZD6.js.map} +1 -1
  77. package/webapp/dist/assets/{gitGraphDiagram-K3NZZRJ6-cPSaCUUk.js → gitGraphDiagram-K3NZZRJ6-7iLQbTrH.js} +8 -8
  78. package/webapp/dist/assets/{gitGraphDiagram-K3NZZRJ6-cPSaCUUk.js.map → gitGraphDiagram-K3NZZRJ6-7iLQbTrH.js.map} +1 -1
  79. package/webapp/dist/assets/{graph-CAlg3tEk.js → graph-Bq1MLNWN.js} +3 -3
  80. package/webapp/dist/assets/{graph-CAlg3tEk.js.map → graph-Bq1MLNWN.js.map} +1 -1
  81. package/webapp/dist/assets/{index-DLTS_eOh.js → index-r4An5YoX.js} +245 -60
  82. package/webapp/dist/assets/{index-DLTS_eOh.js.map → index-r4An5YoX.js.map} +1 -1
  83. package/webapp/dist/assets/{infoDiagram-LFFYTUFH-CHJHvxMC.js → infoDiagram-LFFYTUFH-CoF5OE3_.js} +6 -6
  84. package/webapp/dist/assets/{infoDiagram-LFFYTUFH-CHJHvxMC.js.map → infoDiagram-LFFYTUFH-CoF5OE3_.js.map} +1 -1
  85. package/webapp/dist/assets/{ishikawaDiagram-PHBUUO56-S8N-XZ8E.js → ishikawaDiagram-PHBUUO56-iKggfQhA.js} +2 -2
  86. package/webapp/dist/assets/{ishikawaDiagram-PHBUUO56-S8N-XZ8E.js.map → ishikawaDiagram-PHBUUO56-iKggfQhA.js.map} +1 -1
  87. package/webapp/dist/assets/{journeyDiagram-4ABVD52K-ChHNpMtH.js → journeyDiagram-4ABVD52K-NYDQ7_xv.js} +5 -5
  88. package/webapp/dist/assets/{journeyDiagram-4ABVD52K-ChHNpMtH.js.map → journeyDiagram-4ABVD52K-NYDQ7_xv.js.map} +1 -1
  89. package/webapp/dist/assets/{kanban-definition-K7BYSVSG-Cqxd99wZ.js → kanban-definition-K7BYSVSG-YWCnJwk0.js} +3 -3
  90. package/webapp/dist/assets/{kanban-definition-K7BYSVSG-Cqxd99wZ.js.map → kanban-definition-K7BYSVSG-YWCnJwk0.js.map} +1 -1
  91. package/webapp/dist/assets/{layout-uOLcVthp.js → layout-CE6gccWy.js} +5 -5
  92. package/webapp/dist/assets/{layout-uOLcVthp.js.map → layout-CE6gccWy.js.map} +1 -1
  93. package/webapp/dist/assets/{linear-Ga_f4H_w.js → linear-12arIJK-.js} +2 -2
  94. package/webapp/dist/assets/{linear-Ga_f4H_w.js.map → linear-12arIJK-.js.map} +1 -1
  95. package/webapp/dist/assets/{mindmap-definition-YRQLILUH-TSH7wOlZ.js → mindmap-definition-YRQLILUH-D_5iNhfP.js} +4 -4
  96. package/webapp/dist/assets/{mindmap-definition-YRQLILUH-TSH7wOlZ.js.map → mindmap-definition-YRQLILUH-D_5iNhfP.js.map} +1 -1
  97. package/webapp/dist/assets/{pieDiagram-SKSYHLDU-DPXszqns.js → pieDiagram-SKSYHLDU-DCbLQaXM.js} +8 -8
  98. package/webapp/dist/assets/{pieDiagram-SKSYHLDU-DPXszqns.js.map → pieDiagram-SKSYHLDU-DCbLQaXM.js.map} +1 -1
  99. package/webapp/dist/assets/{quadrantDiagram-337W2JSQ-BgA_GVhR.js → quadrantDiagram-337W2JSQ-CVRDOyty.js} +3 -3
  100. package/webapp/dist/assets/{quadrantDiagram-337W2JSQ-BgA_GVhR.js.map → quadrantDiagram-337W2JSQ-CVRDOyty.js.map} +1 -1
  101. package/webapp/dist/assets/{requirementDiagram-Z7DCOOCP-CM-47daj.js → requirementDiagram-Z7DCOOCP-iBpmayOS.js} +4 -4
  102. package/webapp/dist/assets/{requirementDiagram-Z7DCOOCP-CM-47daj.js.map → requirementDiagram-Z7DCOOCP-iBpmayOS.js.map} +1 -1
  103. package/webapp/dist/assets/{sankeyDiagram-WA2Y5GQK-CxDCwHAj.js → sankeyDiagram-WA2Y5GQK-DqzWCtib.js} +2 -2
  104. package/webapp/dist/assets/{sankeyDiagram-WA2Y5GQK-CxDCwHAj.js.map → sankeyDiagram-WA2Y5GQK-DqzWCtib.js.map} +1 -1
  105. package/webapp/dist/assets/{sequenceDiagram-2WXFIKYE-1UJP6Fff.js → sequenceDiagram-2WXFIKYE-DHzt-u2j.js} +4 -4
  106. package/webapp/dist/assets/{sequenceDiagram-2WXFIKYE-1UJP6Fff.js.map → sequenceDiagram-2WXFIKYE-DHzt-u2j.js.map} +1 -1
  107. package/webapp/dist/assets/{stateDiagram-RAJIS63D-B2aqr0KQ.js → stateDiagram-RAJIS63D-D14FagfU.js} +9 -9
  108. package/webapp/dist/assets/{stateDiagram-RAJIS63D-B2aqr0KQ.js.map → stateDiagram-RAJIS63D-D14FagfU.js.map} +1 -1
  109. package/webapp/dist/assets/{stateDiagram-v2-FVOUBMTO-DvmkevVb.js → stateDiagram-v2-FVOUBMTO-CZRolF-A.js} +5 -5
  110. package/webapp/dist/assets/{stateDiagram-v2-FVOUBMTO-DvmkevVb.js.map → stateDiagram-v2-FVOUBMTO-CZRolF-A.js.map} +1 -1
  111. package/webapp/dist/assets/{timeline-definition-YZTLITO2-CaOrqzT1.js → timeline-definition-YZTLITO2-L4O4kc8p.js} +3 -3
  112. package/webapp/dist/assets/{timeline-definition-YZTLITO2-CaOrqzT1.js.map → timeline-definition-YZTLITO2-L4O4kc8p.js.map} +1 -1
  113. package/webapp/dist/assets/{treemap-KZPCXAKY-CWs_8GJm.js → treemap-KZPCXAKY-CvHKWhtl.js} +5 -5
  114. package/webapp/dist/assets/{treemap-KZPCXAKY-CWs_8GJm.js.map → treemap-KZPCXAKY-CvHKWhtl.js.map} +1 -1
  115. package/webapp/dist/assets/{vennDiagram-LZ73GAT5-BuBxFDz6.js → vennDiagram-LZ73GAT5-8sPBS5jq.js} +2 -2
  116. package/webapp/dist/assets/{vennDiagram-LZ73GAT5-BuBxFDz6.js.map → vennDiagram-LZ73GAT5-8sPBS5jq.js.map} +1 -1
  117. package/webapp/dist/assets/{xychartDiagram-JWTSCODW-ChjL-_2b.js → xychartDiagram-JWTSCODW-CqLmOgCw.js} +3 -3
  118. package/webapp/dist/assets/{xychartDiagram-JWTSCODW-ChjL-_2b.js.map → xychartDiagram-JWTSCODW-CqLmOgCw.js.map} +1 -1
  119. package/webapp/dist/index.html +1 -1
@@ -1908,14 +1908,9 @@ function setupWebSocketServer(httpServer, clients, auth, serverWorkLanguage, mod
1908
1908
  if (msg.fromStatus !== 'running') {
1909
1909
  return;
1910
1910
  }
1911
- void (0, dialog_display_state_1.getRunControlCountsSnapshot)()
1912
- .then((counts) => {
1913
- broadcastToClients({
1914
- type: 'run_control_counts_evt',
1915
- proceeding: counts.proceeding,
1916
- resumable: counts.resumable,
1917
- timestamp: (0, time_1.formatUnifiedTimestamp)(new Date()),
1918
- });
1911
+ void (0, dialog_display_state_1.createRunControlCountsMessage)()
1912
+ .then((message) => {
1913
+ broadcastToClients(message);
1919
1914
  })
1920
1915
  .catch((error) => {
1921
1916
  log.warn('Failed to broadcast run-control counts after dialog quarantine', error, {
@@ -1977,6 +1972,7 @@ function setupWebSocketServer(httpServer, clients, auth, serverWorkLanguage, mod
1977
1972
  message: 'Connected to dialog server',
1978
1973
  serverWorkLanguage,
1979
1974
  supportedLanguageCodes: [...language_1.supportedLanguageCodes],
1975
+ runControlCountsSnapshotEpoch: (0, dialog_display_state_1.getRunControlCountsSnapshotEpoch)(),
1980
1976
  runtimeStatus,
1981
1977
  timestamp: (0, time_1.formatUnifiedTimestamp)(new Date()),
1982
1978
  }));
@@ -2005,13 +2001,7 @@ function setupWebSocketServer(httpServer, clients, auth, serverWorkLanguage, mod
2005
2001
  }
2006
2002
  })();
2007
2003
  try {
2008
- const counts = await (0, dialog_display_state_1.getRunControlCountsSnapshot)();
2009
- ws.send(JSON.stringify({
2010
- type: 'run_control_counts_evt',
2011
- proceeding: counts.proceeding,
2012
- resumable: counts.resumable,
2013
- timestamp: (0, time_1.formatUnifiedTimestamp)(new Date()),
2014
- }));
2004
+ ws.send(JSON.stringify(await (0, dialog_display_state_1.createRunControlCountsMessage)()));
2015
2005
  }
2016
2006
  catch (error) {
2017
2007
  log.warn('Failed to send initial run-control counts snapshot', error);
@@ -168,16 +168,16 @@ function fallbackRenderedReminder(reminder) {
168
168
  }),
169
169
  };
170
170
  }
171
- function formatAppReminderWrapperPrelude(language) {
171
+ function formatAppReminderWrapperPrelude(language, reminderId) {
172
172
  return language === 'zh'
173
- ? `这是 app 自动维护的状态提醒,不是你自己写的工作便签。${(0, driver_messages_1.formatAutoMaintainedReminderManualMirrorBan)(language)}`
174
- : `This is app-maintained state, not a work note you wrote. ${(0, driver_messages_1.formatAutoMaintainedReminderManualMirrorBan)(language)}`;
173
+ ? `这是 app 自动维护的状态提醒 [${reminderId}],不是你自己写的工作便签。${(0, driver_messages_1.formatAutoMaintainedReminderManualMirrorBan)(language)}`
174
+ : `This is app-maintained state [${reminderId}], not a work note you wrote. ${(0, driver_messages_1.formatAutoMaintainedReminderManualMirrorBan)(language)}`;
175
175
  }
176
- function wrapAppRenderedReminder(message, language) {
176
+ function wrapAppRenderedReminder(reminderId, message, language) {
177
177
  return {
178
178
  type: 'environment_msg',
179
179
  role: 'user',
180
- content: `${formatAppReminderWrapperPrelude(language)}\n\n${message.content}`,
180
+ content: `${formatAppReminderWrapperPrelude(language, reminderId)}\n\n${message.content}`,
181
181
  };
182
182
  }
183
183
  async function persistAndPublishReminders(dlg) {
@@ -254,7 +254,7 @@ function createAppReminderOwner(params) {
254
254
  reminderId: reminder.id,
255
255
  workLanguage: language,
256
256
  });
257
- return wrapAppRenderedReminder(rendered, language);
257
+ return wrapAppRenderedReminder(reminder.id, rendered, language);
258
258
  }
259
259
  catch (error) {
260
260
  log_1.log.warn('App reminder render failed; using generic reminder rendering', error, {
@@ -40,6 +40,7 @@ export type CmdRunnerRequest = Readonly<{
40
40
  stderr: boolean;
41
41
  }> | Readonly<{
42
42
  type: 'stop';
43
+ entirePg: boolean;
43
44
  }>;
44
45
  export type CmdRunnerStreamSnapshot = Readonly<{
45
46
  content: string;
@@ -226,9 +226,16 @@ function parseCmdRunnerRequestLine(line) {
226
226
  throw new Error('Invalid cmd_runner request: expected object');
227
227
  }
228
228
  const type = asString(raw['type']);
229
- if (type === 'ping' || type === 'get_status' || type === 'stop') {
229
+ if (type === 'ping' || type === 'get_status') {
230
230
  return { type };
231
231
  }
232
+ if (type === 'stop') {
233
+ const entirePg = asBoolean(raw['entirePg']);
234
+ if (entirePg === null) {
235
+ throw new Error('Invalid cmd_runner stop request: entirePg must be boolean');
236
+ }
237
+ return { type, entirePg };
238
+ }
232
239
  if (type === 'get_output') {
233
240
  const stdout = asBoolean(raw['stdout']);
234
241
  const stderr = asBoolean(raw['stderr']);
@@ -10,6 +10,7 @@ const node_net_1 = __importDefault(require("node:net"));
10
10
  const node_path_1 = __importDefault(require("node:path"));
11
11
  const node_util_1 = require("node:util");
12
12
  const cmd_runner_protocol_1 = require("./cmd-runner-protocol");
13
+ const process_kill_1 = require("./process-kill");
13
14
  const shell_capture_env_1 = require("./shell-capture-env");
14
15
  const execFileAsync = (0, node_util_1.promisify)(child_process_1.execFile);
15
16
  class ScrollingBuffer {
@@ -113,8 +114,8 @@ async function ensureSocketParentDir(endpoint) {
113
114
  }
114
115
  }
115
116
  }
116
- function writeSocketResponse(socket, response) {
117
- socket.end(`${JSON.stringify(response)}\n`);
117
+ function writeSocketResponse(socket, response, callback) {
118
+ socket.end(`${JSON.stringify(response)}\n`, callback);
118
119
  }
119
120
  function isProcessAlive(pid) {
120
121
  try {
@@ -126,6 +127,11 @@ function isProcessAlive(pid) {
126
127
  return code !== 'ESRCH';
127
128
  }
128
129
  }
130
+ function markDaemonMissing(state) {
131
+ state.isRunning = false;
132
+ state.exitCode = null;
133
+ state.exitSignal = 'SIGKILL';
134
+ }
129
135
  async function main() {
130
136
  const initMessage = await new Promise((resolve, reject) => {
131
137
  const timeout = setTimeout(() => {
@@ -335,11 +341,12 @@ async function main() {
335
341
  return;
336
342
  }
337
343
  await handleStopRequest(request, state, childProcess);
344
+ const shouldExitAfterResponse = !state.isRunning;
338
345
  writeSocketResponse(socket, {
339
346
  type: 'stop_result',
340
347
  ok: true,
341
348
  ...buildStatusPayload(state),
342
- });
349
+ }, shouldExitAfterResponse ? () => closeServerAndExit(0) : undefined);
343
350
  }
344
351
  catch (error) {
345
352
  writeSocketResponse(socket, {
@@ -412,8 +419,24 @@ async function handleStopRequest(request, state, childProcess) {
412
419
  if (!state.isRunning) {
413
420
  return;
414
421
  }
415
- process.kill(state.daemonPid, 'SIGTERM');
416
- await new Promise((resolve) => setTimeout(resolve, 1000));
422
+ if (request.entirePg && process.platform === 'win32') {
423
+ await (0, process_kill_1.bestEffortKillWindowsProcessTree)(state.daemonPid);
424
+ await (0, process_kill_1.sleepMs)(100);
425
+ if (!state.isRunning || !isProcessAlive(state.daemonPid)) {
426
+ if (!state.isRunning) {
427
+ return;
428
+ }
429
+ markDaemonMissing(state);
430
+ return;
431
+ }
432
+ }
433
+ try {
434
+ process.kill(state.daemonPid, 'SIGTERM');
435
+ }
436
+ catch {
437
+ return;
438
+ }
439
+ await (0, process_kill_1.sleepMs)(1000);
417
440
  if (!state.isRunning) {
418
441
  return;
419
442
  }
@@ -423,13 +446,17 @@ async function handleStopRequest(request, state, childProcess) {
423
446
  catch {
424
447
  // Process may have exited during grace period.
425
448
  }
426
- await new Promise((resolve) => setTimeout(resolve, 100));
449
+ await (0, process_kill_1.sleepMs)(100);
427
450
  if (!state.isRunning) {
428
451
  return;
429
452
  }
430
453
  if (typeof childProcess.kill === 'function') {
431
454
  childProcess.kill('SIGKILL');
432
455
  }
456
+ await (0, process_kill_1.sleepMs)(100);
457
+ if (state.isRunning && !isProcessAlive(state.daemonPid)) {
458
+ markDaemonMissing(state);
459
+ }
433
460
  }
434
461
  void main().catch((error) => {
435
462
  void flushIpc({
package/dist/tools/mcp.js CHANGED
@@ -213,10 +213,7 @@ exports.mcpLeaseReminderOwner = {
213
213
  `你当前看到的是系统维护的 MCP 租约状态。该 MCP server 被视为非“真正无状态”;当前对话持有一个 MCP 运行时实例(HTTP 连接或 stdio 进程)。`,
214
214
  (0, driver_messages_1.formatAutoMaintainedReminderManualMirrorBan)(workLanguage),
215
215
  '',
216
- `当你确认近期不再需要这个运行时实例时,请释放它,以停止/回收底层 MCP 进程或连接:`,
217
- `- \`mcp_release({\"serverId\":\"${serverId}\"})\``,
218
- '',
219
- `这只影响当前对话持有的运行时实例,不决定该 server 的全局工具注册/可见性。`,
216
+ `该提醒项只说明当前对话持有的运行时实例;它不决定该 server 的全局工具注册/可见性。`,
220
217
  ].join('\n')
221
218
  : [
222
219
  `${prefix} MCP toolset lease [${reminder.id}]: \`${serverId}\``,
@@ -224,10 +221,7 @@ exports.mcpLeaseReminderOwner = {
224
221
  `You are looking at system-maintained MCP lease state. This MCP server is treated as non-stateless, and the current dialog holds one MCP runtime instance for it (an HTTP connection or stdio process).`,
225
222
  (0, driver_messages_1.formatAutoMaintainedReminderManualMirrorBan)(workLanguage),
226
223
  '',
227
- `When you are confident you will not need this runtime instance soon, release it to stop the underlying MCP process/connection:`,
228
- `- \`mcp_release({\"serverId\":\"${serverId}\"})\``,
229
- '',
230
- `This only affects the runtime instance held by the current dialog; it does not determine global tool registration/visibility for that server.`,
224
+ `This reminder only describes the runtime instance held by the current dialog; it does not determine global tool registration/visibility for that server.`,
231
225
  ].join('\n'),
232
226
  };
233
227
  },
package/dist/tools/os.js CHANGED
@@ -31,6 +31,7 @@ const shared_reminders_1 = require("../shared-reminders");
31
31
  const tool_1 = require("../tool");
32
32
  const cmd_runner_protocol_1 = require("./cmd-runner-protocol");
33
33
  const output_limit_1 = require("./output-limit");
34
+ const process_kill_1 = require("./process-kill");
34
35
  const shell_capture_env_1 = require("./shell-capture-env");
35
36
  const execFileAsync = (0, util_1.promisify)(child_process_1.execFile);
36
37
  const requireFn = (0, module_1.createRequire)(__filename);
@@ -382,25 +383,25 @@ function buildShellCmdFinalizedMeta(previousMeta, lastUpdated) {
382
383
  function formatDaemonLifecyclePhaseSummary(command, phase, language) {
383
384
  if (language === 'zh') {
384
385
  return phase === 'running'
385
- ? `🟢 ${command} 运行中(系统维护 / 实时真源 / 不可删除)`
386
- : `🟡 ${command} 已退出(退出事件提示 / 确认看到后可删除)`;
386
+ ? `🟢 ${command} 运行中(系统维护 / 实时真源)`
387
+ : `🟡 ${command} 已退出(退出事件提示)`;
387
388
  }
388
389
  return phase === 'running'
389
- ? `🟢 ${command} running (system-maintained / live source of truth / not deletable)`
390
- : `🟡 ${command} exited (exit event notice / delete after acknowledgment)`;
390
+ ? `🟢 ${command} running (system-maintained / live source of truth)`
391
+ : `🟡 ${command} exited (exit event notice)`;
391
392
  }
392
393
  function formatExitedDaemonReminderContent(command, pid, language, lastKnownSnapshot) {
393
394
  const phaseSummary = formatDaemonLifecyclePhaseSummary(command, 'exited', language);
394
395
  return language === 'zh'
395
396
  ? `${phaseSummary}
396
397
 
397
- 如需核对最后 stdout/stderr,可先按需调用 get_daemon_output({ "pid": ${pid} });若该调用已不可用,则以下保留的是最后一次已知快照。确认已知悉后,请手动删除这条提醒。
398
+ 以下保留最后一次已知 stdout/stderr 快照;该提醒项只表达 daemon 终态,不是当前轮必须立即处理的动作。
398
399
 
399
400
  最后一次已知状态快照:
400
401
  ${lastKnownSnapshot}`
401
402
  : `${phaseSummary}
402
403
 
403
- If you need to verify the final stdout/stderr, first call get_daemon_output({ "pid": ${pid} }) if it is still available; otherwise use the last known snapshot below. After you have acknowledged the exit, delete this reminder manually.
404
+ The last known stdout/stderr snapshot is retained below; this reminder only represents the daemon terminal state, not an action I must perform immediately in this turn.
404
405
 
405
406
  Last known status snapshot:
406
407
  ${lastKnownSnapshot}`;
@@ -554,7 +555,7 @@ async function waitForShellCmdReminderWakeEvent(reminder, signal) {
554
555
  function getOsToolMessages(language) {
555
556
  if (language === 'zh') {
556
557
  return {
557
- daemonStarted: (pid, timeoutSeconds, command) => `🟢 ${command} 已转入后台持续运行(PID: ${pid})\n该进程在 ${timeoutSeconds} 秒内未完成,现已作为守护进程继续执行。你将看到同一条生命周期提醒持续刷新:系统维护 / 实时真源 / 不可删除。${(0, driver_messages_1.formatAutoMaintainedReminderManualMirrorBan)(language)}\n\n需要时可使用 stop_daemon({"pid": ${pid}}) 终止该进程。`,
558
+ daemonStarted: (pid, timeoutSeconds, command) => `🟢 ${command} 已转入后台持续运行(PID: ${pid})\n该进程在 ${timeoutSeconds} 秒内未完成,现已作为守护进程继续执行。你将看到同一条生命周期提醒持续刷新:系统维护 / 实时真源。${(0, driver_messages_1.formatAutoMaintainedReminderManualMirrorBan)(language)}\n\n这条结果只说明进程已转入后台;对应 daemon reminder 的维护参考会描述后续管理通道。`,
558
559
  commandCompleted: (exitCode, scrollNotice) => `✅ 命令已完成(退出码:${exitCode ?? 'unknown'})${scrollNotice}\n\n`,
559
560
  scrolledLinesNotice: (lines) => `\n⚠️ 执行期间有 ${lines} 行已滚出可视范围`,
560
561
  stdoutLabel: '📤 stdout:',
@@ -569,7 +570,7 @@ function getOsToolMessages(language) {
569
570
  };
570
571
  }
571
572
  return {
572
- daemonStarted: (pid, timeoutSeconds, command) => `🟢 ${command} is now running in the background (PID: ${pid})\nThe process did not finish within ${timeoutSeconds} seconds and has transitioned into a daemon. You will see the same lifecycle reminder keep updating: system-maintained / live source of truth / not deletable. ${(0, driver_messages_1.formatAutoMaintainedReminderManualMirrorBan)(language)}\n\nUse stop_daemon({"pid": ${pid}}) to terminate it when needed.`,
573
+ daemonStarted: (pid, timeoutSeconds, command) => `🟢 ${command} is now running in the background (PID: ${pid})\nThe process did not finish within ${timeoutSeconds} seconds and has transitioned into a daemon. You will see the same lifecycle reminder keep updating: system-maintained / live source of truth. ${(0, driver_messages_1.formatAutoMaintainedReminderManualMirrorBan)(language)}\n\nThis result only reports that the process moved into the background; the corresponding daemon reminder maintenance reference describes later management paths.`,
573
574
  commandCompleted: (exitCode, scrollNotice) => `✅ Command completed (exit code: ${exitCode ?? 'unknown'})${scrollNotice}\n\n`,
574
575
  scrolledLinesNotice: (lines) => `\n⚠️ ${lines} lines scrolled out of view during execution`,
575
576
  stdoutLabel: '📤 stdout:',
@@ -794,12 +795,9 @@ function parseStopDaemonArgs(args) {
794
795
  if (entirePg !== undefined && typeof entirePg !== 'boolean') {
795
796
  throw new Error('stop_daemon.entire_pg must be a boolean if provided');
796
797
  }
797
- if (process.platform === 'win32' && entirePg === true) {
798
- throw new Error('stop_daemon.entire_pg=true is unsupported on Windows');
799
- }
800
798
  return {
801
799
  pid,
802
- entirePg: entirePg ?? process.platform !== 'win32',
800
+ entirePg: entirePg ?? true,
803
801
  };
804
802
  }
805
803
  function parseGetDaemonOutputArgs(args) {
@@ -1026,6 +1024,13 @@ async function callRunner(endpoint, request, timeoutMs = 5000) {
1026
1024
  }
1027
1025
  async function bestEffortKillDaemonProcessGroup(meta, options) {
1028
1026
  const includeEntirePg = options?.includeEntirePg ?? true;
1027
+ if (includeEntirePg && process.platform === 'win32') {
1028
+ await (0, process_kill_1.bestEffortKillWindowsProcessTree)(meta.pid);
1029
+ if (meta.runnerPid !== undefined && meta.runnerPid !== meta.pid) {
1030
+ (0, process_kill_1.bestEffortKillPid)(meta.runnerPid);
1031
+ }
1032
+ return;
1033
+ }
1029
1034
  if (includeEntirePg && process.platform !== 'win32' && meta.processGroupId !== undefined) {
1030
1035
  try {
1031
1036
  process.kill(-meta.processGroupId, 'SIGTERM');
@@ -1033,7 +1038,7 @@ async function bestEffortKillDaemonProcessGroup(meta, options) {
1033
1038
  catch {
1034
1039
  // Best effort only.
1035
1040
  }
1036
- await new Promise((resolve) => setTimeout(resolve, 1000));
1041
+ await (0, process_kill_1.sleepMs)(1000);
1037
1042
  try {
1038
1043
  process.kill(-meta.processGroupId, 'SIGKILL');
1039
1044
  }
@@ -1047,7 +1052,7 @@ async function bestEffortKillDaemonProcessGroup(meta, options) {
1047
1052
  catch {
1048
1053
  // Best effort only.
1049
1054
  }
1050
- await new Promise((resolve) => setTimeout(resolve, 250));
1055
+ await (0, process_kill_1.sleepMs)(250);
1051
1056
  try {
1052
1057
  process.kill(meta.pid, 'SIGKILL');
1053
1058
  }
@@ -1216,7 +1221,7 @@ const stopDaemonSchema = {
1216
1221
  },
1217
1222
  entire_pg: {
1218
1223
  type: 'boolean',
1219
- description: 'Whether to signal the entire process group instead of only the tracked PID (default: true on Unix-like systems; false on Windows)',
1224
+ description: 'Whether to stop the entire process group/process tree instead of only the tracked PID (default: true)',
1220
1225
  },
1221
1226
  },
1222
1227
  required: ['pid'],
@@ -1444,11 +1449,11 @@ exports.shellCmdReminderOwner = {
1444
1449
  ? `${prefix} 后台进程生命周期提醒 [${reminder.id}]
1445
1450
  当前运行环境中有一条系统维护的后台进程状态提醒。请把它当成环境信号,不要当成你自己写的工作便签。
1446
1451
  ${(0, driver_messages_1.formatAutoMaintainedReminderManualMirrorBan)(language)}
1447
- 若它没有实质改变你的判断/计划/风险,则禁止做任何用户可见回应(禁止写“静默吸收”“已收到”等占位语句);只有它实际影响后续动作时,才在下一条有实质内容的回复中体现相关事实。该提醒在进程运行期间会自动更新;进程结束后会保留终态,等待你确认后手动删除。
1452
+ 若它没有实质改变你的判断/计划/风险,则禁止做任何用户可见回应(禁止写“静默吸收”“已收到”等占位语句);只有它实际影响后续动作时,才在下一条有实质内容的回复中体现相关事实。该提醒在进程运行期间会自动更新;进程结束后会保留终态作为运行时上下文。
1448
1453
  ---
1449
1454
  ${reminder.content}`
1450
1455
  : `${prefix} Background process lifecycle reminder [${reminder.id}]
1451
- The current runtime environment has a system-maintained background-process state reminder. Treat it as an environment signal, not as your self-authored work note. ${(0, driver_messages_1.formatAutoMaintainedReminderManualMirrorBan)(language)} 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 auto-updates while the process is running; after exit it keeps the terminal state until you delete it manually.
1456
+ The current runtime environment has a system-maintained background-process state reminder. Treat it as an environment signal, not as your self-authored work note. ${(0, driver_messages_1.formatAutoMaintainedReminderManualMirrorBan)(language)} 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 auto-updates while the process is running; after exit it keeps the terminal state as runtime context.
1452
1457
  ---
1453
1458
  ${reminder.content}`,
1454
1459
  };
@@ -1468,11 +1473,11 @@ ${reminder.content}`,
1468
1473
  ? `${prefix} 守护进程生命周期提醒 [${reminder.id}] - ${exitedSummary}|PID ${pid}
1469
1474
  当前运行环境中 daemon 已退出。
1470
1475
  ${(0, driver_messages_1.formatAutoMaintainedReminderManualMirrorBan)(language)}
1471
- 若需要再核对最后 stdout/stderr,可先按需调用 get_daemon_output({ "pid": ${pid} });若该调用已不可用,则以下是最后一次已知快照。确认已知悉后,请手动删除这条提醒。
1476
+ 以下是最后一次已知 stdout/stderr 快照;该提醒项只表达 daemon 终态,不是当前轮必须立即处理的动作。
1472
1477
  ---
1473
1478
  ${reminder.content}`
1474
1479
  : `${prefix} Daemon lifecycle reminder [${reminder.id}] - ${exitedSummary} | PID ${pid}
1475
- The current runtime environment shows that this daemon has exited. ${(0, driver_messages_1.formatAutoMaintainedReminderManualMirrorBan)(language)} If you still need to inspect the final stdout/stderr, first call get_daemon_output({ "pid": ${pid} }) if it is still available; otherwise use the last known snapshot below. After you have acknowledged the exit, delete this reminder manually.
1480
+ The current runtime environment shows that this daemon has exited. ${(0, driver_messages_1.formatAutoMaintainedReminderManualMirrorBan)(language)} The last known stdout/stderr snapshot is retained below; this reminder only represents the daemon terminal state, not an action I must perform immediately in this turn.
1476
1481
  ---
1477
1482
  ${reminder.content}`,
1478
1483
  };
@@ -1510,12 +1515,12 @@ The current runtime environment shows that this daemon process has finished its
1510
1515
  ? `🔄 ${prefix} 守护进程生命周期提醒 [${reminder.id}] - ${runningSummary}|PID ${pid},已运行 ${uptimeStr}
1511
1516
  当前运行环境中 daemon 仍在运行。这是系统维护的状态提醒,不是默认需要单独汇报的事项。
1512
1517
  ${(0, driver_messages_1.formatAutoMaintainedReminderManualMirrorBan)(language)}
1513
- 若下面的信息没有实质改变你的判断、计划、风险,且不需要调用守护进程相关工具,则禁止做任何用户可见回应;若它有实质影响,只在下一条有实质内容的回复中体现,禁止单独发送“静默吸收”“已收到”等占位语句。
1518
+ 若下面的信息没有实质改变你的判断、计划或风险,则禁止做任何用户可见回应;若它有实质影响,只在下一条有实质内容的回复中体现,禁止单独发送“静默吸收”“已收到”等占位语句。
1514
1519
 
1515
1520
  **状态快照:**
1516
1521
  ${statusInfo}`
1517
1522
  : `🔄 ${prefix} Daemon lifecycle reminder [${reminder.id}] - ${runningSummary} | PID ${pid}, uptime: ${uptimeStr}
1518
- The current runtime environment shows that this daemon is still running. This is a system-maintained state reminder and not something that normally deserves a standalone mention. ${(0, driver_messages_1.formatAutoMaintainedReminderManualMirrorBan)(language)} 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".
1523
+ The current runtime environment shows that this daemon is still running. This is a system-maintained state reminder and not something that normally deserves a standalone mention. ${(0, driver_messages_1.formatAutoMaintainedReminderManualMirrorBan)(language)} If the information below does not materially change your judgment, plan, or risk, 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".
1519
1524
 
1520
1525
  **State snapshot:**
1521
1526
  ${statusInfo}`,
@@ -2752,7 +2757,7 @@ exports.stopDaemonTool = {
2752
2757
  if (reminder.meta.runnerEndpoint !== undefined &&
2753
2758
  reminder.meta.runnerEndpoint.trim() !== '') {
2754
2759
  try {
2755
- const stopResponse = await callRunner(reminder.meta.runnerEndpoint, { type: 'stop' }, 10000);
2760
+ const stopResponse = await callRunner(reminder.meta.runnerEndpoint, { type: 'stop', entirePg }, 10000);
2756
2761
  if (stopResponse.ok && runnerResponseMatchesReminder(reminder.meta, stopResponse)) {
2757
2762
  if (stopResponse.isRunning) {
2758
2763
  await bestEffortKillDaemonProcessGroup(reminder.meta, { includeEntirePg: entirePg });
@@ -36,13 +36,13 @@ function isPendingTellaskReminderMeta(value) {
36
36
  }
37
37
  function getPendingTellaskUpdateAltInstruction(language) {
38
38
  return language === 'zh'
39
- ? '不要手改这条系统提醒。诉请更改规则很简单:同一路长线诉请要改要求,就复用同一 `sessionSlug` 再发 `tellask`;`tellaskSessionless` 是另一件一次性独立任务,不能改旧任务,也不能要求旧任务停止。其它情况等待系统按真实诉请状态自动刷新。'
40
- : 'Do not hand-edit this system reminder. The change rule is simple: to change a sessioned task, send another `tellask` with the same `sessionSlug`; `tellaskSessionless` is another one-shot independent task, so it cannot change or stop an earlier task. Otherwise wait for system refresh from real tellask state.';
39
+ ? '我不手改这条系统提醒。诉请更改规则:同一路长线诉请要改要求时,我复用同一 `sessionSlug` 再发 `tellask`;`tellaskSessionless` 是另一件一次性独立任务,不能改旧任务,也不能要求旧任务停止。其它情况我等待系统按真实诉请状态自动刷新。'
40
+ : 'I do not hand-edit this system reminder. To change a sessioned task, I send another `tellask` with the same `sessionSlug`; `tellaskSessionless` is another one-shot independent task, so it cannot change or stop an earlier task. Otherwise I wait for system refresh from real tellask state.';
41
41
  }
42
42
  function getPendingTellaskDeleteAltInstruction(language) {
43
43
  return language === 'zh'
44
- ? '这条系统提醒不可删除。诉请更改规则很简单:同一路长线诉请要改要求,就复用同一 `sessionSlug` 再发 `tellask`;`tellaskSessionless` 是另一件一次性独立任务,不能改旧任务,也不能要求旧任务停止。其它情况等待系统按真实诉请状态自动刷新。'
45
- : 'This system reminder is not deletable. The change rule is simple: to change a sessioned task, send another `tellask` with the same `sessionSlug`; `tellaskSessionless` is another one-shot independent task, so it cannot change or stop an earlier task. Otherwise wait for system refresh from real tellask state.';
44
+ ? '我不能删除这条系统提醒。诉请更改规则:同一路长线诉请要改要求时,我复用同一 `sessionSlug` 再发 `tellask`;`tellaskSessionless` 是另一件一次性独立任务,不能改旧任务,也不能要求旧任务停止。其它情况我等待系统按真实诉请状态自动刷新。'
45
+ : 'I cannot delete this system reminder. To change a sessioned task, I send another `tellask` with the same `sessionSlug`; `tellaskSessionless` is another one-shot independent task, so it cannot change or stop an earlier task. Otherwise I wait for system refresh from real tellask state.';
46
46
  }
47
47
  function callKindLabel(language, view) {
48
48
  if (view.callType === 'A') {
@@ -112,17 +112,17 @@ function buildReminderMeta(pending, previousMeta) {
112
112
  }
113
113
  function buildReminderContent(language, pending) {
114
114
  const heading = language === 'zh'
115
- ? `⏳ 进行中诉请(共 ${pending.length} 路,自动维护${pending.length === 0 ? ',0 路时可手动删除' : ',进行中不可删除'})`
116
- : `⏳ In-flight Tellasks (${pending.length} total, auto-maintained${pending.length === 0 ? ', deletable only at zero in-flight' : ', non-deletable while active'})`;
115
+ ? `⏳ 进行中诉请(共 ${pending.length} 路,自动维护)`
116
+ : `⏳ In-flight Tellasks (${pending.length} total, auto-maintained)`;
117
117
  if (pending.length === 0) {
118
118
  const noneRunningText = language === 'zh'
119
- ? '当前没有任何执行中的诉请,没有其祂智能体仍在后台工作,任何“等待”想法和行为都是错误的。该提醒项仍是系统状态窗,内容不可手改;但因为当前为 0 路进行中,若你已明确知晓这一点,可手动删除以免碍眼。后续需要推进时,只能直接执行下一步本地动作,或发起新的诉请。'
120
- : 'There are no in-flight Tellasks, and no other agents are still working in the background. Any “wait” thought or behavior is wrong. This reminder is still a system status window and its content must not be hand-edited; however, because there are currently zero in-flight Tellasks, you may delete it manually once you are sure. To continue later, take the next local action directly or issue a new Tellask.';
119
+ ? '当前没有任何执行中的诉请,没有其祂智能体仍在后台工作,任何“等待”想法和行为都是错误的。该提醒项只是系统状态窗;后续需要推进时,只能直接执行下一步本地动作,或发起新的诉请。'
120
+ : 'There are no in-flight Tellasks, and no other agents are still working in the background. Any “wait” thought or behavior is wrong. This reminder is only a system status window; to continue later, take the next local action directly or issue a new Tellask.';
121
121
  return [heading, '', noneRunningText].join('\n');
122
122
  }
123
123
  const summary = language === 'zh'
124
- ? '以下诉请仍在执行中;除这些条目外,当前没有其它仍在执行中的诉请。该提醒项只是系统状态窗,不是控制面:自动维护、不可手改,且在非 0 路进行中时不可删除。不要把智能体队友当成真人同事:同一个队友可以同时做多件独立任务。简单规则:同一个队友 + 同一个 `sessionSlug` = 接着同一件事说,并更新那件正在做的事;`tellaskSessionless` 或不同 `sessionSlug` = 另一件独立任务,不会影响旧任务,也不能要求旧任务停止。误删会被拒绝,并返回同样的引导文案。'
125
- : 'Only the Tellasks listed below are still in flight; besides them, no other Tellasks are currently executing. This reminder is only a system status window, not a control surface: auto-maintained, not hand-editable, and non-deletable while any tellask is still active. Do not treat an agent teammate like a human coworker who can only handle one conversation at a time: the same teammate can work on several independent tasks at once. Simple rule: same teammate + same `sessionSlug` = continue the same task and update that task; `tellaskSessionless` or a different `sessionSlug` = another independent task, so it will not affect or stop the earlier task. Mistaken deletion will be rejected with the same guidance.';
124
+ ? '以下诉请仍在执行中;除这些条目外,当前没有其它仍在执行中的诉请。该提醒项只是系统状态窗,不是控制面。不要把智能体队友当成真人同事:同一个队友可以同时做多件独立任务。'
125
+ : 'Only the Tellasks listed below are still in flight; besides them, no other Tellasks are currently executing. This reminder is only a system status window, not a control surface. Do not treat an agent teammate like a human coworker who can only handle one conversation at a time: the same teammate can work on several independent tasks at once.';
126
126
  const lines = pending.map((p, idx) => {
127
127
  const base = language === 'zh'
128
128
  ? `${idx + 1}. ${activeCalleeTargetLabel(language, p)} | ${callKindLabel(language, p)} | ${summarizeTellask(p)}`
@@ -0,0 +1,4 @@
1
+ export declare function sleepMs(milliseconds: number): Promise<void>;
2
+ export declare function buildWindowsTaskkillArgs(pid: number, force: boolean): string[];
3
+ export declare function bestEffortKillWindowsProcessTree(pid: number): Promise<void>;
4
+ export declare function bestEffortKillPid(pid: number): void;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sleepMs = sleepMs;
4
+ exports.buildWindowsTaskkillArgs = buildWindowsTaskkillArgs;
5
+ exports.bestEffortKillWindowsProcessTree = bestEffortKillWindowsProcessTree;
6
+ exports.bestEffortKillPid = bestEffortKillPid;
7
+ const node_child_process_1 = require("node:child_process");
8
+ const node_util_1 = require("node:util");
9
+ const execFileAsync = (0, node_util_1.promisify)(node_child_process_1.execFile);
10
+ function sleepMs(milliseconds) {
11
+ return new Promise((resolve) => setTimeout(resolve, milliseconds));
12
+ }
13
+ function buildWindowsTaskkillArgs(pid, force) {
14
+ assertValidPid(pid);
15
+ return force ? ['/PID', String(pid), '/T', '/F'] : ['/PID', String(pid), '/T'];
16
+ }
17
+ function assertValidPid(pid) {
18
+ if (!Number.isInteger(pid) || pid <= 0) {
19
+ throw new Error(`Invalid process pid: ${String(pid)}`);
20
+ }
21
+ }
22
+ async function bestEffortTaskkill(pid, force) {
23
+ try {
24
+ await execFileAsync('taskkill.exe', buildWindowsTaskkillArgs(pid, force), {
25
+ windowsHide: true,
26
+ maxBuffer: 1024 * 1024,
27
+ });
28
+ }
29
+ catch {
30
+ // Best effort only.
31
+ }
32
+ }
33
+ async function bestEffortKillWindowsProcessTree(pid) {
34
+ assertValidPid(pid);
35
+ await bestEffortTaskkill(pid, false);
36
+ await sleepMs(1000);
37
+ await bestEffortTaskkill(pid, true);
38
+ bestEffortKillPid(pid);
39
+ }
40
+ function bestEffortKillPid(pid) {
41
+ assertValidPid(pid);
42
+ try {
43
+ process.kill(pid, 'SIGKILL');
44
+ }
45
+ catch {
46
+ // Best effort only.
47
+ }
48
+ }
@@ -55,7 +55,7 @@ Stop daemon process.
55
55
  **Parameters:**
56
56
 
57
57
  - `pid` (required): Daemon process ID (number)
58
- - `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`)
58
+ - `entire_pg` (optional): Whether to stop the entire process group/process tree (default: `true`; on Windows this stops the tracked shell process and its child processes)
59
59
 
60
60
  **Returns:**
61
61
 
@@ -151,7 +151,7 @@ stop_daemon({
151
151
  pid: 12345,
152
152
  });
153
153
 
154
- // On Unix-like systems, you can explicitly terminate the whole process group
154
+ // Explicitly stop the whole process group/process tree
155
155
  stop_daemon({
156
156
  pid: 12345,
157
157
  entire_pg: true,
@@ -55,7 +55,7 @@ executed_at: <执行时间戳>
55
55
  **参数:**
56
56
 
57
57
  - `pid`(必需):守护进程 PID(数字)
58
- - `entire_pg`(可选):是否对整个进程组发终止信号(默认:Linux/macOS 为 `true`,Windows `false`;Windows 不支持显式传 `true`)
58
+ - `entire_pg`(可选):是否停止整个进程组/进程树(默认:`true`;Windows 上会停止被追踪的 shell 进程及其子进程)
59
59
 
60
60
  **返回:**
61
61
 
@@ -151,7 +151,7 @@ stop_daemon({
151
151
  pid: 12345,
152
152
  });
153
153
 
154
- // Unix-like 平台可显式要求终止整个进程组
154
+ // 显式要求停止整个进程组/进程树
155
155
  stop_daemon({
156
156
  pid: 12345,
157
157
  entire_pg: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dominds",
3
- "version": "1.25.13",
3
+ "version": "1.25.15",
4
4
  "description": "Dominds CLI and aggregation shell for the LongRun AI kernel/runtime packages.",
5
5
  "type": "commonjs",
6
6
  "publishConfig": {
@@ -52,9 +52,9 @@
52
52
  "ws": "^8.19.0",
53
53
  "yaml": "^2.8.2",
54
54
  "zod": "^4.3.6",
55
- "@longrun-ai/kernel": "1.15.9",
56
- "@longrun-ai/shell": "1.15.9",
57
- "@longrun-ai/codex-auth": "0.13.0"
55
+ "@longrun-ai/codex-auth": "0.13.0",
56
+ "@longrun-ai/kernel": "1.15.11",
57
+ "@longrun-ai/shell": "1.15.11"
58
58
  },
59
59
  "devDependencies": {
60
60
  "@types/node": "^25.3.5",
@@ -1,5 +1,5 @@
1
- import { e as isSymbol, c as baseFlatten, g as baseIteratee, k as keys, h as baseFindIndex, j as baseEach, l as arrayMap, m as hasPath, n as castPath, t as toKey, o as baseGet } from "./_baseUniq-BuB0jmKD.js";
2
- import { aU as isObject, aC as baseRest, aV as isIterateeCall, aW as keysIn, aX as eq, aY as isArrayLike, aZ as isArray, a_ as identity, a$ as isIndex, b0 as assignValue } from "./index-DLTS_eOh.js";
1
+ import { e as isSymbol, c as baseFlatten, g as baseIteratee, k as keys, h as baseFindIndex, j as baseEach, l as arrayMap, m as hasPath, n as castPath, t as toKey, o as baseGet } from "./_baseUniq-CGrWBZre.js";
2
+ import { aU as isObject, aC as baseRest, aV as isIterateeCall, aW as keysIn, aX as eq, aY as isArrayLike, aZ as isArray, a_ as identity, a$ as isIndex, b0 as assignValue } from "./index-r4An5YoX.js";
3
3
  var reWhitespace = /\s/;
4
4
  function trimmedEndIndex(string) {
5
5
  var index = string.length;
@@ -193,4 +193,4 @@ export {
193
193
  map as m,
194
194
  toFinite as t
195
195
  };
196
- //# sourceMappingURL=_basePickBy-B1-brAPU.js.map
196
+ //# sourceMappingURL=_basePickBy-bB-pfQPi.js.map