tianshu-harness 3.23.0

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 (255) hide show
  1. package/LICENSE +189 -0
  2. package/README.en.md +1066 -0
  3. package/README.ja.md +1214 -0
  4. package/README.ko.md +1216 -0
  5. package/README.md +309 -0
  6. package/completions/rivet.bash +118 -0
  7. package/completions/rivet.fish +110 -0
  8. package/completions/rivet.ps1 +230 -0
  9. package/completions/rivet.zsh +187 -0
  10. package/dist/account-OAEKORZE.js +47 -0
  11. package/dist/account-login-V6FOLHJR.js +65 -0
  12. package/dist/account-status-KHNPPAFL.js +23 -0
  13. package/dist/agent/worker-process/child.js +407 -0
  14. package/dist/browser-cli-FLNY5ZHI.js +19 -0
  15. package/dist/browser-readiness-LWVGSBD5.js +12 -0
  16. package/dist/build-backends-5KXKR2S4.js +13 -0
  17. package/dist/build-options-66Y4ZE7C.js +9 -0
  18. package/dist/bundled-skills/brainstorming/SKILL.md +139 -0
  19. package/dist/bundled-skills/visual-acceptance/SKILL.md +64 -0
  20. package/dist/chain-7MAMFXZ3.js +10 -0
  21. package/dist/checkpoint-MND4DUIX.js +33 -0
  22. package/dist/chunk-2E6CK2RC.js +392 -0
  23. package/dist/chunk-2EBWGAXD.js +51 -0
  24. package/dist/chunk-2HDP7RMR.js +119 -0
  25. package/dist/chunk-2HKD2UFM.js +1000 -0
  26. package/dist/chunk-2VYRLULP.js +51 -0
  27. package/dist/chunk-2XN7PM4N.js +125 -0
  28. package/dist/chunk-35H7GVNR.js +66 -0
  29. package/dist/chunk-3C3R7JXY.js +77 -0
  30. package/dist/chunk-3VGD2FXB.js +118 -0
  31. package/dist/chunk-424AP7FM.js +534 -0
  32. package/dist/chunk-4J5TZGOE.js +3707 -0
  33. package/dist/chunk-4QJ3Y5JM.js +898 -0
  34. package/dist/chunk-4U2ET7ZY.js +1326 -0
  35. package/dist/chunk-4XPFLICE.js +876 -0
  36. package/dist/chunk-5B2OCU5P.js +31707 -0
  37. package/dist/chunk-5GGOGLSN.js +73 -0
  38. package/dist/chunk-5JRZPLI6.js +251 -0
  39. package/dist/chunk-5TQ3JYBU.js +397 -0
  40. package/dist/chunk-66JPZSGX.js +55 -0
  41. package/dist/chunk-6HSVXHCZ.js +764 -0
  42. package/dist/chunk-6S5FPUS7.js +21 -0
  43. package/dist/chunk-722LQO64.js +131 -0
  44. package/dist/chunk-73NJ7IT7.js +354 -0
  45. package/dist/chunk-7FW3I7WC.js +95 -0
  46. package/dist/chunk-7KUCBNLB.js +173 -0
  47. package/dist/chunk-7RDOV3DF.js +201 -0
  48. package/dist/chunk-A5MNH4ER.js +79 -0
  49. package/dist/chunk-ADIVZ2D5.js +15 -0
  50. package/dist/chunk-AE3P3F6W.js +366 -0
  51. package/dist/chunk-AERM3VGP.js +280 -0
  52. package/dist/chunk-AEWHC4WM.js +246 -0
  53. package/dist/chunk-AOVQ7VIF.js +169 -0
  54. package/dist/chunk-AOYHP3WI.js +12411 -0
  55. package/dist/chunk-B3YEBABJ.js +7160 -0
  56. package/dist/chunk-BCQXEZPJ.js +154 -0
  57. package/dist/chunk-BKTQAYO2.js +418 -0
  58. package/dist/chunk-BSECIPAQ.js +80 -0
  59. package/dist/chunk-BUIMGNDD.js +52 -0
  60. package/dist/chunk-BXHV3GSB.js +10320 -0
  61. package/dist/chunk-C6ZVZCPP.js +139 -0
  62. package/dist/chunk-CEZNQVWM.js +82 -0
  63. package/dist/chunk-CGFZGR7G.js +1492 -0
  64. package/dist/chunk-CGOADM2X.js +337 -0
  65. package/dist/chunk-CI4R6P2B.js +24 -0
  66. package/dist/chunk-D2TCGRSX.js +73 -0
  67. package/dist/chunk-D4PTYFOG.js +154 -0
  68. package/dist/chunk-D54ZWG4T.js +717 -0
  69. package/dist/chunk-DEBI37QB.js +145 -0
  70. package/dist/chunk-DWROHPXP.js +1051 -0
  71. package/dist/chunk-DZ6UOJ5D.js +92 -0
  72. package/dist/chunk-EBJTVRQN.js +81 -0
  73. package/dist/chunk-EGEI2RQA.js +1167 -0
  74. package/dist/chunk-EHHUASO5.js +1305 -0
  75. package/dist/chunk-EPKTIOED.js +41 -0
  76. package/dist/chunk-ER5JW2QZ.js +5681 -0
  77. package/dist/chunk-ETHFACAB.js +315 -0
  78. package/dist/chunk-EXUE5W2F.js +112 -0
  79. package/dist/chunk-EXXICUIW.js +73 -0
  80. package/dist/chunk-FFQSZJOO.js +169 -0
  81. package/dist/chunk-FHFKPGDO.js +85 -0
  82. package/dist/chunk-FW3QKMFX.js +158 -0
  83. package/dist/chunk-GD4ZNZ7W.js +30 -0
  84. package/dist/chunk-GHVMWF2I.js +581 -0
  85. package/dist/chunk-GMKAXSYQ.js +297 -0
  86. package/dist/chunk-HBVF6BWO.js +325 -0
  87. package/dist/chunk-HV4YGVMS.js +379 -0
  88. package/dist/chunk-ILBCKAV6.js +89 -0
  89. package/dist/chunk-J4U4AW46.js +440 -0
  90. package/dist/chunk-J6ESSM47.js +1791 -0
  91. package/dist/chunk-JBZHIC6T.js +2309 -0
  92. package/dist/chunk-JCFWOULR.js +245 -0
  93. package/dist/chunk-JRF5L6OD.js +131 -0
  94. package/dist/chunk-JSS75KCG.js +2014 -0
  95. package/dist/chunk-JSXWIWWJ.js +225 -0
  96. package/dist/chunk-JYV7I2QH.js +98 -0
  97. package/dist/chunk-KIOXTQQL.js +1596 -0
  98. package/dist/chunk-KWVTXT5B.js +89 -0
  99. package/dist/chunk-KX22RD6R.js +33 -0
  100. package/dist/chunk-LA6IPTGH.js +709 -0
  101. package/dist/chunk-LH5VCGLB.js +1796 -0
  102. package/dist/chunk-LQQ6XJ2Y.js +269 -0
  103. package/dist/chunk-MJQ55WZZ.js +65 -0
  104. package/dist/chunk-ML3UKMH3.js +40 -0
  105. package/dist/chunk-MOZPLHSU.js +5526 -0
  106. package/dist/chunk-NGEWJ4DF.js +89 -0
  107. package/dist/chunk-NH6VIOAR.js +211 -0
  108. package/dist/chunk-O5VZQKCB.js +26106 -0
  109. package/dist/chunk-OHSV42QB.js +748 -0
  110. package/dist/chunk-OO3TAHO5.js +4070 -0
  111. package/dist/chunk-OTNHSAGN.js +38282 -0
  112. package/dist/chunk-OUWAC7AQ.js +442 -0
  113. package/dist/chunk-OXMIV4WE.js +270 -0
  114. package/dist/chunk-P5KJURUR.js +229 -0
  115. package/dist/chunk-P6GJOVO6.js +307 -0
  116. package/dist/chunk-QARAGUXX.js +23 -0
  117. package/dist/chunk-R43HJCDX.js +2711 -0
  118. package/dist/chunk-RAXBAWRN.js +210 -0
  119. package/dist/chunk-RK3JHWPT.js +39 -0
  120. package/dist/chunk-RWA23GMM.js +24 -0
  121. package/dist/chunk-S4K4L6IM.js +179 -0
  122. package/dist/chunk-SAXK6LVF.js +124 -0
  123. package/dist/chunk-SEPGEJNK.js +1607 -0
  124. package/dist/chunk-SUJERP5I.js +285 -0
  125. package/dist/chunk-T3ED6BY2.js +913 -0
  126. package/dist/chunk-THKDVSEC.js +90 -0
  127. package/dist/chunk-TI4GSEL5.js +52 -0
  128. package/dist/chunk-TPI73L57.js +164 -0
  129. package/dist/chunk-TVHW77C7.js +338 -0
  130. package/dist/chunk-TWNHOSDT.js +1073 -0
  131. package/dist/chunk-UFMN76QD.js +347 -0
  132. package/dist/chunk-UHGLFRZE.js +205 -0
  133. package/dist/chunk-UTZYPKBF.js +15231 -0
  134. package/dist/chunk-UXNLELW6.js +25 -0
  135. package/dist/chunk-UXXS53EA.js +166 -0
  136. package/dist/chunk-V5DHFGI7.js +171 -0
  137. package/dist/chunk-V5YIPMHV.js +2353 -0
  138. package/dist/chunk-WMUWEO2C.js +754 -0
  139. package/dist/chunk-WOE3D7JM.js +945 -0
  140. package/dist/chunk-X2IK5LVR.js +2592 -0
  141. package/dist/chunk-XU2YXCDL.js +459 -0
  142. package/dist/chunk-YJG5HIX5.js +203 -0
  143. package/dist/chunk-Z3QE7TZM.js +72 -0
  144. package/dist/chunk-Z5Z3JHJY.js +64 -0
  145. package/dist/chunk-ZDIFBJFT.js +168 -0
  146. package/dist/chunk-ZGGCEXDC.js +176 -0
  147. package/dist/chunk-ZMZCZNKU.js +263 -0
  148. package/dist/chunk-ZNC5T65N.js +17 -0
  149. package/dist/chunk-ZO3I3A7O.js +308 -0
  150. package/dist/chunk-ZQKXBUB7.js +217 -0
  151. package/dist/chunk-ZTRINFM2.js +78 -0
  152. package/dist/chunk-ZU7JZCVP.js +193 -0
  153. package/dist/chunk-ZZAWNALS.js +350 -0
  154. package/dist/cli/entry.js +54 -0
  155. package/dist/connector-L5QQTR6Y.js +26 -0
  156. package/dist/context-62DC6EC3.js +31 -0
  157. package/dist/council-convene-NJWPNBDU.js +46 -0
  158. package/dist/create-agent-config-ODSQWNVC.js +55 -0
  159. package/dist/default-registry-2PU3BTAU.js +68 -0
  160. package/dist/deliver-task-KONV4C4M.js +57 -0
  161. package/dist/delivery-gate-v2-F2YVMVGK.js +27 -0
  162. package/dist/domain-knowledge-store-DDZ3F4J7.js +11 -0
  163. package/dist/fetch-core-ZPPYDSZH.js +14 -0
  164. package/dist/galaxy-K72BBDQN.js +91 -0
  165. package/dist/goal-criteria-SCALAU2D.js +141 -0
  166. package/dist/goal-persist-XWY2GDQX.js +19 -0
  167. package/dist/goal-tracker-FXMJ2GVK.js +11 -0
  168. package/dist/headless-LSB6I7PT.js +162 -0
  169. package/dist/headless-coordinator-VDPDMVUT.js +90 -0
  170. package/dist/inject-U55SMB6A.js +39 -0
  171. package/dist/login-flow-CD4ZGXOC.js +59 -0
  172. package/dist/logs-cli-SQVYFMMN.js +283 -0
  173. package/dist/loop-ULZYBDA3.js +76 -0
  174. package/dist/main.js +4064 -0
  175. package/dist/manager-ROZBCWPA.js +171 -0
  176. package/dist/manager-Z7XFFUOM.js +10670 -0
  177. package/dist/meridian-indexer-ZIW363L7.js +21 -0
  178. package/dist/native-resolver-PN34UIVV.js +13 -0
  179. package/dist/node_modules/better-sqlite3/lib/database.js +90 -0
  180. package/dist/node_modules/better-sqlite3/lib/index.js +3 -0
  181. package/dist/node_modules/better-sqlite3/lib/methods/aggregate.js +43 -0
  182. package/dist/node_modules/better-sqlite3/lib/methods/backup.js +67 -0
  183. package/dist/node_modules/better-sqlite3/lib/methods/function.js +31 -0
  184. package/dist/node_modules/better-sqlite3/lib/methods/inspect.js +7 -0
  185. package/dist/node_modules/better-sqlite3/lib/methods/pragma.js +12 -0
  186. package/dist/node_modules/better-sqlite3/lib/methods/serialize.js +16 -0
  187. package/dist/node_modules/better-sqlite3/lib/methods/table.js +189 -0
  188. package/dist/node_modules/better-sqlite3/lib/methods/transaction.js +78 -0
  189. package/dist/node_modules/better-sqlite3/lib/methods/wrappers.js +54 -0
  190. package/dist/node_modules/better-sqlite3/lib/sqlite-error.js +20 -0
  191. package/dist/node_modules/better-sqlite3/lib/util.js +12 -0
  192. package/dist/node_modules/better-sqlite3/package.json +59 -0
  193. package/dist/ownership-ledger-E3WIEKPL.js +9 -0
  194. package/dist/package.json +3 -0
  195. package/dist/path-grants-XRRXHXG7.js +40 -0
  196. package/dist/paths-LVV5IMQN.js +49 -0
  197. package/dist/plan-fact-anchors-LMVQZCW5.js +13 -0
  198. package/dist/plan-store-ODLTTPFB.js +17 -0
  199. package/dist/plan-templates-5FPFBOL6.js +109 -0
  200. package/dist/plugin-loader-ZZKX7ZE6.js +22 -0
  201. package/dist/prefix-budget-62OV5HQC.js +13 -0
  202. package/dist/project-trust-5WS5MOMU.js +31 -0
  203. package/dist/provider-cli-ALDQXIT7.js +37 -0
  204. package/dist/providers-XQYTAVPK.js +11 -0
  205. package/dist/proxy-resolver-V2Y6534D.js +15 -0
  206. package/dist/recovery-cli-KPGY6FY3.js +106 -0
  207. package/dist/review-discipline-MNSYCST5.js +55 -0
  208. package/dist/review-router-BVQZW3MX.js +18 -0
  209. package/dist/seed-capsules/seed-capsule-attack-methodology.md +62 -0
  210. package/dist/seed-capsules/seed-capsule-changgeng.md +31 -0
  211. package/dist/seed-capsules/seed-capsule-design-aesthetics.md +38 -0
  212. package/dist/seed-capsules/seed-capsule-diagnostic-ladder.md +54 -0
  213. package/dist/seed-capsules/seed-capsule-fu.md +39 -0
  214. package/dist/seed-capsules/seed-capsule-huagai.md +73 -0
  215. package/dist/seed-capsules/seed-capsule-kaiyang.md +65 -0
  216. package/dist/seed-capsules/seed-capsule-knowledge-work.md +40 -0
  217. package/dist/seed-capsules/seed-capsule-tanlang.md +47 -0
  218. package/dist/seed-capsules/seed-capsule-tianfu.md +23 -0
  219. package/dist/seed-capsules/seed-capsule-tianliang.md +63 -0
  220. package/dist/seed-capsules/seed-capsule-tianquan.md +32 -0
  221. package/dist/seed-capsules/seed-capsule-tianxuan-ccr.md +22 -0
  222. package/dist/seed-capsules/seed-capsule-tianxuan.md +64 -0
  223. package/dist/seed-capsules/seed-capsule-yaoguang.md +87 -0
  224. package/dist/serve-X2R2UTLF.js +170 -0
  225. package/dist/serve-agent-KHSU6RVV.js +965 -0
  226. package/dist/session-persist-HUUC772H.js +37 -0
  227. package/dist/session-registry-6XUD5C4Y.js +15 -0
  228. package/dist/skill-loader-CK3RMO47.js +48 -0
  229. package/dist/skills/cli-harness-sop.md +207 -0
  230. package/dist/spawn-git-4HFU65AH.js +29 -0
  231. package/dist/sse-EYUTBWUK.js +512 -0
  232. package/dist/starflow-NOFBMPFU.js +30 -0
  233. package/dist/streamableHttp-V67CNJMO.js +447 -0
  234. package/dist/task-contract-6XHBNJQK.js +32 -0
  235. package/dist/task-ledger-3K4TJIER.js +9 -0
  236. package/dist/team-orchestrate-S6NHZP7X.js +64 -0
  237. package/dist/title-extract-QX4XGCYN.js +50 -0
  238. package/dist/todo-QDXGRZZP.js +31 -0
  239. package/dist/todo-store-V3TTO5AH.js +12 -0
  240. package/dist/tool-preset-LU5BYEDZ.js +23 -0
  241. package/dist/tool-tiers-GD742YBN.js +23 -0
  242. package/dist/turndown.es-OI55K6C3.js +17373 -0
  243. package/dist/verification-attribution-EKG4CNUV.js +13 -0
  244. package/dist/volatile-git-MBTST7RA.js +15 -0
  245. package/dist/wave-checkpoint-XLIIHXQA.js +30 -0
  246. package/dist/web-cli-DUG4I35O.js +233 -0
  247. package/dist/web-search-3IK542AA.js +34 -0
  248. package/dist/workers/cpu-worker.js +45 -0
  249. package/dist/workflow-runner-HX7UBAYG.js +297 -0
  250. package/dist/worktree-baseline-O5NCU6M2.js +9 -0
  251. package/package.json +122 -0
  252. package/scripts/check-mobile-env.mjs +76 -0
  253. package/scripts/fetch-native-sqlite.js +392 -0
  254. package/scripts/prune-installed-wasms.js +45 -0
  255. package/scripts/tree-sitter-wasm-keep.js +40 -0
