@qlingzzy/qling 1.0.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 (512) hide show
  1. package/CHANGELOG.md +122 -0
  2. package/LICENSE +21 -0
  3. package/README.en.md +129 -0
  4. package/README.md +416 -0
  5. package/dist/agent/subtask.d.ts +21 -0
  6. package/dist/agent/subtask.d.ts.map +1 -0
  7. package/dist/agent/subtask.js +55 -0
  8. package/dist/agent-loop.d.ts +151 -0
  9. package/dist/agent-loop.d.ts.map +1 -0
  10. package/dist/agent-loop.js +1498 -0
  11. package/dist/agents/isolation-policy.d.ts +14 -0
  12. package/dist/agents/isolation-policy.d.ts.map +1 -0
  13. package/dist/agents/isolation-policy.js +52 -0
  14. package/dist/channels/console-channel.d.ts +15 -0
  15. package/dist/channels/console-channel.d.ts.map +1 -0
  16. package/dist/channels/console-channel.js +66 -0
  17. package/dist/channels/registry.d.ts +10 -0
  18. package/dist/channels/registry.d.ts.map +1 -0
  19. package/dist/channels/registry.js +25 -0
  20. package/dist/channels/slack-channel.d.ts +35 -0
  21. package/dist/channels/slack-channel.d.ts.map +1 -0
  22. package/dist/channels/slack-channel.js +232 -0
  23. package/dist/channels/telegram-channel.d.ts +32 -0
  24. package/dist/channels/telegram-channel.d.ts.map +1 -0
  25. package/dist/channels/telegram-channel.js +167 -0
  26. package/dist/channels/types.d.ts +31 -0
  27. package/dist/channels/types.d.ts.map +1 -0
  28. package/dist/channels/types.js +4 -0
  29. package/dist/cli/bootstrap.d.ts +39 -0
  30. package/dist/cli/bootstrap.d.ts.map +1 -0
  31. package/dist/cli/bootstrap.js +138 -0
  32. package/dist/cli/channel-bootstrap.d.ts +23 -0
  33. package/dist/cli/channel-bootstrap.d.ts.map +1 -0
  34. package/dist/cli/channel-bootstrap.js +46 -0
  35. package/dist/cli/daemon-control.d.ts +31 -0
  36. package/dist/cli/daemon-control.d.ts.map +1 -0
  37. package/dist/cli/daemon-control.js +177 -0
  38. package/dist/cli/guidance-panel.d.ts +11 -0
  39. package/dist/cli/guidance-panel.d.ts.map +1 -0
  40. package/dist/cli/guidance-panel.js +16 -0
  41. package/dist/cli/mcp-control.d.ts +7 -0
  42. package/dist/cli/mcp-control.d.ts.map +1 -0
  43. package/dist/cli/mcp-control.js +119 -0
  44. package/dist/cli/mission-views.d.ts +13 -0
  45. package/dist/cli/mission-views.d.ts.map +1 -0
  46. package/dist/cli/mission-views.js +82 -0
  47. package/dist/cli/setup.d.ts +9 -0
  48. package/dist/cli/setup.d.ts.map +1 -0
  49. package/dist/cli/setup.js +140 -0
  50. package/dist/cli/startup-contract.d.ts +23 -0
  51. package/dist/cli/startup-contract.d.ts.map +1 -0
  52. package/dist/cli/startup-contract.js +694 -0
  53. package/dist/commands/agents.d.ts +3 -0
  54. package/dist/commands/agents.d.ts.map +1 -0
  55. package/dist/commands/agents.js +44 -0
  56. package/dist/commands/checkpoint.d.ts +3 -0
  57. package/dist/commands/checkpoint.d.ts.map +1 -0
  58. package/dist/commands/checkpoint.js +52 -0
  59. package/dist/commands/claude-style.d.ts +12 -0
  60. package/dist/commands/claude-style.d.ts.map +1 -0
  61. package/dist/commands/claude-style.js +560 -0
  62. package/dist/commands/clear.d.ts +3 -0
  63. package/dist/commands/clear.d.ts.map +1 -0
  64. package/dist/commands/clear.js +20 -0
  65. package/dist/commands/compact.d.ts +3 -0
  66. package/dist/commands/compact.d.ts.map +1 -0
  67. package/dist/commands/compact.js +23 -0
  68. package/dist/commands/config.d.ts +3 -0
  69. package/dist/commands/config.d.ts.map +1 -0
  70. package/dist/commands/config.js +22 -0
  71. package/dist/commands/connect.d.ts +3 -0
  72. package/dist/commands/connect.d.ts.map +1 -0
  73. package/dist/commands/connect.js +102 -0
  74. package/dist/commands/context.d.ts +3 -0
  75. package/dist/commands/context.d.ts.map +1 -0
  76. package/dist/commands/context.js +13 -0
  77. package/dist/commands/dashboard.d.ts +3 -0
  78. package/dist/commands/dashboard.d.ts.map +1 -0
  79. package/dist/commands/dashboard.js +22 -0
  80. package/dist/commands/detach.d.ts +3 -0
  81. package/dist/commands/detach.d.ts.map +1 -0
  82. package/dist/commands/detach.js +44 -0
  83. package/dist/commands/distill.d.ts +3 -0
  84. package/dist/commands/distill.d.ts.map +1 -0
  85. package/dist/commands/distill.js +23 -0
  86. package/dist/commands/doctor.d.ts +3 -0
  87. package/dist/commands/doctor.d.ts.map +1 -0
  88. package/dist/commands/doctor.js +13 -0
  89. package/dist/commands/dream.d.ts +3 -0
  90. package/dist/commands/dream.d.ts.map +1 -0
  91. package/dist/commands/dream.js +59 -0
  92. package/dist/commands/export.d.ts +3 -0
  93. package/dist/commands/export.d.ts.map +1 -0
  94. package/dist/commands/export.js +18 -0
  95. package/dist/commands/exports.d.ts +3 -0
  96. package/dist/commands/exports.d.ts.map +1 -0
  97. package/dist/commands/exports.js +15 -0
  98. package/dist/commands/goal.d.ts +3 -0
  99. package/dist/commands/goal.d.ts.map +1 -0
  100. package/dist/commands/goal.js +147 -0
  101. package/dist/commands/help.d.ts +4 -0
  102. package/dist/commands/help.d.ts.map +1 -0
  103. package/dist/commands/help.js +75 -0
  104. package/dist/commands/hooks.d.ts +3 -0
  105. package/dist/commands/hooks.d.ts.map +1 -0
  106. package/dist/commands/hooks.js +14 -0
  107. package/dist/commands/index.d.ts +29 -0
  108. package/dist/commands/index.d.ts.map +1 -0
  109. package/dist/commands/index.js +417 -0
  110. package/dist/commands/knowledge.d.ts +8 -0
  111. package/dist/commands/knowledge.d.ts.map +1 -0
  112. package/dist/commands/knowledge.js +191 -0
  113. package/dist/commands/loop.d.ts +3 -0
  114. package/dist/commands/loop.d.ts.map +1 -0
  115. package/dist/commands/loop.js +138 -0
  116. package/dist/commands/mcp.d.ts +3 -0
  117. package/dist/commands/mcp.d.ts.map +1 -0
  118. package/dist/commands/mcp.js +57 -0
  119. package/dist/commands/memory.d.ts +3 -0
  120. package/dist/commands/memory.d.ts.map +1 -0
  121. package/dist/commands/memory.js +215 -0
  122. package/dist/commands/mission.d.ts +3 -0
  123. package/dist/commands/mission.d.ts.map +1 -0
  124. package/dist/commands/mission.js +129 -0
  125. package/dist/commands/permissions.d.ts +3 -0
  126. package/dist/commands/permissions.d.ts.map +1 -0
  127. package/dist/commands/permissions.js +82 -0
  128. package/dist/commands/privacy.d.ts +3 -0
  129. package/dist/commands/privacy.d.ts.map +1 -0
  130. package/dist/commands/privacy.js +13 -0
  131. package/dist/commands/recap.d.ts +3 -0
  132. package/dist/commands/recap.d.ts.map +1 -0
  133. package/dist/commands/recap.js +11 -0
  134. package/dist/commands/repomap.d.ts +3 -0
  135. package/dist/commands/repomap.d.ts.map +1 -0
  136. package/dist/commands/repomap.js +146 -0
  137. package/dist/commands/resume.d.ts +3 -0
  138. package/dist/commands/resume.d.ts.map +1 -0
  139. package/dist/commands/resume.js +42 -0
  140. package/dist/commands/runtime.d.ts +61 -0
  141. package/dist/commands/runtime.d.ts.map +1 -0
  142. package/dist/commands/runtime.js +20 -0
  143. package/dist/commands/sessions.d.ts +3 -0
  144. package/dist/commands/sessions.d.ts.map +1 -0
  145. package/dist/commands/sessions.js +34 -0
  146. package/dist/commands/shortcuts.d.ts +3 -0
  147. package/dist/commands/shortcuts.d.ts.map +1 -0
  148. package/dist/commands/shortcuts.js +12 -0
  149. package/dist/commands/skill.d.ts +3 -0
  150. package/dist/commands/skill.d.ts.map +1 -0
  151. package/dist/commands/skill.js +20 -0
  152. package/dist/commands/status.d.ts +3 -0
  153. package/dist/commands/status.d.ts.map +1 -0
  154. package/dist/commands/status.js +31 -0
  155. package/dist/commands/statusline.d.ts +3 -0
  156. package/dist/commands/statusline.d.ts.map +1 -0
  157. package/dist/commands/statusline.js +40 -0
  158. package/dist/commands/storage.d.ts +3 -0
  159. package/dist/commands/storage.d.ts.map +1 -0
  160. package/dist/commands/storage.js +122 -0
  161. package/dist/commands/tasks.d.ts +3 -0
  162. package/dist/commands/tasks.d.ts.map +1 -0
  163. package/dist/commands/tasks.js +117 -0
  164. package/dist/commands/types.d.ts +14 -0
  165. package/dist/commands/types.d.ts.map +1 -0
  166. package/dist/commands/types.js +1 -0
  167. package/dist/commands/verify.d.ts +3 -0
  168. package/dist/commands/verify.d.ts.map +1 -0
  169. package/dist/commands/verify.js +86 -0
  170. package/dist/config-report.d.ts +35 -0
  171. package/dist/config-report.d.ts.map +1 -0
  172. package/dist/config-report.js +100 -0
  173. package/dist/config.d.ts +217 -0
  174. package/dist/config.d.ts.map +1 -0
  175. package/dist/config.js +690 -0
  176. package/dist/context-compactor.d.ts +27 -0
  177. package/dist/context-compactor.d.ts.map +1 -0
  178. package/dist/context-compactor.js +489 -0
  179. package/dist/context-report.d.ts +35 -0
  180. package/dist/context-report.d.ts.map +1 -0
  181. package/dist/context-report.js +172 -0
  182. package/dist/daemon.d.ts +2 -0
  183. package/dist/daemon.d.ts.map +1 -0
  184. package/dist/daemon.js +316 -0
  185. package/dist/dashboard-server.d.ts +18 -0
  186. package/dist/dashboard-server.d.ts.map +1 -0
  187. package/dist/dashboard-server.js +325 -0
  188. package/dist/discovery-registry.d.ts +28 -0
  189. package/dist/discovery-registry.d.ts.map +1 -0
  190. package/dist/discovery-registry.js +106 -0
  191. package/dist/discovery-types.d.ts +54 -0
  192. package/dist/discovery-types.d.ts.map +1 -0
  193. package/dist/discovery-types.js +5 -0
  194. package/dist/doctor.d.ts +31 -0
  195. package/dist/doctor.d.ts.map +1 -0
  196. package/dist/doctor.js +343 -0
  197. package/dist/eval/runner.d.ts +10 -0
  198. package/dist/eval/runner.d.ts.map +1 -0
  199. package/dist/eval/runner.js +78 -0
  200. package/dist/eval/tasks.d.ts +3 -0
  201. package/dist/eval/tasks.d.ts.map +1 -0
  202. package/dist/eval/tasks.js +179 -0
  203. package/dist/eval/types.d.ts +31 -0
  204. package/dist/eval/types.d.ts.map +1 -0
  205. package/dist/eval/types.js +4 -0
  206. package/dist/git/auto-commit.d.ts +28 -0
  207. package/dist/git/auto-commit.d.ts.map +1 -0
  208. package/dist/git/auto-commit.js +112 -0
  209. package/dist/guard/approval.d.ts +16 -0
  210. package/dist/guard/approval.d.ts.map +1 -0
  211. package/dist/guard/approval.js +68 -0
  212. package/dist/guard/content-filter.d.ts +15 -0
  213. package/dist/guard/content-filter.d.ts.map +1 -0
  214. package/dist/guard/content-filter.js +102 -0
  215. package/dist/guard/permissions.d.ts +17 -0
  216. package/dist/guard/permissions.d.ts.map +1 -0
  217. package/dist/guard/permissions.js +54 -0
  218. package/dist/guard/rate-limit.d.ts +14 -0
  219. package/dist/guard/rate-limit.d.ts.map +1 -0
  220. package/dist/guard/rate-limit.js +47 -0
  221. package/dist/guard.d.ts +21 -0
  222. package/dist/guard.d.ts.map +1 -0
  223. package/dist/guard.js +144 -0
  224. package/dist/help-topics.d.ts +19 -0
  225. package/dist/help-topics.d.ts.map +1 -0
  226. package/dist/help-topics.js +391 -0
  227. package/dist/hooks-report.d.ts +23 -0
  228. package/dist/hooks-report.d.ts.map +1 -0
  229. package/dist/hooks-report.js +44 -0
  230. package/dist/i18n/index.d.ts +5 -0
  231. package/dist/i18n/index.d.ts.map +1 -0
  232. package/dist/i18n/index.js +4 -0
  233. package/dist/i18n/zh-cn.d.ts +180 -0
  234. package/dist/i18n/zh-cn.d.ts.map +1 -0
  235. package/dist/i18n/zh-cn.js +184 -0
  236. package/dist/index.d.ts +3 -0
  237. package/dist/index.d.ts.map +1 -0
  238. package/dist/index.js +1157 -0
  239. package/dist/knowledge-agent.d.ts +47 -0
  240. package/dist/knowledge-agent.d.ts.map +1 -0
  241. package/dist/knowledge-agent.js +320 -0
  242. package/dist/local-status-report.d.ts +23 -0
  243. package/dist/local-status-report.d.ts.map +1 -0
  244. package/dist/local-status-report.js +63 -0
  245. package/dist/local-storage-report.d.ts +32 -0
  246. package/dist/local-storage-report.d.ts.map +1 -0
  247. package/dist/local-storage-report.js +171 -0
  248. package/dist/mcp/bridge.d.ts +11 -0
  249. package/dist/mcp/bridge.d.ts.map +1 -0
  250. package/dist/mcp/bridge.js +37 -0
  251. package/dist/mcp/client.d.ts +26 -0
  252. package/dist/mcp/client.d.ts.map +1 -0
  253. package/dist/mcp/client.js +209 -0
  254. package/dist/mcp/http-transport.d.ts +21 -0
  255. package/dist/mcp/http-transport.d.ts.map +1 -0
  256. package/dist/mcp/http-transport.js +126 -0
  257. package/dist/mcp/presets.d.ts +22 -0
  258. package/dist/mcp/presets.d.ts.map +1 -0
  259. package/dist/mcp/presets.js +80 -0
  260. package/dist/mcp/registry.d.ts +23 -0
  261. package/dist/mcp/registry.d.ts.map +1 -0
  262. package/dist/mcp/registry.js +85 -0
  263. package/dist/mcp/stdio-transport.d.ts +25 -0
  264. package/dist/mcp/stdio-transport.d.ts.map +1 -0
  265. package/dist/mcp/stdio-transport.js +92 -0
  266. package/dist/mcp/store.d.ts +41 -0
  267. package/dist/mcp/store.d.ts.map +1 -0
  268. package/dist/mcp/store.js +100 -0
  269. package/dist/mcp/types.d.ts +40 -0
  270. package/dist/mcp/types.d.ts.map +1 -0
  271. package/dist/mcp/types.js +4 -0
  272. package/dist/mcp-report.d.ts +30 -0
  273. package/dist/mcp-report.d.ts.map +1 -0
  274. package/dist/mcp-report.js +104 -0
  275. package/dist/memory/cognitive-index.d.ts +56 -0
  276. package/dist/memory/cognitive-index.d.ts.map +1 -0
  277. package/dist/memory/cognitive-index.js +265 -0
  278. package/dist/memory/compactor.d.ts +28 -0
  279. package/dist/memory/compactor.d.ts.map +1 -0
  280. package/dist/memory/compactor.js +92 -0
  281. package/dist/memory/consolidation.d.ts +13 -0
  282. package/dist/memory/consolidation.d.ts.map +1 -0
  283. package/dist/memory/consolidation.js +77 -0
  284. package/dist/memory/embedding.d.ts +15 -0
  285. package/dist/memory/embedding.d.ts.map +1 -0
  286. package/dist/memory/embedding.js +59 -0
  287. package/dist/memory/memory-llm-dream.d.ts +3 -0
  288. package/dist/memory/memory-llm-dream.d.ts.map +1 -0
  289. package/dist/memory/memory-llm-dream.js +59 -0
  290. package/dist/memory/projection-worker.d.ts +30 -0
  291. package/dist/memory/projection-worker.d.ts.map +1 -0
  292. package/dist/memory/projection-worker.js +92 -0
  293. package/dist/memory/semantic-index.d.ts +18 -0
  294. package/dist/memory/semantic-index.d.ts.map +1 -0
  295. package/dist/memory/semantic-index.js +86 -0
  296. package/dist/memory/wal.d.ts +33 -0
  297. package/dist/memory/wal.d.ts.map +1 -0
  298. package/dist/memory/wal.js +131 -0
  299. package/dist/memory-report.d.ts +120 -0
  300. package/dist/memory-report.d.ts.map +1 -0
  301. package/dist/memory-report.js +726 -0
  302. package/dist/memory.d.ts +149 -0
  303. package/dist/memory.d.ts.map +1 -0
  304. package/dist/memory.js +632 -0
  305. package/dist/metrics/agent-telemetry.d.ts +14 -0
  306. package/dist/metrics/agent-telemetry.d.ts.map +1 -0
  307. package/dist/metrics/agent-telemetry.js +44 -0
  308. package/dist/metrics/collector.d.ts +17 -0
  309. package/dist/metrics/collector.d.ts.map +1 -0
  310. package/dist/metrics/collector.js +137 -0
  311. package/dist/metrics/types.d.ts +14 -0
  312. package/dist/metrics/types.d.ts.map +1 -0
  313. package/dist/metrics/types.js +4 -0
  314. package/dist/mission/manager.d.ts +28 -0
  315. package/dist/mission/manager.d.ts.map +1 -0
  316. package/dist/mission/manager.js +208 -0
  317. package/dist/mission/types.d.ts +37 -0
  318. package/dist/mission/types.d.ts.map +1 -0
  319. package/dist/mission/types.js +5 -0
  320. package/dist/onboarding/tutorial.d.ts +33 -0
  321. package/dist/onboarding/tutorial.d.ts.map +1 -0
  322. package/dist/onboarding/tutorial.js +96 -0
  323. package/dist/output-style.d.ts +14 -0
  324. package/dist/output-style.d.ts.map +1 -0
  325. package/dist/output-style.js +29 -0
  326. package/dist/package-version.d.ts +12 -0
  327. package/dist/package-version.d.ts.map +1 -0
  328. package/dist/package-version.js +42 -0
  329. package/dist/permissions-report.d.ts +42 -0
  330. package/dist/permissions-report.d.ts.map +1 -0
  331. package/dist/permissions-report.js +120 -0
  332. package/dist/pipeline/consistency-checker.d.ts +8 -0
  333. package/dist/pipeline/consistency-checker.d.ts.map +1 -0
  334. package/dist/pipeline/consistency-checker.js +40 -0
  335. package/dist/pipeline/example-generator.d.ts +4 -0
  336. package/dist/pipeline/example-generator.d.ts.map +1 -0
  337. package/dist/pipeline/example-generator.js +64 -0
  338. package/dist/pipeline/hooks.d.ts +68 -0
  339. package/dist/pipeline/hooks.d.ts.map +1 -0
  340. package/dist/pipeline/hooks.js +377 -0
  341. package/dist/pipeline/sections.d.ts +41 -0
  342. package/dist/pipeline/sections.d.ts.map +1 -0
  343. package/dist/pipeline/sections.js +244 -0
  344. package/dist/pipeline/verification.d.ts +12 -0
  345. package/dist/pipeline/verification.d.ts.map +1 -0
  346. package/dist/pipeline/verification.js +138 -0
  347. package/dist/privacy-report.d.ts +24 -0
  348. package/dist/privacy-report.d.ts.map +1 -0
  349. package/dist/privacy-report.js +78 -0
  350. package/dist/providers/presets.d.ts +25 -0
  351. package/dist/providers/presets.d.ts.map +1 -0
  352. package/dist/providers/presets.js +205 -0
  353. package/dist/recap.d.ts +38 -0
  354. package/dist/recap.d.ts.map +1 -0
  355. package/dist/recap.js +154 -0
  356. package/dist/repl.d.ts +41 -0
  357. package/dist/repl.d.ts.map +1 -0
  358. package/dist/repl.js +396 -0
  359. package/dist/runtime-paths.d.ts +32 -0
  360. package/dist/runtime-paths.d.ts.map +1 -0
  361. package/dist/runtime-paths.js +134 -0
  362. package/dist/sdk.d.ts +12 -0
  363. package/dist/sdk.d.ts.map +1 -0
  364. package/dist/sdk.js +18 -0
  365. package/dist/session/daemon-session-api.d.ts +22 -0
  366. package/dist/session/daemon-session-api.d.ts.map +1 -0
  367. package/dist/session/daemon-session-api.js +48 -0
  368. package/dist/session/durable-session-supervisor.d.ts +24 -0
  369. package/dist/session/durable-session-supervisor.d.ts.map +1 -0
  370. package/dist/session/durable-session-supervisor.js +195 -0
  371. package/dist/session/goal-controller.d.ts +43 -0
  372. package/dist/session/goal-controller.d.ts.map +1 -0
  373. package/dist/session/goal-controller.js +77 -0
  374. package/dist/session/goal-evaluator.d.ts +29 -0
  375. package/dist/session/goal-evaluator.d.ts.map +1 -0
  376. package/dist/session/goal-evaluator.js +100 -0
  377. package/dist/session/loop-prompt.d.ts +14 -0
  378. package/dist/session/loop-prompt.d.ts.map +1 -0
  379. package/dist/session/loop-prompt.js +49 -0
  380. package/dist/session/session-goal-manager.d.ts +51 -0
  381. package/dist/session/session-goal-manager.d.ts.map +1 -0
  382. package/dist/session/session-goal-manager.js +118 -0
  383. package/dist/session/session-registry.d.ts +40 -0
  384. package/dist/session/session-registry.d.ts.map +1 -0
  385. package/dist/session/session-registry.js +124 -0
  386. package/dist/session/session-scheduler.d.ts +59 -0
  387. package/dist/session/session-scheduler.d.ts.map +1 -0
  388. package/dist/session/session-scheduler.js +170 -0
  389. package/dist/session-checkpoint-report.d.ts +22 -0
  390. package/dist/session-checkpoint-report.d.ts.map +1 -0
  391. package/dist/session-checkpoint-report.js +99 -0
  392. package/dist/session-export-index.d.ts +23 -0
  393. package/dist/session-export-index.d.ts.map +1 -0
  394. package/dist/session-export-index.js +96 -0
  395. package/dist/session-export.d.ts +28 -0
  396. package/dist/session-export.d.ts.map +1 -0
  397. package/dist/session-export.js +99 -0
  398. package/dist/session-goal-report.d.ts +37 -0
  399. package/dist/session-goal-report.d.ts.map +1 -0
  400. package/dist/session-goal-report.js +219 -0
  401. package/dist/session-list-report.d.ts +16 -0
  402. package/dist/session-list-report.d.ts.map +1 -0
  403. package/dist/session-list-report.js +60 -0
  404. package/dist/session-task-report.d.ts +23 -0
  405. package/dist/session-task-report.d.ts.map +1 -0
  406. package/dist/session-task-report.js +183 -0
  407. package/dist/shortcuts.d.ts +2 -0
  408. package/dist/shortcuts.d.ts.map +1 -0
  409. package/dist/shortcuts.js +32 -0
  410. package/dist/skills/registry.d.ts +8 -0
  411. package/dist/skills/registry.d.ts.map +1 -0
  412. package/dist/skills/registry.js +119 -0
  413. package/dist/skills/types.d.ts +7 -0
  414. package/dist/skills/types.d.ts.map +1 -0
  415. package/dist/skills/types.js +4 -0
  416. package/dist/statusline.d.ts +37 -0
  417. package/dist/statusline.d.ts.map +1 -0
  418. package/dist/statusline.js +207 -0
  419. package/dist/tools/bash.d.ts +10 -0
  420. package/dist/tools/bash.d.ts.map +1 -0
  421. package/dist/tools/bash.js +278 -0
  422. package/dist/tools/browser-fetch.d.ts +7 -0
  423. package/dist/tools/browser-fetch.d.ts.map +1 -0
  424. package/dist/tools/browser-fetch.js +133 -0
  425. package/dist/tools/error-utils.d.ts +9 -0
  426. package/dist/tools/error-utils.d.ts.map +1 -0
  427. package/dist/tools/error-utils.js +35 -0
  428. package/dist/tools/index.d.ts +27 -0
  429. package/dist/tools/index.d.ts.map +1 -0
  430. package/dist/tools/index.js +86 -0
  431. package/dist/tools/patch.d.ts +22 -0
  432. package/dist/tools/patch.d.ts.map +1 -0
  433. package/dist/tools/patch.js +458 -0
  434. package/dist/tools/planner.d.ts +7 -0
  435. package/dist/tools/planner.d.ts.map +1 -0
  436. package/dist/tools/planner.js +148 -0
  437. package/dist/tools/read.d.ts +8 -0
  438. package/dist/tools/read.d.ts.map +1 -0
  439. package/dist/tools/read.js +114 -0
  440. package/dist/tools/search.d.ts +11 -0
  441. package/dist/tools/search.d.ts.map +1 -0
  442. package/dist/tools/search.js +636 -0
  443. package/dist/tools/skill.d.ts +8 -0
  444. package/dist/tools/skill.d.ts.map +1 -0
  445. package/dist/tools/skill.js +181 -0
  446. package/dist/tools/subtask.d.ts +9 -0
  447. package/dist/tools/subtask.d.ts.map +1 -0
  448. package/dist/tools/subtask.js +120 -0
  449. package/dist/tools/todo.d.ts +8 -0
  450. package/dist/tools/todo.d.ts.map +1 -0
  451. package/dist/tools/todo.js +170 -0
  452. package/dist/tools/url-fetch.d.ts +11 -0
  453. package/dist/tools/url-fetch.d.ts.map +1 -0
  454. package/dist/tools/url-fetch.js +208 -0
  455. package/dist/tools/vision-analyze.d.ts +9 -0
  456. package/dist/tools/vision-analyze.d.ts.map +1 -0
  457. package/dist/tools/vision-analyze.js +179 -0
  458. package/dist/tools/write.d.ts +7 -0
  459. package/dist/tools/write.d.ts.map +1 -0
  460. package/dist/tools/write.js +128 -0
  461. package/dist/tui/chrome.d.ts +7 -0
  462. package/dist/tui/chrome.d.ts.map +1 -0
  463. package/dist/tui/chrome.js +22 -0
  464. package/dist/tui/input-buffer.d.ts +37 -0
  465. package/dist/tui/input-buffer.d.ts.map +1 -0
  466. package/dist/tui/input-buffer.js +228 -0
  467. package/dist/tui/input-history.d.ts +11 -0
  468. package/dist/tui/input-history.d.ts.map +1 -0
  469. package/dist/tui/input-history.js +69 -0
  470. package/dist/tui/input-queue.d.ts +27 -0
  471. package/dist/tui/input-queue.d.ts.map +1 -0
  472. package/dist/tui/input-queue.js +85 -0
  473. package/dist/tui/markdown.d.ts +10 -0
  474. package/dist/tui/markdown.d.ts.map +1 -0
  475. package/dist/tui/markdown.js +396 -0
  476. package/dist/tui/progress.d.ts +3 -0
  477. package/dist/tui/progress.d.ts.map +1 -0
  478. package/dist/tui/progress.js +13 -0
  479. package/dist/tui/shell.d.ts +67 -0
  480. package/dist/tui/shell.d.ts.map +1 -0
  481. package/dist/tui/shell.js +271 -0
  482. package/dist/tui/streaming-repl.d.ts +39 -0
  483. package/dist/tui/streaming-repl.d.ts.map +1 -0
  484. package/dist/tui/streaming-repl.js +460 -0
  485. package/dist/tui/streaming-tui.d.ts +174 -0
  486. package/dist/tui/streaming-tui.d.ts.map +1 -0
  487. package/dist/tui/streaming-tui.js +1049 -0
  488. package/dist/types.d.ts +221 -0
  489. package/dist/types.d.ts.map +1 -0
  490. package/dist/types.js +37 -0
  491. package/dist/utils/symbol-extractor.d.ts +8 -0
  492. package/dist/utils/symbol-extractor.d.ts.map +1 -0
  493. package/dist/utils/symbol-extractor.js +190 -0
  494. package/dist/workflow-runtime.d.ts +45 -0
  495. package/dist/workflow-runtime.d.ts.map +1 -0
  496. package/dist/workflow-runtime.js +146 -0
  497. package/dist/workflow-types.d.ts +73 -0
  498. package/dist/workflow-types.d.ts.map +1 -0
  499. package/dist/workflow-types.js +34 -0
  500. package/docs/docker.md +66 -0
  501. package/docs/install.md +159 -0
  502. package/docs/sdk.md +67 -0
  503. package/docs/skills.md +51 -0
  504. package/package.json +102 -0
  505. package/scripts/bootstrap.mjs +63 -0
  506. package/scripts/check_image.ps1 +18 -0
  507. package/scripts/clean-dist.mjs +18 -0
  508. package/scripts/copy_image.ps1 +5 -0
  509. package/scripts/eval-smoke.mjs +17 -0
  510. package/skills/examples/repo-triage/SKILL.md +50 -0
  511. package/skills/qling.md +42 -0
  512. package/skills/templates/SKILL.md +37 -0
@@ -0,0 +1,1049 @@
1
+ // ============================================================
2
+ // streaming-tui.ts - Claude Code 风格流式 Agent CLI
3
+ //
4
+ // 架构原则:
5
+ // 1. Header 只打印一次(启动时)
6
+ // 2. 所有输出追加到终端历史,从不重绘
7
+ // 3. 底部输入栏:› prompt,支持 Ctrl+N 插入多行、Ctrl+R 搜索历史
8
+ // 4. Agent 执行期间输入栏保持可用
9
+ // 5. 执行完毕后调用 showPrompt() 恢复 › prompt
10
+ //
11
+ // 事件输出(全部 append,不清屏):
12
+ // appendToolStart / appendToolSuccess / appendToolError
13
+ // appendThinking / appendCogitated
14
+ // appendValidation / appendRepair
15
+ // appendFinal / appendError / appendState / appendDone
16
+ // ============================================================
17
+ import { default as stringWidth } from "string-width";
18
+ import { findSlashCompletion, formatSlashCommandPanel, formatGroupedSlashPanel } from "../commands/index.js";
19
+ import { InputBuffer } from "./input-buffer.js";
20
+ import { formatProgressPulse } from "./progress.js";
21
+ import { formatBottomHints, formatWelcomeGuide, formatRoleHeader, formatToolOutputCard, formatToolTimelineRow, formatTopBar, padVisible, truncateVisible, } from "./shell.js";
22
+ import { formatMarkdownForTerminal } from "./markdown.js";
23
+ import { getPackageVersion } from "../package-version.js";
24
+ // ── ANSI 颜色工具 ───────────────────────────────────────
25
+ function rgb(hex) {
26
+ const n = parseInt(hex.slice(1), 16);
27
+ return `${(n >> 16) & 255};${(n >> 8) & 255};${n & 255}`;
28
+ }
29
+ const C = {
30
+ p: "#36F5B5", // primary 竹青绿
31
+ s: "#75D7FF", // secondary 青蓝
32
+ d: "#8B949E", // dim 灰
33
+ b: "#E6EDF3", // bright 白
34
+ g: "#4ADE80", // green
35
+ r: "#FB7185", // red
36
+ y: "#FACC15", // yellow
37
+ m: "#E879F9", // magenta
38
+ };
39
+ const F = (color, s) => `\x1b[38;2;${rgb(color)}m${s}\x1b[0m`;
40
+ const S = {
41
+ p: (s) => F(C.p, s),
42
+ s: (s) => F(C.s, s),
43
+ d: (s) => F(C.d, s),
44
+ b: (s) => F(C.b, s),
45
+ g: (s) => F(C.g, s),
46
+ r: (s) => F(C.r, s),
47
+ y: (s) => F(C.y, s),
48
+ m: (s) => F(C.m, s),
49
+ };
50
+ const DIM = (s) => `\x1b[2m${s}\x1b[0m`;
51
+ const BOLD = (s) => `\x1b[1m${s}\x1b[0m`;
52
+ // ── 显示宽度工具 ────────────────────────────────────────
53
+ const sw = (s) => stringWidth(s);
54
+ function trunc(s, maxW) {
55
+ if (sw(s) <= maxW)
56
+ return s;
57
+ let col = 0;
58
+ let i = 0;
59
+ while (i < s.length && col < maxW - 1) {
60
+ const cw = sw(s[i]);
61
+ if (col + cw > maxW - 1)
62
+ break;
63
+ col += cw;
64
+ i++;
65
+ }
66
+ return s.slice(0, i) + "…";
67
+ }
68
+ // ── Duration 格式化 ─────────────────────────────────────
69
+ function fmtDur(ms) {
70
+ if (ms < 1000)
71
+ return `${ms}ms`;
72
+ if (ms < 60_000)
73
+ return `${(ms / 1000).toFixed(1)}s`;
74
+ const m = Math.floor(ms / 60_000);
75
+ const s = Math.floor((ms % 60_000) / 1000);
76
+ return `${m}m ${s}s`;
77
+ }
78
+ export class StreamUI {
79
+ model;
80
+ tools;
81
+ chromeStatus = {};
82
+ input = new InputBuffer();
83
+ running = false;
84
+ inputCallback = null;
85
+ currentToolRunning = false;
86
+ dataHandler = null;
87
+ resizeHandler = null;
88
+ statusLine = null;
89
+ statusLineEnabled = true;
90
+ progressTimer = null;
91
+ progressStartedAt = 0;
92
+ progressLabel = "agent";
93
+ lastEmptyCtrlCAt = 0;
94
+ lastClearedDraft = null;
95
+ lastClearedDraftDisplaySource = null;
96
+ draftDisplaySource = null;
97
+ expandLongToolOutput = false;
98
+ lastInputContentLineCount = 1;
99
+ lastInputCursorLineIndex = 0;
100
+ lastInputHintLineCount = 0;
101
+ slashCompletionSelectedIndex = 0;
102
+ inputCursorAnchor = "current";
103
+ inputStartRow = 0;
104
+ now;
105
+ doubleCtrlCExitWindowMs = 2_000;
106
+ constructor(model = "deepseek-chat", tools = 0, options = {}) {
107
+ this.model = model;
108
+ this.tools = tools;
109
+ this.now = options.now ?? (() => Date.now());
110
+ }
111
+ start() {
112
+ this.running = true;
113
+ this.printHeader();
114
+ this.printInputBar();
115
+ this.setupInput();
116
+ }
117
+ stop() {
118
+ this.running = false;
119
+ this.stopProgress();
120
+ if (this.dataHandler) {
121
+ process.stdin.off("data", this.dataHandler);
122
+ this.dataHandler = null;
123
+ }
124
+ if (this.resizeHandler) {
125
+ process.stdout.off("resize", this.resizeHandler);
126
+ this.resizeHandler = null;
127
+ }
128
+ if (typeof process.stdin.setRawMode === "function") {
129
+ process.stdin.setRawMode(false);
130
+ }
131
+ process.stdin.pause();
132
+ process.stdout.write("\n");
133
+ }
134
+ onInput(cb) {
135
+ this.inputCallback = cb;
136
+ }
137
+ setStatusLine(line) {
138
+ this.statusLine = line;
139
+ }
140
+ setStatusLineEnabled(enabled) {
141
+ this.statusLineEnabled = enabled;
142
+ }
143
+ setChromeStatus(status) {
144
+ this.chromeStatus = { ...this.chromeStatus, ...status };
145
+ }
146
+ setModel(model) {
147
+ const next = String(model ?? "").trim();
148
+ if (next)
149
+ this.model = next;
150
+ }
151
+ isExpandLongToolOutput() {
152
+ return this.expandLongToolOutput;
153
+ }
154
+ setExpandLongToolOutput(expanded) {
155
+ this.expandLongToolOutput = Boolean(expanded);
156
+ }
157
+ toggleExpandLongToolOutput() {
158
+ this.expandLongToolOutput = !this.expandLongToolOutput;
159
+ return this.expandLongToolOutput;
160
+ }
161
+ setHistory(entries) {
162
+ this.input.setHistory(entries);
163
+ }
164
+ startProgress(label = "agent", intervalMs = 10_000) {
165
+ this.stopProgress();
166
+ this.progressLabel = label.trim() || "agent";
167
+ this.progressStartedAt = Date.now();
168
+ const safeIntervalMs = Math.max(1_000, intervalMs);
169
+ this.progressTimer = setInterval(() => {
170
+ const elapsedMs = Date.now() - this.progressStartedAt;
171
+ process.stdout.write("\n" + DIM(formatProgressPulse(this.progressLabel, elapsedMs)));
172
+ }, safeIntervalMs);
173
+ this.progressTimer.unref?.();
174
+ }
175
+ stopProgress() {
176
+ if (!this.progressTimer)
177
+ return;
178
+ clearInterval(this.progressTimer);
179
+ this.progressTimer = null;
180
+ }
181
+ // ── Header(只调用一次) ───────────────────────────
182
+ printHeader() {
183
+ const width = process.stdout.columns || 120;
184
+ const lines = formatTopBar({
185
+ productName: "轻灵",
186
+ englishName: "Qling",
187
+ version: getPackageVersion(),
188
+ model: this.model,
189
+ workspace: this.chromeStatus.workspace ?? process.cwd(),
190
+ tokens: this.chromeStatus.tokens ?? 0,
191
+ branch: this.chromeStatus.branch ?? "-",
192
+ ready: this.chromeStatus.ready ?? true,
193
+ sessionMode: this.chromeStatus.sessionMode ?? "agent",
194
+ permissionMode: this.chromeStatus.permissionMode ?? "ask",
195
+ width,
196
+ });
197
+ // 批量写入减少闪烁
198
+ const chunks = [S.p(lines[0]) + "\n", S.d(lines[1]) + "\n"];
199
+ const homeSnap = {
200
+ model: this.model,
201
+ workspace: this.chromeStatus.workspace,
202
+ memoryStatus: this.chromeStatus.memoryStatus || "本地",
203
+ permissionMode: this.chromeStatus.permissionMode || "ask",
204
+ recentSessions: [],
205
+ width,
206
+ };
207
+ for (const line of formatWelcomeGuide(width, homeSnap)) {
208
+ chunks.push(DIM(line) + "\n");
209
+ }
210
+ process.stdout.write(chunks.join(""));
211
+ }
212
+ // ── 底部输入栏 ────────────────────────────────────
213
+ printPromptHint() {
214
+ const chunks = [];
215
+ if (this.statusLineEnabled && this.statusLine) {
216
+ chunks.push(DIM(this.statusLine) + "\n");
217
+ }
218
+ chunks.push(DIM(formatBottomHints()) + "\n");
219
+ process.stdout.write(chunks.join(""));
220
+ }
221
+ printInputBar() {
222
+ this.printPromptHint();
223
+ this.writeInputValue(true);
224
+ this.syncCursor();
225
+ }
226
+ backToPrompt() {
227
+ this.moveToInputContentStart();
228
+ process.stdout.write("\r");
229
+ process.stdout.write("\x1b[J");
230
+ }
231
+ redrawInput() {
232
+ this.backToPrompt();
233
+ this.writeInputValue();
234
+ this.syncCursor();
235
+ }
236
+ appendFeedbackAndRedraw(message, usePlaceholder = false) {
237
+ this.moveAfterInputFrame();
238
+ process.stdout.write("\n" + message + "\n");
239
+ this.writeInputValue(usePlaceholder);
240
+ this.syncCursor();
241
+ }
242
+ wrapInputVisualLines(value, width, cursor) {
243
+ if (width <= 0) {
244
+ return { lines: [value], cursorRow: 0, cursorCol: 0 };
245
+ }
246
+ const lines = [""];
247
+ let currentWidth = 0;
248
+ let cursorRow = 0;
249
+ let cursorCol = 0;
250
+ let charIndex = 0;
251
+ const chars = Array.from(value);
252
+ for (const ch of chars) {
253
+ if (charIndex === cursor) {
254
+ cursorRow = lines.length - 1;
255
+ cursorCol = currentWidth;
256
+ }
257
+ if (ch === "\n") {
258
+ lines.push("");
259
+ currentWidth = 0;
260
+ charIndex += 1;
261
+ continue;
262
+ }
263
+ const w = sw(ch);
264
+ if (currentWidth + w > width) {
265
+ lines.push("");
266
+ currentWidth = 0;
267
+ }
268
+ lines[lines.length - 1] += ch;
269
+ currentWidth += w;
270
+ charIndex += ch.length;
271
+ }
272
+ if (charIndex === cursor) {
273
+ cursorRow = lines.length - 1;
274
+ cursorCol = currentWidth;
275
+ }
276
+ return { lines, cursorRow, cursorCol };
277
+ }
278
+ formatByteSize(value) {
279
+ const bytes = Buffer.byteLength(value, "utf8");
280
+ if (bytes < 1024)
281
+ return `${bytes} B`;
282
+ const kb = bytes / 1024;
283
+ if (kb < 10)
284
+ return `${kb.toFixed(1)} KB`;
285
+ return `${Math.round(kb)} KB`;
286
+ }
287
+ countInputLines(value) {
288
+ if (!value)
289
+ return 0;
290
+ return value.split("\n").length;
291
+ }
292
+ shouldUseCompactDraft(value, wrappedLineCount, isPlaceholder) {
293
+ return !isPlaceholder && Boolean(value) && (value.includes("\n") || wrappedLineCount > 1);
294
+ }
295
+ formatDraftChip(value) {
296
+ const source = this.draftDisplaySource === "pasted" ? "pasted" : "typed";
297
+ const size = this.formatByteSize(value);
298
+ if (source === "pasted") {
299
+ const lines = this.countInputLines(value);
300
+ if (lines > 1) {
301
+ return `[Pasted: ${lines} lines]`;
302
+ }
303
+ return `[Pasted: ${size}]`;
304
+ }
305
+ return `[Draft: ${this.countInputLines(value)} lines, ${size}]`;
306
+ }
307
+ resetDraftDisplaySourceIfEmpty() {
308
+ if (!this.input.value) {
309
+ this.draftDisplaySource = null;
310
+ }
311
+ }
312
+ markPastedDraft() {
313
+ if (this.input.value) {
314
+ this.draftDisplaySource = "pasted";
315
+ }
316
+ }
317
+ formatInputFrameBorder(left, right, label, totalWidth) {
318
+ if (!label) {
319
+ return left + "─".repeat(totalWidth - 2) + right;
320
+ }
321
+ const text = " " + label + " ";
322
+ const textLen = sw(text);
323
+ const borderLen = totalWidth - 2;
324
+ if (borderLen <= textLen) {
325
+ return left + text.slice(0, borderLen) + right;
326
+ }
327
+ const leftDash = Math.floor((borderLen - textLen) / 2);
328
+ const rightDash = borderLen - textLen - leftDash;
329
+ return left + "─".repeat(leftDash) + text + "─".repeat(rightDash) + right;
330
+ }
331
+ syncCursor() {
332
+ const contentWidth = this.inputFrameContentWidth();
333
+ const wrapWidth = contentWidth - 2;
334
+ const wrapped = this.wrapInputVisualLines(this.input.value, wrapWidth, this.input.cursorPos);
335
+ const compactDraft = this.shouldUseCompactDraft(this.input.value, wrapped.lines.length, false);
336
+ const cursor = compactDraft
337
+ ? { lineIndex: 2, columnText: " ".repeat(Math.min(contentWidth - 1, 2 + sw(this.formatDraftChip(this.input.value)))) }
338
+ : this.inputCursorPosition(wrapped);
339
+ if (this.inputCursorAnchor === "bottom") {
340
+ const rowsUp = Math.max(0, this.lastInputContentLineCount + this.lastInputHintLineCount - cursor.lineIndex);
341
+ if (rowsUp > 0) {
342
+ process.stdout.write("\x1b[" + rowsUp + "A");
343
+ }
344
+ }
345
+ else {
346
+ const rowDelta = cursor.lineIndex - this.lastInputCursorLineIndex;
347
+ if (rowDelta > 0) {
348
+ process.stdout.write("\x1b[" + rowDelta + "B");
349
+ }
350
+ else if (rowDelta < 0) {
351
+ process.stdout.write("\x1b[" + Math.abs(rowDelta) + "A");
352
+ }
353
+ }
354
+ const col = 5 + cursor.columnText.length;
355
+ process.stdout.write("\x1b[" + col + "G");
356
+ this.lastInputCursorLineIndex = cursor.lineIndex;
357
+ this.inputCursorAnchor = "current";
358
+ }
359
+ inputFrameWidth() {
360
+ return Math.max(40, process.stdout.columns || 80);
361
+ }
362
+ inputFrameContentWidth() {
363
+ return Math.max(20, this.inputFrameWidth() - 4);
364
+ }
365
+ inputFrameTop() {
366
+ return "┌" + "─".repeat(this.inputFrameContentWidth() + 2) + "┐";
367
+ }
368
+ inputFrameBottom() {
369
+ return "└" + "─".repeat(this.inputFrameContentWidth() + 2) + "┘";
370
+ }
371
+ inputCursorPosition(wrapped) {
372
+ const visualCursorRow = wrapped.cursorRow - this.inputStartRow;
373
+ return {
374
+ lineIndex: 2 + visualCursorRow,
375
+ columnText: " ".repeat(wrapped.cursorCol),
376
+ };
377
+ }
378
+ moveToInputContentStart() {
379
+ const rowsUp = this.inputCursorAnchor === "bottom"
380
+ ? this.lastInputContentLineCount + this.lastInputHintLineCount
381
+ : Math.max(0, this.lastInputCursorLineIndex - 1);
382
+ if (rowsUp > 0) {
383
+ process.stdout.write("\x1b[" + rowsUp + "A");
384
+ }
385
+ this.lastInputCursorLineIndex = 0;
386
+ this.inputCursorAnchor = "current";
387
+ }
388
+ moveAfterInputFrame() {
389
+ if (this.inputCursorAnchor === "current") {
390
+ const rowsDown = Math.max(0, this.lastInputContentLineCount + this.lastInputHintLineCount - this.lastInputCursorLineIndex);
391
+ if (rowsDown > 0) {
392
+ process.stdout.write("\x1b[" + rowsDown + "B");
393
+ }
394
+ }
395
+ process.stdout.write("\r");
396
+ this.lastInputCursorLineIndex = 0;
397
+ this.inputCursorAnchor = "current";
398
+ }
399
+ writeInputValue(usePlaceholder = false) {
400
+ const contentWidth = this.inputFrameContentWidth();
401
+ const valueToWrap = this.input.value || (usePlaceholder ? "输入任务,或按 / 打开命令面板" : "");
402
+ const isPlaceholder = !this.input.value && usePlaceholder;
403
+ const wrapWidth = contentWidth - 2;
404
+ const wrapped = this.wrapInputVisualLines(valueToWrap, wrapWidth, isPlaceholder ? 0 : this.input.cursorPos);
405
+ const compactDraft = this.shouldUseCompactDraft(this.input.value, wrapped.lines.length, isPlaceholder);
406
+ const visibleCount = compactDraft ? 1 : Math.min(5, wrapped.lines.length);
407
+ if (wrapped.cursorRow < this.inputStartRow) {
408
+ this.inputStartRow = wrapped.cursorRow;
409
+ }
410
+ else if (wrapped.cursorRow >= this.inputStartRow + 5) {
411
+ this.inputStartRow = wrapped.cursorRow - 4;
412
+ }
413
+ if (compactDraft) {
414
+ this.inputStartRow = 0;
415
+ }
416
+ else {
417
+ this.inputStartRow = Math.max(0, Math.min(this.inputStartRow, wrapped.lines.length - visibleCount));
418
+ }
419
+ const visibleLines = compactDraft
420
+ ? [this.formatDraftChip(this.input.value)]
421
+ : wrapped.lines.slice(this.inputStartRow, this.inputStartRow + visibleCount);
422
+ const topLabel = !compactDraft && this.inputStartRow > 0
423
+ ? "▲ 更多内容 (当前第 " + (wrapped.cursorRow + 1) + " 行)"
424
+ : "";
425
+ const bottomLabel = !compactDraft && this.inputStartRow + visibleCount < wrapped.lines.length
426
+ ? "▼ 更多内容 (共 " + wrapped.lines.length + " 行)"
427
+ : "";
428
+ const frameWidth = contentWidth + 4;
429
+ const topBorder = this.formatInputFrameBorder("┌", "┐", topLabel, frameWidth);
430
+ const bottomBorder = this.formatInputFrameBorder("└", "┘", bottomLabel, frameWidth);
431
+ // 批量拼串后一次写出,降低 Windows 终端重绘闪烁
432
+ const chunks = [S.p(topBorder)];
433
+ for (let i = 0; i < visibleLines.length; i++) {
434
+ const absoluteRow = this.inputStartRow + i;
435
+ const prefix = compactDraft || absoluteRow === 0 ? "› " : " ";
436
+ const textLine = visibleLines[i] ?? "";
437
+ const contentText = textLine;
438
+ const rendered = truncateVisible(prefix + contentText, contentWidth);
439
+ chunks.push("\n" + S.p("│ " + padVisible(rendered, contentWidth) + " │"));
440
+ }
441
+ chunks.push("\n" + S.p(bottomBorder));
442
+ let extraHint = "";
443
+ if (compactDraft) {
444
+ extraHint = S.y("多行草稿:Enter 发送全部内容");
445
+ }
446
+ if (extraHint) {
447
+ chunks.push("\n" + extraHint);
448
+ }
449
+ const hints = this.formatCurrentSlashCompletionHints();
450
+ for (const hint of hints) {
451
+ chunks.push("\n" + DIM(hint));
452
+ }
453
+ process.stdout.write(chunks.join(""));
454
+ this.lastInputContentLineCount = 1 + visibleLines.length + 1;
455
+ this.lastInputHintLineCount = hints.length + (extraHint ? 1 : 0);
456
+ const cursor = compactDraft
457
+ ? { lineIndex: 2, columnText: " ".repeat(Math.min(contentWidth - 1, 2 + sw(this.formatDraftChip(this.input.value)))) }
458
+ : this.inputCursorPosition(wrapped);
459
+ this.lastInputCursorLineIndex = cursor.lineIndex;
460
+ this.inputCursorAnchor = "bottom";
461
+ }
462
+ formatCurrentSlashCompletionHints() {
463
+ if (!this.isSlashCompletionActive(this.input.value))
464
+ return [];
465
+ const matches = findSlashCompletion(this.input.value, 8);
466
+ if (matches.length > 0 && this.slashCompletionSelectedIndex >= matches.length) {
467
+ this.slashCompletionSelectedIndex = 0;
468
+ }
469
+ const inputVal = this.input.value || "";
470
+ if (inputVal === "/" || inputVal === "") {
471
+ return formatGroupedSlashPanel(process.stdout.columns || 80);
472
+ }
473
+ return formatSlashCommandPanel(inputVal, this.slashCompletionSelectedIndex, process.stdout.columns || 80, 8);
474
+ }
475
+ isSlashCompletionPrefix(value) {
476
+ const text = value.trim();
477
+ return text.startsWith("/") && !/\s/.test(text);
478
+ }
479
+ isSlashCompletionActive(value) {
480
+ return value.startsWith("/") && (!/\s/.test(value.trim()) || /\s$/.test(value));
481
+ }
482
+ acceptSlashCompletion() {
483
+ if (!this.isSlashCompletionPrefix(this.input.value))
484
+ return false;
485
+ const matches = findSlashCompletion(this.input.value, 8);
486
+ const completion = matches[this.slashCompletionSelectedIndex] ?? matches[0];
487
+ if (!completion)
488
+ return false;
489
+ this.input.value = completion.name + " ";
490
+ this.input.cursorPos = this.input.value.length;
491
+ this.draftDisplaySource = null;
492
+ this.slashCompletionSelectedIndex = 0;
493
+ this.lastEmptyCtrlCAt = 0;
494
+ this.redrawInput();
495
+ return true;
496
+ }
497
+ moveSlashCompletionSelection(delta) {
498
+ if (!this.isSlashCompletionPrefix(this.input.value))
499
+ return false;
500
+ const matches = findSlashCompletion(this.input.value, 8);
501
+ if (matches.length <= 1)
502
+ return false;
503
+ this.slashCompletionSelectedIndex =
504
+ (this.slashCompletionSelectedIndex + delta + matches.length) % matches.length;
505
+ this.redrawInput();
506
+ return true;
507
+ }
508
+ showPrompt() {
509
+ if (!this.running)
510
+ return;
511
+ this.inputStartRow = 0;
512
+ process.stdout.write("\n");
513
+ this.printPromptHint();
514
+ this.writeInputValue(true);
515
+ this.syncCursor();
516
+ }
517
+ /** 测试与 slash 复用:当前是否默认展开长工具输出 */
518
+ getExpandLongToolOutput() {
519
+ return this.expandLongToolOutput;
520
+ }
521
+ // ── 键盘输入处理 ─────────────────────────────────
522
+ setupInput() {
523
+ if (typeof process.stdin.setRawMode === "function") {
524
+ process.stdin.setRawMode(true);
525
+ }
526
+ process.stdin.resume();
527
+ process.stdin.setEncoding("utf8");
528
+ this.resizeHandler = () => {
529
+ if (this.running) {
530
+ this.redrawInput();
531
+ }
532
+ };
533
+ process.stdout.on("resize", this.resizeHandler);
534
+ let partial = "";
535
+ let bracketedPaste = false;
536
+ let pasteSawCarriageReturn = false;
537
+ this.dataHandler = (chunk) => {
538
+ if (!this.running)
539
+ return;
540
+ if (chunk === "\x1b") {
541
+ partial = "";
542
+ return;
543
+ }
544
+ // 非 bracketed 粘贴保护
545
+ let isMultilinePaste = false;
546
+ if (!bracketedPaste && !chunk.includes("\x1b") && chunk.length > 1) {
547
+ const normalized = chunk.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
548
+ const withoutTrailing = normalized.endsWith("\n") ? normalized.slice(0, -1) : normalized;
549
+ if (withoutTrailing.includes("\n")) {
550
+ isMultilinePaste = true;
551
+ }
552
+ }
553
+ if (isMultilinePaste) {
554
+ const normalized = chunk.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
555
+ for (const ch of normalized) {
556
+ if (ch === "\n") {
557
+ this.input.insertNewline();
558
+ }
559
+ else if (ch >= " " || ch === "\t") {
560
+ this.input.insertChar(ch);
561
+ }
562
+ }
563
+ this.markPastedDraft();
564
+ this.redrawInput();
565
+ return;
566
+ }
567
+ for (const ch of chunk) {
568
+ if (!partial && ch === "\x1b") {
569
+ partial = ch;
570
+ continue;
571
+ }
572
+ const seq = partial + ch;
573
+ if (seq === "\x1b[200~") {
574
+ partial = "";
575
+ bracketedPaste = true;
576
+ pasteSawCarriageReturn = false;
577
+ }
578
+ else if (seq === "\x1b[201~") {
579
+ partial = "";
580
+ bracketedPaste = false;
581
+ pasteSawCarriageReturn = false;
582
+ this.markPastedDraft();
583
+ this.redrawInput();
584
+ }
585
+ else if (seq === "\x1b[" || /^\x1b\[\d*(?:;\d*)?$/.test(seq)) {
586
+ partial = seq;
587
+ }
588
+ else if (bracketedPaste) {
589
+ partial = "";
590
+ if (seq === "\r") {
591
+ this.input.insertNewline();
592
+ pasteSawCarriageReturn = true;
593
+ }
594
+ else if (seq === "\n") {
595
+ if (!pasteSawCarriageReturn) {
596
+ this.input.insertNewline();
597
+ }
598
+ pasteSawCarriageReturn = false;
599
+ }
600
+ else if (ch >= " " || ch === "\t") {
601
+ pasteSawCarriageReturn = false;
602
+ this.input.insertChar(ch);
603
+ }
604
+ }
605
+ else if (seq === "\r" || seq === "\n") {
606
+ partial = "";
607
+ this.handleEnter();
608
+ }
609
+ else if (seq === "\t") {
610
+ partial = "";
611
+ this.handleTab();
612
+ }
613
+ else if (seq === "\x03") {
614
+ partial = "";
615
+ this.handleCtrlC();
616
+ }
617
+ else if (seq === "\x7f") {
618
+ partial = "";
619
+ this.handleBackspace();
620
+ }
621
+ else if (seq === "\x01") {
622
+ partial = "";
623
+ this.handleCtrlA();
624
+ }
625
+ else if (seq === "\x05") {
626
+ partial = "";
627
+ this.handleCtrlE();
628
+ }
629
+ else if (seq === "\x15") {
630
+ partial = "";
631
+ this.handleCtrlU();
632
+ }
633
+ else if (seq === "\x0b") {
634
+ partial = "";
635
+ this.handleCtrlK();
636
+ }
637
+ else if (seq === "\x17") {
638
+ partial = "";
639
+ this.handleCtrlW();
640
+ }
641
+ else if (seq === "\x1a") {
642
+ partial = "";
643
+ this.handleCtrlZ();
644
+ }
645
+ else if (seq === "\x0c") {
646
+ partial = "";
647
+ this.handleCtrlL();
648
+ }
649
+ else if (seq === "\x04") {
650
+ partial = "";
651
+ this.handleCtrlD();
652
+ }
653
+ else if (seq === "\x1b[A") {
654
+ partial = "";
655
+ this.handleHistoryUp();
656
+ }
657
+ else if (seq === "\x1b[B") {
658
+ partial = "";
659
+ this.handleHistoryDown();
660
+ }
661
+ else if (seq === "\x1b[1;3A" || seq === "\x1b[1;5A" || seq === "\x1b[5A") {
662
+ partial = "";
663
+ this.handleLineUp();
664
+ }
665
+ else if (seq === "\x1b[1;3B" || seq === "\x1b[1;5B" || seq === "\x1b[5B") {
666
+ partial = "";
667
+ this.handleLineDown();
668
+ }
669
+ else if (seq === "\x1b[3~") {
670
+ partial = "";
671
+ this.handleDelete();
672
+ }
673
+ else if (seq === "\x1bd" || seq === "\x1b[3;5~" || seq === "\x1b[3;3~") {
674
+ partial = "";
675
+ this.handleAltD();
676
+ }
677
+ else if (seq === "\x1bb" || seq === "\x1b[1;3D" || seq === "\x1b[1;5D" || seq === "\x1b[5D") {
678
+ partial = "";
679
+ this.handleWordLeft();
680
+ }
681
+ else if (seq === "\x1bf" || seq === "\x1b[1;3C" || seq === "\x1b[1;5C" || seq === "\x1b[5C") {
682
+ partial = "";
683
+ this.handleWordRight();
684
+ }
685
+ else if (seq === "\x1b[C") {
686
+ partial = "";
687
+ this.handleRight();
688
+ }
689
+ else if (seq === "\x1b[D") {
690
+ partial = "";
691
+ this.handleLeft();
692
+ }
693
+ else if (seq === "\x1b[H" || seq === "\x1b[1~") {
694
+ partial = "";
695
+ this.handleHome();
696
+ }
697
+ else if (seq === "\x1b[F" || seq === "\x1b[4~") {
698
+ partial = "";
699
+ this.handleEnd();
700
+ }
701
+ else if (seq === "\x0f") {
702
+ partial = "";
703
+ this.handleCtrlO();
704
+ }
705
+ else if (seq === "\x0e") {
706
+ // Ctrl+N inserts a newline while Enter still submits.
707
+ partial = "";
708
+ this.handleNewline();
709
+ }
710
+ else if (seq === "\x12") {
711
+ // Ctrl+R restores the latest history entry matching the current input.
712
+ partial = "";
713
+ this.handleHistorySearch();
714
+ }
715
+ else if (ch >= " " || ch === "\t") {
716
+ partial = "";
717
+ this.handleChar(ch);
718
+ }
719
+ else {
720
+ partial = "";
721
+ }
722
+ }
723
+ };
724
+ process.stdin.on("data", this.dataHandler);
725
+ }
726
+ handleEnter() {
727
+ const cmd = this.input.value.trim();
728
+ if (!cmd)
729
+ return;
730
+ this.lastEmptyCtrlCAt = 0;
731
+ this.inputStartRow = 0;
732
+ this.moveAfterInputFrame();
733
+ process.stdout.write("\n");
734
+ this.input.submit();
735
+ this.draftDisplaySource = null;
736
+ if (this.inputCallback) {
737
+ this.inputCallback(cmd);
738
+ }
739
+ }
740
+ handleTab() {
741
+ if (!this.input.value) {
742
+ this.lastEmptyCtrlCAt = 0;
743
+ process.stdout.write("\n");
744
+ if (this.inputCallback) {
745
+ this.inputCallback("/agents");
746
+ }
747
+ return;
748
+ }
749
+ if (this.acceptSlashCompletion()) {
750
+ return;
751
+ }
752
+ this.appendFeedbackAndRedraw(S.y("Tab agents 仅在空输入时打开;当前草稿已保留,补全未启用"));
753
+ }
754
+ handleCtrlC() {
755
+ if (!this.input.value) {
756
+ const now = this.now();
757
+ const shouldExit = this.lastEmptyCtrlCAt > 0 &&
758
+ now - this.lastEmptyCtrlCAt <= this.doubleCtrlCExitWindowMs;
759
+ this.lastEmptyCtrlCAt = shouldExit ? 0 : now;
760
+ if (shouldExit) {
761
+ process.stdout.write("\n" + DIM("再次 Ctrl+C 已确认退出") + "\n");
762
+ if (this.inputCallback) {
763
+ this.inputCallback("exit");
764
+ }
765
+ return;
766
+ }
767
+ this.appendFeedbackAndRedraw(S.r("^C") + " " + DIM("再次 Ctrl+C 退出,或输入 exit"), true);
768
+ return;
769
+ }
770
+ this.lastEmptyCtrlCAt = 0;
771
+ this.lastClearedDraft = this.input.value;
772
+ this.lastClearedDraftDisplaySource = this.draftDisplaySource;
773
+ this.input.clear();
774
+ this.draftDisplaySource = null;
775
+ this.inputStartRow = 0;
776
+ this.appendFeedbackAndRedraw(S.r("^C") + " " + DIM("草稿已清空,Ctrl+Z 恢复"), true);
777
+ }
778
+ handleCtrlZ() {
779
+ if (this.input.value) {
780
+ this.appendFeedbackAndRedraw(S.y("当前输入不会被覆盖,草稿未恢复"));
781
+ return;
782
+ }
783
+ if (!this.lastClearedDraft) {
784
+ this.appendFeedbackAndRedraw(S.y("没有可恢复的草稿"), true);
785
+ return;
786
+ }
787
+ for (const ch of this.lastClearedDraft) {
788
+ if (ch === "\n") {
789
+ this.input.insertNewline();
790
+ }
791
+ else {
792
+ this.input.insertChar(ch);
793
+ }
794
+ }
795
+ this.draftDisplaySource = this.lastClearedDraftDisplaySource;
796
+ this.lastClearedDraft = null;
797
+ this.lastClearedDraftDisplaySource = null;
798
+ this.appendFeedbackAndRedraw(S.g("已恢复草稿"));
799
+ }
800
+ handleBackspace() {
801
+ const beforeValue = this.input.value;
802
+ const beforeCursor = this.input.cursorPos;
803
+ this.input.backspace();
804
+ if (this.input.value === beforeValue && this.input.cursorPos === beforeCursor) {
805
+ this.syncCursor();
806
+ return;
807
+ }
808
+ this.resetDraftDisplaySourceIfEmpty();
809
+ this.slashCompletionSelectedIndex = 0;
810
+ this.redrawInput();
811
+ }
812
+ handleCtrlA() {
813
+ this.input.moveStart();
814
+ this.redrawInput();
815
+ }
816
+ handleCtrlE() {
817
+ this.input.moveEnd();
818
+ this.redrawInput();
819
+ }
820
+ handleCtrlU() {
821
+ this.input.deleteBeforeCursor();
822
+ this.resetDraftDisplaySourceIfEmpty();
823
+ this.redrawInput();
824
+ }
825
+ handleCtrlK() {
826
+ this.input.deleteAfterCursor();
827
+ this.resetDraftDisplaySourceIfEmpty();
828
+ this.redrawInput();
829
+ }
830
+ handleCtrlW() {
831
+ this.input.deleteWordBeforeCursor();
832
+ this.resetDraftDisplaySourceIfEmpty();
833
+ this.redrawInput();
834
+ }
835
+ handleAltD() {
836
+ this.input.deleteWordAfterCursor();
837
+ this.resetDraftDisplaySourceIfEmpty();
838
+ this.redrawInput();
839
+ }
840
+ handleDelete() {
841
+ const beforeValue = this.input.value;
842
+ const beforeCursor = this.input.cursorPos;
843
+ this.input.deleteAfterCursorChar();
844
+ if (this.input.value === beforeValue && this.input.cursorPos === beforeCursor) {
845
+ this.syncCursor();
846
+ return;
847
+ }
848
+ this.resetDraftDisplaySourceIfEmpty();
849
+ this.redrawInput();
850
+ }
851
+ handleCtrlL() {
852
+ process.stdout.write("\x1b[2J\x1b[H");
853
+ this.printHeader();
854
+ this.printInputBar();
855
+ this.syncCursor();
856
+ }
857
+ handleCtrlO() {
858
+ const expanded = this.toggleExpandLongToolOutput();
859
+ const state = expanded ? "展开后续工具输出" : "折叠后续工具输出";
860
+ this.appendFeedbackAndRedraw(S.s("长输出:") + DIM(state), !this.input.value);
861
+ }
862
+ handleCtrlD() {
863
+ if (this.input.value) {
864
+ this.appendFeedbackAndRedraw(S.y("非空输入不会退出,草稿已保留"));
865
+ return;
866
+ }
867
+ this.lastEmptyCtrlCAt = 0;
868
+ if (this.inputCallback) {
869
+ this.inputCallback("exit");
870
+ }
871
+ }
872
+ handleHistoryUp() {
873
+ if (this.moveSlashCompletionSelection(-1))
874
+ return;
875
+ this.input.historyUp();
876
+ this.draftDisplaySource = this.input.value ? "typed" : null;
877
+ this.redrawInput();
878
+ }
879
+ handleHistoryDown() {
880
+ if (this.moveSlashCompletionSelection(1))
881
+ return;
882
+ this.input.historyDown();
883
+ this.draftDisplaySource = this.input.value ? "typed" : null;
884
+ this.redrawInput();
885
+ }
886
+ handleHistorySearch() {
887
+ const matched = this.input.searchHistory();
888
+ if (!matched) {
889
+ this.appendFeedbackAndRedraw(S.y("无匹配历史"));
890
+ return;
891
+ }
892
+ this.draftDisplaySource = this.input.value ? "typed" : null;
893
+ this.redrawInput();
894
+ }
895
+ handleLeft() {
896
+ this.input.moveLeft();
897
+ this.syncCursor();
898
+ }
899
+ handleRight() {
900
+ this.input.moveRight();
901
+ this.syncCursor();
902
+ }
903
+ handleWordLeft() {
904
+ this.input.moveWordLeft();
905
+ this.syncCursor();
906
+ }
907
+ handleWordRight() {
908
+ this.input.moveWordRight();
909
+ this.syncCursor();
910
+ }
911
+ handleLineUp() {
912
+ this.input.moveLineUp();
913
+ this.syncCursor();
914
+ }
915
+ handleLineDown() {
916
+ this.input.moveLineDown();
917
+ this.syncCursor();
918
+ }
919
+ handleHome() {
920
+ this.input.moveStart();
921
+ this.redrawInput();
922
+ }
923
+ handleEnd() {
924
+ this.input.moveEnd();
925
+ this.redrawInput();
926
+ }
927
+ handleChar(ch) {
928
+ this.input.insertChar(ch);
929
+ if (this.draftDisplaySource !== "pasted") {
930
+ this.draftDisplaySource = "typed";
931
+ }
932
+ this.slashCompletionSelectedIndex = 0;
933
+ this.redrawInput();
934
+ }
935
+ handleNewline() {
936
+ this.input.insertNewline();
937
+ if (this.draftDisplaySource !== "pasted") {
938
+ this.draftDisplaySource = "typed";
939
+ }
940
+ this.redrawInput();
941
+ }
942
+ // ── 工具块渲染 ────────────────────────────────────
943
+ printToolHeader(tool, command, status, durationMs = 0) {
944
+ const w = process.stdout.columns || 100;
945
+ const row = formatToolTimelineRow({ tool, command, status, durationMs, width: w });
946
+ const color = status === "error" ? S.r : status === "success" ? S.g : S.m;
947
+ process.stdout.write("\n" + color(row));
948
+ }
949
+ printToolOutput(output, _status) {
950
+ const card = formatToolOutputCard(output, {
951
+ expand: this.expandLongToolOutput,
952
+ maxTop: 8,
953
+ maxBottom: 2,
954
+ longThreshold: 12,
955
+ });
956
+ const chunks = [];
957
+ for (const line of card.displayLines) {
958
+ chunks.push(" " + DIM(line) + "\n");
959
+ }
960
+ if (card.footer) {
961
+ chunks.push(" " + DIM(card.footer) + "\n");
962
+ }
963
+ if (chunks.length > 0) {
964
+ process.stdout.write(chunks.join(""));
965
+ }
966
+ }
967
+ // ── 事件输出(全部 append,不清屏) ────────────────
968
+ appendToolStart(tool, command) {
969
+ this.currentToolRunning = true;
970
+ process.stdout.write("\n" + S.m(formatRoleHeader("executing")));
971
+ this.printToolHeader(tool, command, "running");
972
+ }
973
+ appendToolSuccess(tool, command, output, durationMs) {
974
+ if (this.currentToolRunning) {
975
+ this.currentToolRunning = false;
976
+ }
977
+ this.printToolHeader(tool, command, "success", durationMs);
978
+ process.stdout.write("\n");
979
+ if (output.trim()) {
980
+ this.printToolOutput(output, "success");
981
+ }
982
+ }
983
+ appendToolError(tool, command, error, durationMs) {
984
+ if (this.currentToolRunning) {
985
+ this.currentToolRunning = false;
986
+ }
987
+ this.printToolHeader(tool, command, "error", durationMs);
988
+ process.stdout.write("\n " + S.r("Error: ") + S.r(error.split("\n")[0]) + "\n");
989
+ const rest = error.split("\n");
990
+ if (rest.length > 1) {
991
+ this.printToolOutput(rest.slice(1).join("\n"), "error");
992
+ }
993
+ }
994
+ appendThinking(text) {
995
+ const lines = text.split("\n").filter((l) => l.trim());
996
+ if (lines.length === 0)
997
+ return;
998
+ process.stdout.write("\n" + S.p(formatRoleHeader("assistant")) + "\n");
999
+ process.stdout.write(lines[0]);
1000
+ for (let i = 1; i < lines.length; i++) {
1001
+ process.stdout.write("\n" + lines[i]);
1002
+ }
1003
+ }
1004
+ appendCogitated(durationMs) {
1005
+ process.stdout.write("\n" + DIM("◆ Cogitated for " + fmtDur(durationMs)));
1006
+ }
1007
+ appendValidation(status, text) {
1008
+ const icon = status === "pass" ? S.g("●") : status === "fail" ? S.r("●") : S.y("●");
1009
+ const label = status === "pass" ? S.g("pass") : status === "fail" ? S.r("fail") : S.y("warn");
1010
+ process.stdout.write("\n" + icon + " " + label + " " + S.d(text));
1011
+ }
1012
+ appendOutput(text) {
1013
+ const lines = text.split("\n");
1014
+ for (const line of lines) {
1015
+ process.stdout.write(line.trim() ? "\n" + S.b("› ") + line : "\n");
1016
+ }
1017
+ }
1018
+ appendUserInput(text) {
1019
+ const lines = text.split("\n");
1020
+ process.stdout.write("\n" + S.s(formatRoleHeader("user")) + "\n");
1021
+ for (const line of lines) {
1022
+ process.stdout.write(line + "\n");
1023
+ }
1024
+ }
1025
+ appendRepair(reason, action, retryCount) {
1026
+ process.stdout.write("\n" + S.y("[repair]"));
1027
+ process.stdout.write("\n " + S.d("原因:") + " " + S.r(reason));
1028
+ process.stdout.write("\n " + S.d("动作:") + " " + S.b(action));
1029
+ process.stdout.write("\n " + S.d("retry:") + " " + S.y(String(retryCount)));
1030
+ }
1031
+ appendFinal(text) {
1032
+ process.stdout.write("\n" + S.p(formatRoleHeader("assistant")) + "\n");
1033
+ const width = process.stdout.columns || 100;
1034
+ const lines = formatMarkdownForTerminal(text, { width });
1035
+ for (const line of lines) {
1036
+ process.stdout.write(line + "\n");
1037
+ }
1038
+ }
1039
+ appendError(text) {
1040
+ process.stdout.write("\n" + S.r("● error") + " " + S.r(text));
1041
+ }
1042
+ appendState(from, to) {
1043
+ process.stdout.write("\n" + DIM("[state] ") + S.y(from) + " " + DIM("→") + " " + S.g(to));
1044
+ }
1045
+ appendDone(durationMs) {
1046
+ const dur = fmtDur(durationMs);
1047
+ process.stdout.write("\n" + S.g("☑ 分析完成") + " " + DIM(dur));
1048
+ }
1049
+ }