@@ -0,0 +1,366 @@
1
+ #!/usr/bin/env -S node --expose-gc --max-old-space-size=4096
2
+ import { createRequire as __rivetCreateRequire } from 'node:module'; const require = __rivetCreateRequire(import.meta.url);
3
+ import {
4
+ getSessionDir
5
+ } from "./chunk-LH5VCGLB.js";
6
+ import {
7
+ TODO_EMPTY_RESULT,
8
+ TodoStore
9
+ } from "./chunk-DEBI37QB.js";
10
+ import {
11
+ external_exports
12
+ } from "./chunk-OO3TAHO5.js";
13
+ import {
14
+ writeFileAtomicSync
15
+ } from "./chunk-A5MNH4ER.js";
16
+ import {
17
+ init_esm_shims
18
+ } from "./chunk-5GGOGLSN.js";
19
+
20
+ // src/tools/todo.ts
21
+ init_esm_shims();
22
+
23
+ // src/tools/todo-deps.ts
24
+ init_esm_shims();
25
+ var DEP_CUE = /(?:基于|依赖|需先|先完成|完成后|建立在|after|depends?\s+on|requires?|blocked\s+by|builds?\s+on|based\s+on)/i;
26
+ function escapeRe(s) {
27
+ return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
28
+ }
29
+ function referencesId(content, id) {
30
+ const escaped = escapeRe(id);
31
+ if (/[A-Za-z]/.test(id)) {
32
+ return new RegExp(`\\b${escaped}\\b`).test(content);
33
+ }
34
+ return new RegExp(`${DEP_CUE.source}\\s*#?${escaped}\\b`, "i").test(content);
35
+ }
36
+ function detectDependencies(todos) {
37
+ const ids = todos.map((t) => t.id);
38
+ return todos.map((t) => {
39
+ const deps = [];
40
+ for (const otherId of ids) {
41
+ if (otherId === t.id) continue;
42
+ if (referencesId(t.content, otherId)) {
43
+ deps.push(otherId);
44
+ }
45
+ }
46
+ return { id: t.id, dependsOn: deps };
47
+ });
48
+ }
49
+ function computeMaxDepth(deps) {
50
+ const depMap = new Map(deps.map((d) => [d.id, d.dependsOn]));
51
+ const cache = /* @__PURE__ */ new Map();
52
+ function depth(id, visiting) {
53
+ if (cache.has(id)) return cache.get(id);
54
+ if (visiting.has(id)) return Infinity;
55
+ visiting.add(id);
56
+ const upstreams = depMap.get(id) ?? [];
57
+ if (upstreams.length === 0) {
58
+ cache.set(id, 0);
59
+ visiting.delete(id);
60
+ return 0;
61
+ }
62
+ let max = 0;
63
+ for (const up of upstreams) {
64
+ const d = depth(up, visiting);
65
+ if (d === Infinity) {
66
+ cache.set(id, Infinity);
67
+ visiting.delete(id);
68
+ return Infinity;
69
+ }
70
+ if (d + 1 > max) max = d + 1;
71
+ }
72
+ cache.set(id, max);
73
+ visiting.delete(id);
74
+ return max;
75
+ }
76
+ let result = 0;
77
+ for (const dep of deps) {
78
+ const d = depth(dep.id, /* @__PURE__ */ new Set());
79
+ if (d === Infinity) return Infinity;
80
+ if (d > result) result = d;
81
+ }
82
+ return result;
83
+ }
84
+ function findExecutable(todos, deps) {
85
+ const completedSet = new Set(
86
+ todos.filter((t) => t.status === "completed").map((t) => t.id)
87
+ );
88
+ const depMap = new Map(deps.map((d) => [d.id, d.dependsOn]));
89
+ return todos.filter((t) => {
90
+ if (t.status !== "pending") return false;
91
+ const upstreams = depMap.get(t.id) ?? [];
92
+ return upstreams.every((dep) => completedSet.has(dep));
93
+ });
94
+ }
95
+ function orderPendingByExecutability(todos, deps) {
96
+ const executableIds = new Set(findExecutable(todos, deps).map((t) => t.id));
97
+ const pending = todos.filter((t) => t.status === "pending");
98
+ const executable = pending.filter((t) => executableIds.has(t.id));
99
+ const blocked = pending.filter((t) => !executableIds.has(t.id));
100
+ return [...executable, ...blocked];
101
+ }
102
+ var SCOPE_PENDING_THRESHOLD = 5;
103
+ var SCOPE_DEPTH_THRESHOLD = 3;
104
+ function assessScopeRisk(todos, deps) {
105
+ const pendingCount = todos.filter((t) => t.status === "pending").length;
106
+ const maxDepth = computeMaxDepth(deps);
107
+ const hasCycle = maxDepth === Infinity;
108
+ const completedSet = new Set(
109
+ todos.filter((t) => t.status === "completed").map((t) => t.id)
110
+ );
111
+ const depMap = new Map(deps.map((d) => [d.id, d.dependsOn]));
112
+ let blockedCount = 0;
113
+ for (const t of todos) {
114
+ if (t.status !== "pending") continue;
115
+ const upstreams = depMap.get(t.id) ?? [];
116
+ if (upstreams.some((dep) => !completedSet.has(dep))) blockedCount++;
117
+ }
118
+ const reasons = [];
119
+ if (pendingCount > SCOPE_PENDING_THRESHOLD) {
120
+ reasons.push(`${pendingCount} \u4E2A\u5F85\u529E\u9879\u4E00\u6B21\u6027\u94FA\u5F00\uFF08\u9608\u503C ${SCOPE_PENDING_THRESHOLD}\uFF09`);
121
+ }
122
+ if (hasCycle) {
123
+ reasons.push("\u5F85\u529E\u4E4B\u95F4\u5B58\u5728\u5FAA\u73AF\u4F9D\u8D56\uFF0C\u65E0\u6CD5\u7EBF\u6027\u63A8\u8FDB");
124
+ } else if (maxDepth > SCOPE_DEPTH_THRESHOLD) {
125
+ reasons.push(`\u4F9D\u8D56\u94FE\u6DF1\u5EA6 ${maxDepth}\uFF08\u9608\u503C ${SCOPE_DEPTH_THRESHOLD}\uFF09`);
126
+ }
127
+ let level = "none";
128
+ if (hasCycle || maxDepth > SCOPE_DEPTH_THRESHOLD || pendingCount > SCOPE_PENDING_THRESHOLD * 2) {
129
+ level = "high";
130
+ } else if (pendingCount > SCOPE_PENDING_THRESHOLD) {
131
+ level = "elevated";
132
+ }
133
+ return { level, pendingCount, maxDepth: hasCycle ? Infinity : maxDepth, blockedCount, hasCycle, reasons };
134
+ }
135
+ function buildScopeNotice(todos, deps, risk) {
136
+ const completedSet = new Set(
137
+ todos.filter((t) => t.status === "completed").map((t) => t.id)
138
+ );
139
+ const depMap = new Map(deps.map((d) => [d.id, d.dependsOn]));
140
+ const blocked = [];
141
+ for (const t of todos) {
142
+ if (t.status !== "pending") continue;
143
+ const upstreams = depMap.get(t.id) ?? [];
144
+ const unmet = upstreams.filter((dep) => !completedSet.has(dep));
145
+ if (unmet.length > 0) {
146
+ blocked.push(` \u26D4 ${t.id} "${t.content.slice(0, 40)}" \u2190 blocked by ${unmet.join(", ")}`);
147
+ }
148
+ }
149
+ if (risk.level === "none" && blocked.length === 0) return null;
150
+ const lines = [];
151
+ if (risk.level === "high") {
152
+ lines.push(`\u26A0\uFE0F \u8303\u56F4\u98CE\u9669\u504F\u9AD8\uFF1A${risk.reasons.join("\uFF1B")}\u3002`);
153
+ lines.push("\u5EFA\u8BAE\u7ACB\u523B\u505C\u4E0B\u6765\u4E0E\u7528\u6237\u786E\u8BA4\u8303\u56F4/\u4F18\u5148\u7EA7\uFF0C\u62C6\u4E3A 2-3 wave \u5206\u6279\u6267\u884C\u3002\u6BCF\u6CE2 typecheck+test \u901A\u8FC7\u540E\u518D\u7EE7\u7EED\u4E0B\u4E00\u6CE2\u3002\u82E5\u5DF2\u4E0E\u7528\u6237\u5BF9\u9F50\uFF0C\u53EF\u7EE7\u7EED\u3002");
154
+ } else if (risk.level === "elevated") {
155
+ lines.push(`\u63D0\u793A\uFF1A${risk.reasons.join("\uFF1B")}\u3002`);
156
+ lines.push("\u5EFA\u8BAE\u63D0\u524D\u62C6\u4E3A 2-3 wave \u5206\u6279\u6267\u884C\uFF0C\u6BCF\u6CE2 typecheck+test \u901A\u8FC7\u540E\u518D\u505A\u4E0B\u4E00\u6CE2\u2014\u2014\u4E0D\u8981\u4E00\u6B21\u6027\u94FA\u5F00\u5168\u90E8\u3002\u82E5\u7528\u6237\u786E\u8BA4\u6241\u5E73\u6267\u884C\uFF0C\u53EF\u7EE7\u7EED\u3002");
157
+ }
158
+ if (blocked.length > 0) {
159
+ lines.push(`\u4F9D\u8D56\u672A\u6EE1\u8DB3 (${blocked.length} \u9879\uFF0C\u4ECD\u4FDD\u7559\u5728\u5217\u8868\u4E2D):`);
160
+ lines.push(...blocked);
161
+ }
162
+ return lines.join("\n");
163
+ }
164
+
165
+ // src/tools/todo.ts
166
+ import { existsSync, readFileSync } from "fs";
167
+ var VALID_STATUSES = ["pending", "in_progress", "completed"];
168
+ var todoItemSchema = external_exports.object({
169
+ id: external_exports.string().min(1),
170
+ content: external_exports.string().min(1),
171
+ status: external_exports.enum(VALID_STATUSES),
172
+ /** 进行中的现在时说法(如「正在修复认证 bug」);缺席时面板回退 content。 */
173
+ activeForm: external_exports.string().min(1).optional()
174
+ });
175
+ var acceptanceItemSchema = external_exports.object({
176
+ criterion: external_exports.string().min(1),
177
+ status: external_exports.enum(["pending", "met", "blocked"]),
178
+ evidence: external_exports.string().optional()
179
+ });
180
+ var todoActionSchema = external_exports.discriminatedUnion("action", [
181
+ external_exports.object({ action: external_exports.literal("read") }),
182
+ external_exports.object({
183
+ action: external_exports.literal("write"),
184
+ todos: external_exports.array(todoItemSchema),
185
+ acceptance: external_exports.array(acceptanceItemSchema).optional()
186
+ })
187
+ ]);
188
+ var defaultStore = new TodoStore();
189
+ function getTodos() {
190
+ return defaultStore.read();
191
+ }
192
+ function getTodoRegressionStats() {
193
+ return defaultStore.getRegressionStats();
194
+ }
195
+ function setTodos(todos) {
196
+ defaultStore.write(todos);
197
+ persistTodos();
198
+ }
199
+ var todoSessionId;
200
+ var todoCwd;
201
+ function setTodoSession(sessionId, cwd) {
202
+ todoSessionId = sessionId;
203
+ todoCwd = cwd;
204
+ }
205
+ function todoPersistPath() {
206
+ if (!todoSessionId || !todoCwd) return void 0;
207
+ return `${getSessionDir(todoCwd)}/${todoSessionId}.todos.json`;
208
+ }
209
+ function persistTodos() {
210
+ const path = todoPersistPath();
211
+ if (!path) return;
212
+ try {
213
+ writeFileAtomicSync(path, JSON.stringify(defaultStore.read(), null, 2) + "\n");
214
+ } catch {
215
+ }
216
+ }
217
+ function loadTodos(sessionId, cwd) {
218
+ const path = `${getSessionDir(cwd)}/${sessionId}.todos.json`;
219
+ if (!existsSync(path)) return null;
220
+ try {
221
+ const raw = JSON.parse(readFileSync(path, "utf-8"));
222
+ if (Array.isArray(raw)) {
223
+ defaultStore.write(raw);
224
+ return raw;
225
+ }
226
+ } catch {
227
+ }
228
+ return null;
229
+ }
230
+ function createTodoTool(store = defaultStore) {
231
+ return {
232
+ definition: {
233
+ name: "todo",
234
+ description: `\u8BFB\u5199\u4F1A\u8BDD\u4EFB\u52A1\u6E05\u5355\u2014\u2014\u4F60\u7684\u76EE\u6807\u5206\u89E3\u3002\u4E3B\u52A8\u4F7F\u7528\u5B83\u3002
235
+
236
+ Actions:
237
+ - write: \u6574\u4F53\u66FF\u6362\u6E05\u5355\uFF08\u5168\u91CF\u66FF\u6362\uFF0C\u4E0D\u662F\u8865\u4E01\uFF09\u3002\u6BCF\u9879\u542B id\u3001content\u3001status\uFF08pending/in_progress/completed\uFF09\u3002\u5DF2\u5B8C\u6210\u9879\u4E5F\u8981\u91CD\u53D1\uFF0C\u5426\u5219\u4E22\u5931\u3002
238
+ - read: \u8FD4\u56DE\u5F53\u524D\u6E05\u5355\u3002
239
+
240
+ \u4F55\u65F6\u521B\u5EFA/\u66F4\u65B0\uFF08\u4E0D\u7528\u7B49\u7528\u6237\u8981\u6C42\uFF09\uFF1A
241
+ - \u4EFB\u52A1\u9700\u8981 3 \u4E2A\u4EE5\u4E0A\u4E0D\u540C\u6B65\u9AA4\uFF0C\u6216\u975E\u5E73\u51E1/\u8DE8\u591A\u6587\u4EF6\u3002
242
+ - \u7528\u6237\u4E00\u6B21\u7ED9\u591A\u4E2A\u4EFB\u52A1\uFF08\u7F16\u53F7\u6216\u9017\u53F7\u5206\u9694\u7684\u6E05\u5355\uFF09\u3002
243
+ - \u6536\u5230\u65B0\u6307\u4EE4\u540E\u7ACB\u5373\u5EFA\u2014\u2014\u5148\u843D\u6210 todo\uFF0C\u518D\u5F00\u5DE5\u3002
244
+
245
+ \u4F55\u65F6\u4E0D\u7528\uFF1A\u5355\u6B65\u7410\u788E\u64CD\u4F5C\uFF08\u4E00\u6B21\u6027\u5C0F\u7F16\u8F91\u522B\u52A0\u4EEA\u5F0F\uFF09\u3002
246
+
247
+ Plan mode \u4E0B\uFF1A\u7528 todo \u8DDF\u8E2A\u8C03\u7814\u6B65\u9AA4\uFF08\u6700\u540E\u4E00\u9879\u56FA\u5B9A\u4E3A\u300C\u6C47\u603B\u5199\u8BA1\u5212\u5E76\u63D0\u4EA4\u5BA1\u6279\u300D\uFF09\uFF1B\u8BA1\u5212\u6B63\u6587\u5199\u6D3B\u52A8\u8BA1\u5212\u6587\u4EF6\uFF0C\u4E0D\u8FDB todo\u3002
248
+
249
+ TDD \u7EAA\u5F8B\uFF1A
250
+ - \u4EE3\u7801\u4EFB\u52A1\uFF08\u975E\u6587\u6863/\u914D\u7F6E\uFF09\u6BCF\u4E2A\u4EFB\u52A1\u7684\u7B2C\u4E00\u6B65\u5E94\u662F\u5199\u6216\u66F4\u65B0\u6D4B\u8BD5\uFF08RED\uFF09\uFF0C\u518D\u5B9E\u73B0\u901A\u8FC7\uFF08GREEN\uFF09\u3002todo \u7ED3\u6784\u4F53\u73B0\u8FD9\u4E00\u70B9\uFF1A\u5982\u300C\u5199 X \u7684\u6D4B\u8BD5\u300D\u2192\u300C\u5B9E\u73B0 X\u300D\u2192\u300C\u91CD\u6784\u300D\u3002
251
+ - \u4EE5\u4E0B\u4E0D\u5F3A\u5236\uFF1A\u6587\u6863\u3001\u914D\u7F6E\u6539\u52A8\u3001\u5DF2\u6709\u6D4B\u8BD5\u8986\u76D6\u7684\u91CD\u6784\u3001\u5FEB\u901F typo \u4FEE\u590D\u3002
252
+
253
+ \u72B6\u6001\u89C4\u5219\uFF1A
254
+ - \u5F00\u5DE5\u524D\u628A\u4EFB\u52A1\u6807\u4E3A in_progress\uFF1B\u4EFB\u4F55\u65F6\u523B\u6070\u597D\u53EA\u6709\u4E00\u4E2A in_progress\u3002
255
+ - \u5B8C\u6210\u7ACB\u5373\u6807 completed\u2014\u2014\u4E0D\u8981\u6512\u6279\u3002
256
+ - \u91CD\u5199\u6E05\u5355\u65F6\u4E0D\u8981\u9759\u9ED8\u4E22\u5F03\u6216\u91CD\u7F6E\u5DF2\u5B8C\u6210\u9879\u3002
257
+
258
+ \u9A8C\u6536\u9762\uFF1A\u4EE3\u7801\u4EFB\u52A1\u9996\u6B21 write \u65F6\u7528 acceptance \u5B57\u6BB5\u58F0\u660E\u53EF\u89C2\u5BDF\u7684\u5B8C\u6210\u6807\u5FD7\uFF08\u5F62\u72B6\u4E0E\u6B63\u53CD\u4F8B\u89C1\u8BE5\u5B57\u6BB5\u8BF4\u660E\uFF09\u3002`,
259
+ input_schema: {
260
+ type: "object",
261
+ properties: {
262
+ action: {
263
+ type: "string",
264
+ enum: ["read", "write"],
265
+ description: "read \u8BFB\u5F53\u524D\u6E05\u5355\uFF1Bwrite \u5199\u65B0\u6E05\u5355"
266
+ },
267
+ todos: {
268
+ type: "array",
269
+ description: "\u5B8C\u6574 todo \u6E05\u5355\uFF08\u4EC5 write \u7528\uFF09",
270
+ items: {
271
+ type: "object",
272
+ properties: {
273
+ id: { type: "string", description: "\u4EFB\u52A1\u552F\u4E00\u6807\u8BC6" },
274
+ content: { type: "string", description: "\u4EFB\u52A1\u63CF\u8FF0\uFF08\u7948\u4F7F\u5F0F\uFF0C\u5982\u300C\u4FEE\u590D\u8BA4\u8BC1 bug\u300D\uFF09" },
275
+ status: { type: "string", enum: [...VALID_STATUSES], description: "\u4EFB\u52A1\u72B6\u6001" },
276
+ activeForm: { type: "string", description: "\u8FDB\u884C\u4E2D\u7684\u73B0\u5728\u65F6\u8BF4\u6CD5\uFF08\u5982\u300C\u6B63\u5728\u4FEE\u590D\u8BA4\u8BC1 bug\u300D\uFF09\uFF1B\u53EF\u9009\uFF0C\u7F3A\u7701\u65F6\u9762\u677F\u663E\u793A content" }
277
+ },
278
+ required: ["id", "content", "status"]
279
+ }
280
+ },
281
+ acceptance: {
282
+ type: "array",
283
+ description: "\u7528\u6237\u7EA7\u9A8C\u6536\u9762\uFF08\u53EF\u9009\uFF0C\u4EE3\u7801\u4EFB\u52A1\u5EFA\u8BAE\u9996\u6B21 write \u5C31\u5E26\uFF1B\u58F0\u660E\u987B\u65E9\u4E8E\u9A8C\u8BC1\uFF09\u3002\u6B63\u4F8B\u300C\u6309 ESC \u540E\u5F39\u7A97 isVisible() \u4E3A False\u300D\u3002\u53CD\u4F8B\u4E00\u5F8B\u62D2\u7EDD\uFF1A\u300C\u4FE1\u53F7\u8FDE\u901A\u300D\u300C\u51FD\u6570\u903B\u8F91\u6B63\u786E\u300D\u662F\u5185\u90E8\u5C5E\u6027\uFF1B\u300C\u6240\u6709\u6D4B\u8BD5\u901A\u8FC7\u300D\u300C\u8DD1 test_x.py \u770B\u5230 3 passed\u300D\u662F\u4FE1\u53F7\u7EA7\u2014\u2014\u5355\u6D4B\u8986\u76D6\u7684\u662F\u51FD\u6570\u5206\u652F\uFF0C\u4E0D\u662F\u7528\u6237\u6309\u952E\u540E\u7684\u884C\u4E3A\u3002",
284
+ items: {
285
+ type: "object",
286
+ properties: {
287
+ criterion: { type: "string", description: "\u7528\u6237\u505A\u4EC0\u4E48\u52A8\u4F5C \u2192 \u770B\u5230\u4EC0\u4E48\u53EF\u89C2\u5BDF\u7ED3\u679C" },
288
+ status: { type: "string", enum: ["pending", "met", "blocked"] },
289
+ evidence: { type: "string", description: "met\uFF1A\u5B9E\u9645\u505A\u4E86\u4EC0\u4E48\u3001\u89C2\u5BDF\u5230\u4EC0\u4E48\uFF1Bblocked\uFF1A\u4E3A\u4F55\u6267\u884C\u4E0D\u4E86" }
290
+ },
291
+ required: ["criterion", "status"]
292
+ }
293
+ }
294
+ },
295
+ required: ["action"]
296
+ }
297
+ },
298
+ async execute(params) {
299
+ const parsed = todoActionSchema.safeParse(params.input);
300
+ if (!parsed.success) {
301
+ return { content: `\u65E0\u6548\u8F93\u5165\uFF1A${parsed.error.message}`, isError: true, errorKind: "format_error" };
302
+ }
303
+ const data = parsed.data;
304
+ if (data.action === "read") {
305
+ const todos = store.read();
306
+ if (todos.length === 0) {
307
+ return { content: TODO_EMPTY_RESULT };
308
+ }
309
+ return { content: TodoStore.formatList(todos) };
310
+ }
311
+ const detection = store.detectRegressions(data.todos);
312
+ store.recordWrite(detection);
313
+ store.write(data.todos);
314
+ if (params.onPlanSteps && data.todos.length > 0) {
315
+ params.onPlanSteps(data.todos.map((t) => ({ id: t.id, content: t.content, status: t.status })));
316
+ }
317
+ if (params.onAcceptance && data.acceptance && data.acceptance.length > 0) {
318
+ params.onAcceptance(data.acceptance);
319
+ }
320
+ const summary = TodoStore.formatSummary(data.todos);
321
+ let content = summary;
322
+ const deps = detectDependencies(data.todos);
323
+ const risk = assessScopeRisk(data.todos, deps);
324
+ const notice = buildScopeNotice(data.todos, deps, risk);
325
+ if (notice) {
326
+ content += "\n\n" + notice;
327
+ }
328
+ if (detection.regressed.length > 0) {
329
+ const warn = detection.regressed.map((r) => ` - ${r}`).join("\n");
330
+ content = `\u26A0\uFE0F ${detection.regressed.length} \u9879\u6B64\u524D\u5DF2\u5B8C\u6210\u7684\u4EFB\u52A1\u88AB\u91CD\u7F6E\u6216\u79FB\u9664\uFF1A
331
+ ${warn}
332
+
333
+ \u82E5\u975E\u6709\u610F\u4E3A\u4E4B\uFF08\u4F8B\u5982\u957F\u4EFB\u52A1\u540E\u51ED\u8BB0\u5FC6\u91CD\u5EFA\u6E05\u5355\uFF09\uFF0C\u8BF7\u91CD\u65B0\u6807\u4E3A completed\u3002\u4E0D\u8981\u91CD\u505A\u5DF2\u5B8C\u6210\u7684\u5DE5\u4F5C\u3002
334
+
335
+ ${content}`;
336
+ }
337
+ if (data.acceptance && data.acceptance.length > 0) {
338
+ const met = data.acceptance.filter((a) => a.status === "met").length;
339
+ const blocked = data.acceptance.filter((a) => a.status === "blocked").length;
340
+ const pending = data.acceptance.length - met - blocked;
341
+ content += `
342
+
343
+ \u9A8C\u6536\u9762 ${met}/${data.acceptance.length} \u8FBE\u6807` + (pending > 0 ? `\uFF0C${pending} \u9879\u5F85\u6267\u884C` : "") + (blocked > 0 ? `\uFF0C${blocked} \u9879\u53D7\u963B\uFF08\u4EA4\u4ED8\u65F6\u987B\u62AB\u9732\uFF09` : "") + "\u3002";
344
+ }
345
+ content += "\n\n\u7EE7\u7EED\u7528 todo \u8DDF\u8E2A\u8FDB\u5EA6\u2014\u2014\u5B8C\u6210\u5373\u6807 completed\uFF0C\u4FDD\u6301\u6070\u597D\u4E00\u4E2A in_progress\u3002";
346
+ return { content };
347
+ },
348
+ requiresApproval: () => false,
349
+ isConcurrencySafe: () => true,
350
+ isEnabled: () => true
351
+ };
352
+ }
353
+ var TODO_TOOL = createTodoTool();
354
+
355
+ export {
356
+ detectDependencies,
357
+ orderPendingByExecutability,
358
+ defaultStore,
359
+ getTodos,
360
+ getTodoRegressionStats,
361
+ setTodos,
362
+ setTodoSession,
363
+ loadTodos,
364
+ createTodoTool,
365
+ TODO_TOOL
366
+ };
@@ -0,0 +1,280 @@
1
+ #!/usr/bin/env -S node --expose-gc --max-old-space-size=4096
2
+ import { createRequire as __rivetCreateRequire } from 'node:module'; const require = __rivetCreateRequire(import.meta.url);
3
+ import {
4
+ init_esm_shims
5
+ } from "./chunk-5GGOGLSN.js";
6
+
7
+ // src/tools/worker-activity-stream.ts
8
+ init_esm_shims();
9
+ function shortOrderLabel(workOrderId) {
10
+ const seg = workOrderId.split(":").pop() ?? workOrderId;
11
+ return seg.replace(/^wo_/, "").slice(0, 12);
12
+ }
13
+ function progressSnippet(text, max = 80) {
14
+ return text.replace(/\s+/g, " ").trim().slice(0, max);
15
+ }
16
+ function terminalActivity(result, parentToolId, objective, opts) {
17
+ const identity = result;
18
+ const authority = opts && "authority" in opts ? opts.authority : result.authority;
19
+ return {
20
+ workOrderId: result.workOrderId,
21
+ parentToolId,
22
+ ...identity.dispatchId ? { dispatchId: identity.dispatchId } : {},
23
+ ...identity.attemptId ? { attemptId: identity.attemptId } : {},
24
+ ...identity.parentAttemptId ? { parentAttemptId: identity.parentAttemptId } : {},
25
+ ...opts?.omitProfile ? {} : { profile: result.profile ?? opts?.profileFallback },
26
+ authority,
27
+ objective,
28
+ status: result.status === "passed" ? "completed" : result.status,
29
+ progressLine: progressSnippet(result.summary),
30
+ summary: result.summary,
31
+ failureReason: result.failureReason,
32
+ model: result.model,
33
+ provider: result.provider,
34
+ usage: result.usage,
35
+ ...opts?.omitArtifacts ? {} : {
36
+ artifactId: result.diffArtifactId,
37
+ changedFiles: result.changedFiles.length > 0 ? result.changedFiles : void 0
38
+ },
39
+ findingsCount: result.findings.length > 0 ? result.findings.length : void 0,
40
+ topFinding: result.findings[0]?.claim,
41
+ verificationBrief: result.verification ? { status: result.verification.status, passed: result.verification.passed, failed: result.verification.failed } : void 0,
42
+ evidenceStatus: result.evidenceStatus
43
+ };
44
+ }
45
+ function activityProgressLine(event) {
46
+ if (event.kind === "tool_use") return `\u2699 ${event.detail ? progressSnippet(event.detail, 60) : "\u5DE5\u5177\u8C03\u7528"}`;
47
+ if (event.kind === "tool_result") return `\u2713 ${event.detail ? progressSnippet(event.detail, 50) : "\u5B8C\u6210"}`;
48
+ if (event.kind === "thinking") return "\u601D\u8003\u4E2D";
49
+ if (event.kind === "retry") return "\u21BB \u4E0A\u6E38\u91CD\u8BD5";
50
+ if (event.kind === "lifecycle") return event.detail ? `\u21BB ${progressSnippet(event.detail, 60)}` : "\u21BB \u8865\u507F\u8F6E";
51
+ if (event.kind === "turn") return "";
52
+ return "\u5199\u5165\u4E2D";
53
+ }
54
+ var DEFAULT_COALESCE_MS = 120;
55
+ function activityAttemptKey(activity) {
56
+ if (activity.attemptId) return `attempt:${activity.attemptId}`;
57
+ if (activity.dispatchId) return `dispatch:${activity.dispatchId}:${activity.workOrderId}`;
58
+ return `legacy:${activity.workOrderId}`;
59
+ }
60
+ var defaultActivityScheduler = {
61
+ setTimeout: (callback, ms) => setTimeout(callback, ms),
62
+ clearTimeout: (handle) => clearTimeout(handle)
63
+ };
64
+ function createDelegationActivityMapper(parentToolId, onWorkerActivity, opts) {
65
+ const counters = /* @__PURE__ */ new Map();
66
+ const objectiveSent = /* @__PURE__ */ new Set();
67
+ const contractSent = /* @__PURE__ */ new Set();
68
+ const coalesceMs = opts?.coalesceMs ?? DEFAULT_COALESCE_MS;
69
+ const scheduler = opts?.scheduler ?? defaultActivityScheduler;
70
+ const pending = /* @__PURE__ */ new Map();
71
+ const sealed = /* @__PURE__ */ new Set();
72
+ const sealedWorkers = /* @__PURE__ */ new Set();
73
+ const finished = /* @__PURE__ */ new Set();
74
+ const attemptOwners = /* @__PURE__ */ new Map();
75
+ let disposed = false;
76
+ const counterOf = (attemptKey) => {
77
+ let c = counters.get(attemptKey);
78
+ if (!c) {
79
+ c = { toolUseCount: 0, tokenCount: 0 };
80
+ counters.set(attemptKey, c);
81
+ }
82
+ return c;
83
+ };
84
+ const safeEmit = (activity) => {
85
+ if (disposed) return false;
86
+ try {
87
+ onWorkerActivity(activity);
88
+ return true;
89
+ } catch {
90
+ return false;
91
+ }
92
+ };
93
+ const emitRunning = (event, detail) => {
94
+ const attemptKey = activityAttemptKey(event);
95
+ const c = counterOf(attemptKey);
96
+ const line = activityProgressLine(event);
97
+ let objective;
98
+ let contract;
99
+ if (!objectiveSent.has(attemptKey)) {
100
+ objective = event.objective ?? opts?.objectiveOf?.(event.workOrderId);
101
+ if (objective) objectiveSent.add(attemptKey);
102
+ }
103
+ if (!contractSent.has(attemptKey)) {
104
+ contract = event.contract ?? opts?.contractOf?.(event.workOrderId);
105
+ if (contract) contractSent.add(attemptKey);
106
+ }
107
+ const identity = event;
108
+ safeEmit({
109
+ workOrderId: event.workOrderId,
110
+ parentToolId,
111
+ ...identity.attemptId ? { attemptId: identity.attemptId } : {},
112
+ ...identity.dispatchId ? { dispatchId: identity.dispatchId } : {},
113
+ ...identity.parentAttemptId ? { parentAttemptId: identity.parentAttemptId } : {},
114
+ profile: event.profile,
115
+ authority: event.authority,
116
+ authorityReason: event.authorityReason,
117
+ status: "running",
118
+ ...objective ? { objective } : {},
119
+ progressLine: line || void 0,
120
+ toolUseCount: c.toolUseCount,
121
+ tokenCount: c.tokenCount > 0 ? c.tokenCount : void 0,
122
+ eventKind: event.kind,
123
+ eventDetail: detail,
124
+ ...contract ? { contract } : {}
125
+ });
126
+ };
127
+ const cancelSlotTimer = (slot) => {
128
+ slot.timerGeneration += 1;
129
+ if (slot.timer === void 0) return;
130
+ scheduler.clearTimeout(slot.timer);
131
+ slot.timer = void 0;
132
+ };
133
+ const flushPending = (attemptKey, expectedSlot, allowSealed = false) => {
134
+ const slot = pending.get(attemptKey);
135
+ if (!slot || expectedSlot && slot !== expectedSlot) return;
136
+ cancelSlotTimer(slot);
137
+ pending.delete(attemptKey);
138
+ if (disposed || !allowSealed && sealed.has(attemptKey)) return;
139
+ const merged = { ...slot.base };
140
+ if (slot.objective !== void 0) merged.objective = slot.objective;
141
+ if (slot.contract !== void 0) merged.contract = slot.contract;
142
+ emitRunning(merged, slot.parts.join(""));
143
+ };
144
+ const flush = (workOrderId) => {
145
+ if (disposed) return;
146
+ if (workOrderId !== void 0) {
147
+ for (const [attemptKey, slot] of [...pending.entries()]) {
148
+ if (slot.base.workOrderId === workOrderId) flushPending(attemptKey);
149
+ }
150
+ return;
151
+ }
152
+ for (const attemptKey of [...pending.keys()]) flushPending(attemptKey);
153
+ };
154
+ const sealAttempt = (attemptKey) => {
155
+ if (disposed || sealed.has(attemptKey)) return;
156
+ sealed.add(attemptKey);
157
+ flushPending(attemptKey, void 0, true);
158
+ counters.delete(attemptKey);
159
+ objectiveSent.delete(attemptKey);
160
+ contractSent.delete(attemptKey);
161
+ };
162
+ const seal = (workOrderId) => {
163
+ if (disposed) return;
164
+ sealedWorkers.add(workOrderId);
165
+ const keys = [...attemptOwners.entries()].filter(([, owner]) => owner === workOrderId).map(([attemptKey]) => attemptKey);
166
+ if (keys.length === 0) keys.push(activityAttemptKey({ workOrderId }));
167
+ for (const attemptKey of keys) sealAttempt(attemptKey);
168
+ };
169
+ const finish = (activity) => {
170
+ if (disposed) return;
171
+ const attemptKey = activityAttemptKey(activity);
172
+ attemptOwners.set(attemptKey, activity.workOrderId);
173
+ if (activity.status === "running" || finished.has(attemptKey)) return;
174
+ sealAttempt(attemptKey);
175
+ if (safeEmit(activity)) finished.add(attemptKey);
176
+ };
177
+ const dispose = () => {
178
+ if (disposed) return;
179
+ disposed = true;
180
+ for (const slot of pending.values()) cancelSlotTimer(slot);
181
+ pending.clear();
182
+ counters.clear();
183
+ objectiveSent.clear();
184
+ contractSent.clear();
185
+ sealed.clear();
186
+ sealedWorkers.clear();
187
+ finished.clear();
188
+ attemptOwners.clear();
189
+ };
190
+ const mapper = ((event) => {
191
+ if (disposed) return;
192
+ const attemptKey = activityAttemptKey(event);
193
+ attemptOwners.set(attemptKey, event.workOrderId);
194
+ if (sealedWorkers.has(event.workOrderId) || sealed.has(attemptKey)) return;
195
+ if (event.kind === "text" || event.kind === "thinking") {
196
+ const cur = pending.get(attemptKey);
197
+ if (cur && cur.kind !== event.kind) flushPending(attemptKey);
198
+ let slot = pending.get(attemptKey);
199
+ if (!slot) {
200
+ slot = { timerGeneration: 0, kind: event.kind, parts: [], base: event };
201
+ pending.set(attemptKey, slot);
202
+ }
203
+ if (event.detail) slot.parts.push(event.detail);
204
+ if (slot.objective === void 0 && event.objective !== void 0) slot.objective = event.objective;
205
+ if (slot.contract === void 0 && event.contract !== void 0) slot.contract = event.contract;
206
+ cancelSlotTimer(slot);
207
+ const generation = ++slot.timerGeneration;
208
+ const expectedSlot = slot;
209
+ let timer;
210
+ timer = scheduler.setTimeout(() => {
211
+ if (disposed || sealedWorkers.has(event.workOrderId) || sealed.has(attemptKey)) return;
212
+ if (pending.get(attemptKey) !== expectedSlot) return;
213
+ if (expectedSlot.timerGeneration !== generation || expectedSlot.timer !== timer) return;
214
+ flushPending(attemptKey, expectedSlot);
215
+ }, coalesceMs);
216
+ slot.timer = timer;
217
+ timer?.unref?.();
218
+ return;
219
+ }
220
+ flushPending(attemptKey);
221
+ const c = counterOf(attemptKey);
222
+ if (event.kind === "tool_use") c.toolUseCount += 1;
223
+ if (event.kind === "turn") {
224
+ const n = Number(event.detail);
225
+ if (Number.isFinite(n) && n > c.tokenCount) c.tokenCount = n;
226
+ }
227
+ emitRunning(event, event.detail);
228
+ });
229
+ mapper.flush = flush;
230
+ mapper.seal = seal;
231
+ mapper.finish = finish;
232
+ mapper.dispose = dispose;
233
+ return mapper;
234
+ }
235
+ function createActivityStreamer(emit, _opts) {
236
+ const textSeen = /* @__PURE__ */ new Set();
237
+ const retrySeen = /* @__PURE__ */ new Set();
238
+ return (event) => {
239
+ if (event.kind === "turn") return;
240
+ const label = `${shortOrderLabel(event.workOrderId)}\xB7${event.profile}`;
241
+ if (event.kind === "tool_use") {
242
+ const toolDetail = event.detail ? ` ${progressSnippet(event.detail, 60)}` : "";
243
+ emit(` \u21B3 [${label}] \u2699${toolDetail}
244
+ `);
245
+ return;
246
+ }
247
+ if (event.kind === "tool_result") {
248
+ const resultHint = event.detail ? ` (${progressSnippet(event.detail, 40)})` : "";
249
+ emit(` \u21B3 [${label}] \u2713 \u5B8C\u6210${resultHint}
250
+ `);
251
+ return;
252
+ }
253
+ if (event.kind === "lifecycle") {
254
+ if (event.detail) emit(` \u21B3 [${label}] \u21BB ${progressSnippet(event.detail, 60)}
255
+ `);
256
+ return;
257
+ }
258
+ if (event.kind === "retry") {
259
+ if (!retrySeen.has(event.workOrderId)) {
260
+ retrySeen.add(event.workOrderId);
261
+ emit(` \u21B3 [${label}] \u21BB \u4E0A\u6E38\u91CD\u8BD5\u4E2D
262
+ `);
263
+ }
264
+ return;
265
+ }
266
+ if (!textSeen.has(event.workOrderId)) {
267
+ textSeen.add(event.workOrderId);
268
+ const glyph = event.kind === "thinking" ? "\u601D\u8003\u4E2D" : "\u5199\u4F5C\u4E2D";
269
+ emit(` \u21B3 [${label}] \u270E ${glyph}
270
+ `);
271
+ }
272
+ };
273
+ }
274
+
275
+ export {
276
+ shortOrderLabel,
277
+ terminalActivity,
278
+ createDelegationActivityMapper,
279
+ createActivityStreamer
280
+ };