@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
package/dist/index.js ADDED
@@ -0,0 +1,1157 @@
1
+ #!/usr/bin/env node
2
+ // ============================================================
3
+ // 轻灵 - CLI 入口
4
+ // 契约:
5
+ // 默认启动: qling -> chat (TUI)
6
+ // 单次任务: qling run "任务" -> run
7
+ // REPL: qling repl -> repl
8
+ // ============================================================
9
+ import { fileURLToPath } from "url";
10
+ import path from "path";
11
+ import fs from "fs";
12
+ import os from "os";
13
+ import dotenv from "dotenv";
14
+ import axios from "axios";
15
+ import { AgentLoop } from "./agent-loop.js";
16
+ import { Repl } from "./repl.js";
17
+ import { StreamingREPL } from "./tui/streaming-repl.js";
18
+ import { buildHelpText, formatCliError, parseCliArgs } from "./cli/startup-contract.js";
19
+ import { runBootstrap } from "./cli/bootstrap.js";
20
+ import { applyConfigToProcessEnv, loadQlingConfig } from "./config.js";
21
+ import { CliChannelBootstrapError, resolveRunModeChannel, } from "./cli/channel-bootstrap.js";
22
+ import { buildToolRegistry } from "./tools/index.js";
23
+ import { runSetup } from "./cli/setup.js";
24
+ import { checkOnboarding } from "./onboarding/tutorial.js";
25
+ import { MissionManager } from "./mission/manager.js";
26
+ import { getDaemonStatus, startDaemon, stopDaemon } from "./cli/daemon-control.js";
27
+ import { followMissionAttach, renderAgentsView, renderMissionEvents } from "./cli/mission-views.js";
28
+ import { buildDoctorReport, formatDoctorReport } from "./doctor.js";
29
+ import { storageCommand } from "./commands/storage.js";
30
+ import { formatSessionExportIndex, listSessionExportFiles, parseSessionExportCount } from "./session-export-index.js";
31
+ import { formatSessionListReport, listLocalSessions, parseSessionListCount } from "./session-list-report.js";
32
+ import { createLocalSessionCheckpoint, formatLocalSessionCheckpointResult, parseLocalSessionCheckpointArgs } from "./session-checkpoint-report.js";
33
+ import { cancelLocalSessionTask, formatCanceledSessionTask, formatSessionTaskReport, listLocalSessionTasks, parseSessionTaskCount } from "./session-task-report.js";
34
+ import { clearLocalSessionGoal, formatSessionGoalMutation, formatSessionGoalReport, listLocalSessionGoals, setLocalSessionGoal } from "./session-goal-report.js";
35
+ import { buildLocalMemoryReport, buildLocalMemorySourcesReport, findLocalMemoryEntry, formatLocalMemoryEntry, formatLocalMemoryGraphReport, formatLocalMemoryPracticesReport, formatLocalMemoryReport, formatLocalMemorySearchReport, formatLocalMemorySourcesReport, listLocalMemoryGraph, listLocalMemoryPractices, parseMemoryReportCount, parseMemorySearchArgs, searchLocalMemoryEntries } from "./memory-report.js";
36
+ import { buildLocalPrivacyReport, formatPrivacyReport } from "./privacy-report.js";
37
+ import { buildLocalContextReport, formatContextReport } from "./context-report.js";
38
+ import { SHORTCUT_LINES } from "./shortcuts.js";
39
+ import { collectLocalStatusLineSnapshot, formatStatusLine, parseStatusLineCostPer1k } from "./statusline.js";
40
+ import { buildSavedSessionRecap, parseSavedSessionRecapArgs } from "./recap.js";
41
+ import { buildLocalPermissionsReport, explainLocalPermissionDecision, formatLocalPermissionsReport, formatPermissionExplanationReport, } from "./permissions-report.js";
42
+ import { buildLocalConfigReport, formatLocalConfigReport } from "./config-report.js";
43
+ import { buildLocalHooksReport, formatLocalHooksReport } from "./hooks-report.js";
44
+ import { buildLocalStatusReport, formatLocalStatusReport } from "./local-status-report.js";
45
+ const CURRENT_FILE = fileURLToPath(import.meta.url);
46
+ const DIST_DIR = path.dirname(CURRENT_FILE);
47
+ function findEnvPaths() {
48
+ const paths = [];
49
+ // 1. 项目配置 (从当前目录向上查找,最优先)
50
+ let dir = process.cwd();
51
+ while (true) {
52
+ const envPath = path.join(dir, ".env");
53
+ if (fs.existsSync(envPath)) {
54
+ paths.push(envPath);
55
+ break;
56
+ }
57
+ const parent = path.dirname(dir);
58
+ if (parent === dir)
59
+ break;
60
+ dir = parent;
61
+ }
62
+ // 2. 全局配置 (~/.qling/.env,作为回退)
63
+ const globalEnv = path.join(os.homedir(), ".qling", ".env");
64
+ if (fs.existsSync(globalEnv)) {
65
+ paths.push(globalEnv);
66
+ }
67
+ // 3. 回退: 如果啥也没找到,默认指向当前目录 .env
68
+ if (paths.length === 0) {
69
+ paths.push(path.join(process.cwd(), ".env"));
70
+ }
71
+ return paths;
72
+ }
73
+ const envPaths = findEnvPaths();
74
+ for (const p of envPaths) {
75
+ dotenv.config({ path: p });
76
+ }
77
+ function formatTimestamp(value) {
78
+ return new Date(value).toLocaleString();
79
+ }
80
+ function printMissionList(missions, source) {
81
+ console.error(source);
82
+ console.log("\n📋 【使命列表】");
83
+ console.log("-----------------------------------------");
84
+ if (missions.length === 0) {
85
+ console.log("(无)");
86
+ }
87
+ for (const mission of missions) {
88
+ console.log(`- [${mission.status.toUpperCase()}] ${mission.id} | ${formatTimestamp(mission.createdAt)}`);
89
+ console.log(` 名称: ${mission.name}`);
90
+ console.log(` 任务: ${mission.description.slice(0, 80)}`);
91
+ }
92
+ console.log("-----------------------------------------\n");
93
+ }
94
+ function printMissionDetail(mission) {
95
+ console.log(`ID: ${mission.id}`);
96
+ console.log(`名称: ${mission.name}`);
97
+ console.log(`状态: ${mission.status}`);
98
+ console.log(`会话: ${mission.sessionId}`);
99
+ console.log(`创建: ${formatTimestamp(mission.createdAt)}`);
100
+ console.log(`更新: ${formatTimestamp(mission.updatedAt)}`);
101
+ if (mission.sourceMissionId) {
102
+ console.log(`来源使命: ${mission.sourceMissionId}`);
103
+ }
104
+ if (mission.error) {
105
+ console.log(`错误: [${mission.error.code}] ${mission.error.message}`);
106
+ }
107
+ console.log(`任务: ${mission.description}`);
108
+ }
109
+ function printMissionLogs(events) {
110
+ console.log(renderMissionEvents(events));
111
+ }
112
+ function shouldFallbackToLocalMission(err) {
113
+ return !(axios.isAxiosError(err) && err.response);
114
+ }
115
+ async function buildCliDoctorLines(loadedConfig) {
116
+ const report = await buildDoctorReport({
117
+ workspaceDir: loadedConfig.runtime.workspace_dir ?? process.cwd(),
118
+ agentLoop: {
119
+ getWorkspaceDir: () => loadedConfig.runtime.workspace_dir ?? process.cwd(),
120
+ getSessionStats: () => ({ sessionId: "cli-doctor", turnCount: 0, tokens: 0 }),
121
+ getPermissionMode: () => loadedConfig.guard.permissions.default,
122
+ },
123
+ writeLine: () => { },
124
+ writeError: () => { },
125
+ });
126
+ return formatDoctorReport(report);
127
+ }
128
+ async function withMissionFallback(daemonCall, localCall) {
129
+ try {
130
+ return {
131
+ value: await daemonCall(),
132
+ source: "daemon",
133
+ };
134
+ }
135
+ catch (err) {
136
+ if (!shouldFallbackToLocalMission(err)) {
137
+ throw err;
138
+ }
139
+ return {
140
+ value: await localCall(),
141
+ source: "local",
142
+ };
143
+ }
144
+ }
145
+ async function executeLocalMission(agent, manager, mission) {
146
+ await manager.updateStatus(mission.id, "running");
147
+ await manager.appendLog(mission.id, "使命开始在当前前台进程执行", { source: "local_cli" });
148
+ try {
149
+ agent.addUserMessage(mission.description);
150
+ const response = await agent.run();
151
+ await manager.appendLog(mission.id, "使命执行成功", {
152
+ source: "local_cli",
153
+ resultPreview: response.slice(0, 120),
154
+ });
155
+ await manager.updateStatus(mission.id, "succeeded");
156
+ return response;
157
+ }
158
+ catch (err) {
159
+ await manager.updateStatus(mission.id, "failed", {
160
+ code: "LOCAL_MISSION_FAILED",
161
+ message: err instanceof Error ? err.message : String(err),
162
+ });
163
+ await manager.appendLog(mission.id, `使命执行失败: ${err instanceof Error ? err.message : String(err)}`, { source: "local_cli" });
164
+ throw err;
165
+ }
166
+ }
167
+ function normalizeMissionSubcommand(sub) {
168
+ const normalized = (sub ?? "").toLowerCase();
169
+ const aliases = {
170
+ "开始": "start",
171
+ "列表": "list",
172
+ "查看": "show",
173
+ "日志": "logs",
174
+ "附着": "attach",
175
+ "跟随": "attach",
176
+ "暂停": "pause",
177
+ "恢复": "resume",
178
+ "取消": "cancel",
179
+ "停止": "cancel",
180
+ "终止": "cancel",
181
+ stop: "cancel",
182
+ terminate: "cancel",
183
+ "重试": "retry",
184
+ respawn: "retry",
185
+ };
186
+ return aliases[normalized] ?? normalized;
187
+ }
188
+ function normalizeTasksSubcommand(sub) {
189
+ const normalized = (sub ?? "").toLowerCase();
190
+ const aliases = {
191
+ "": "list",
192
+ "列表": "list",
193
+ "查看": "list",
194
+ "取消": "cancel",
195
+ "停止": "cancel",
196
+ "终止": "cancel",
197
+ "stop": "cancel",
198
+ "terminate": "cancel",
199
+ };
200
+ return aliases[normalized] ?? normalized;
201
+ }
202
+ function normalizeGoalSubcommand(sub) {
203
+ const normalized = (sub ?? "").toLowerCase();
204
+ const aliases = {
205
+ "": "status",
206
+ "状态": "status",
207
+ "查看": "status",
208
+ "列表": "status",
209
+ "设置": "set",
210
+ "清除": "clear",
211
+ "取消": "clear",
212
+ "停止": "clear",
213
+ "终止": "clear",
214
+ "reset": "clear",
215
+ "stop": "clear",
216
+ "cancel": "clear",
217
+ };
218
+ return aliases[normalized] ?? normalized;
219
+ }
220
+ function normalizeMemorySubcommand(sub) {
221
+ const normalized = (sub ?? "").toLowerCase();
222
+ const aliases = {
223
+ "": "list",
224
+ "状态": "list",
225
+ "查看列表": "list",
226
+ "列表": "list",
227
+ "status": "list",
228
+ "list": "list",
229
+ "practice": "practices",
230
+ "practices": "practices",
231
+ "实践": "practices",
232
+ "经验": "practices",
233
+ "graph": "graph",
234
+ "图谱": "graph",
235
+ "知识图谱": "graph",
236
+ "搜索": "search",
237
+ "search": "search",
238
+ "source": "sources",
239
+ "sources": "sources",
240
+ "来源": "sources",
241
+ "来源图": "sources",
242
+ "查看": "show",
243
+ "详情": "show",
244
+ "show": "show",
245
+ };
246
+ return aliases[normalized] ?? normalized;
247
+ }
248
+ function parseGoalSetArgs(args) {
249
+ const remaining = [];
250
+ let sessionRef;
251
+ for (let i = 0; i < args.length; i++) {
252
+ const arg = args[i];
253
+ if (arg === "--session" || arg === "-s") {
254
+ sessionRef = args[i + 1];
255
+ i++;
256
+ continue;
257
+ }
258
+ if (arg.startsWith("--session=")) {
259
+ sessionRef = arg.slice("--session=".length);
260
+ continue;
261
+ }
262
+ remaining.push(arg);
263
+ }
264
+ return {
265
+ sessionRef,
266
+ condition: remaining.join(" ").trim(),
267
+ };
268
+ }
269
+ function isPureMissionManagementSubcommand(sub) {
270
+ return ["list", "show", "logs", "attach", "pause", "resume", "cancel"].includes(sub);
271
+ }
272
+ async function createStandaloneMissionManager(stateDir) {
273
+ const manager = new MissionManager(stateDir);
274
+ await manager.init();
275
+ return manager;
276
+ }
277
+ async function buildMissionReader(missionId, daemonUrl, stateDir) {
278
+ try {
279
+ await axios.get(`${daemonUrl}/missions/${encodeURIComponent(missionId)}`, { timeout: 2000 });
280
+ return {
281
+ source: "daemon",
282
+ getMission: async () => {
283
+ const resp = await axios.get(`${daemonUrl}/missions/${encodeURIComponent(missionId)}`, { timeout: 2000 });
284
+ return resp.data;
285
+ },
286
+ getLogs: async () => {
287
+ const resp = await axios.get(`${daemonUrl}/missions/${encodeURIComponent(missionId)}/logs`, { timeout: 2000 });
288
+ return resp.data;
289
+ },
290
+ };
291
+ }
292
+ catch (err) {
293
+ if (!shouldFallbackToLocalMission(err)) {
294
+ throw err;
295
+ }
296
+ return {
297
+ source: "local",
298
+ getMission: async () => {
299
+ const manager = await createStandaloneMissionManager(stateDir);
300
+ return manager.getMissionOrThrow(missionId);
301
+ },
302
+ getLogs: async () => {
303
+ const manager = await createStandaloneMissionManager(stateDir);
304
+ return manager.getMissionLogs(missionId);
305
+ },
306
+ };
307
+ }
308
+ }
309
+ async function main() {
310
+ const decision = parseCliArgs(process.argv.slice(2));
311
+ if (decision.kind === "error") {
312
+ console.error(formatCliError(decision.code, decision.message));
313
+ process.exit(decision.exitCode);
314
+ }
315
+ if (decision.mode === "help") {
316
+ console.log(buildHelpText("qling", decision.subArgs.join(" ")));
317
+ process.exit(0);
318
+ }
319
+ if (decision.mode === "version") {
320
+ // 与 parseCliArgs 同源;不加载配置、不要求 API key
321
+ const { buildVersionText } = await import("./cli/startup-contract.js");
322
+ console.log(buildVersionText("qling"));
323
+ process.exit(0);
324
+ }
325
+ // v0.4 / Phase 1.4 Onboarding(仅交互模式;非 TTY 跳过)
326
+ if (decision.mode === "chat" || decision.mode === "repl") {
327
+ const needSetup = !(process.env.QLING_LLM_API_KEY?.trim() ||
328
+ process.env.DEEPSEEK_API_KEY?.trim() ||
329
+ process.env.OPENAI_API_KEY?.trim());
330
+ await checkOnboarding({
331
+ stateDir: decision.global.fileStateDir,
332
+ needSetup,
333
+ });
334
+ }
335
+ for (const warning of decision.warnings) {
336
+ console.error(`Warning: ${warning}`);
337
+ }
338
+ let loaded;
339
+ try {
340
+ loaded = await loadQlingConfig(decision.global);
341
+ }
342
+ catch (err) {
343
+ console.error(formatCliError("CONFIG_LOAD_FAILED", err instanceof Error ? err.message : String(err)));
344
+ process.exit(1);
345
+ }
346
+ for (const warning of loaded.warnings) {
347
+ console.error(`Warning: ${warning}`);
348
+ }
349
+ const originalMcpServersEnv = process.env.QLING_MCP_SERVERS;
350
+ applyConfigToProcessEnv(loaded.config);
351
+ const stateDir = loaded.config.runtime.file_state_dir;
352
+ const DAEMON_PORT = process.env.QLING_DAEMON_PORT || "9998";
353
+ const daemonUrl = `http://localhost:${DAEMON_PORT}`;
354
+ let standaloneMissionManagerPromise = null;
355
+ const getStandaloneMissionManager = async () => {
356
+ if (!standaloneMissionManagerPromise) {
357
+ standaloneMissionManagerPromise = createStandaloneMissionManager(stateDir);
358
+ }
359
+ return standaloneMissionManagerPromise;
360
+ };
361
+ // v0.3 Management Subcommands
362
+ if (decision.mode === "setup") {
363
+ await runSetup();
364
+ return;
365
+ }
366
+ if (decision.mode === "bootstrap") {
367
+ await runBootstrap(decision.subArgs, {
368
+ setupRunner: runSetup,
369
+ doctorRunner: () => buildCliDoctorLines(loaded.config),
370
+ stateDir: loaded.config.runtime.file_state_dir,
371
+ });
372
+ return;
373
+ }
374
+ if (decision.mode === "doctor") {
375
+ console.log((await buildCliDoctorLines(loaded.config)).join("\n"));
376
+ return;
377
+ }
378
+ if (decision.mode === "status") {
379
+ const report = await buildLocalStatusReport(loaded.config);
380
+ console.log(formatLocalStatusReport(report).join("\n"));
381
+ return;
382
+ }
383
+ if (decision.mode === "storage") {
384
+ await storageCommand.execute(decision.subArgs, {
385
+ workspaceDir: loaded.config.runtime.workspace_dir ?? process.cwd(),
386
+ agentLoop: {
387
+ getWorkspaceDir: () => loaded.config.runtime.workspace_dir ?? process.cwd(),
388
+ getRuntimeRootDir: () => loaded.config.runtime.file_state_dir,
389
+ },
390
+ writeLine: (line = "") => console.log(line),
391
+ writeError: (line = "") => console.error(line),
392
+ env: {
393
+ ...process.env,
394
+ QLING_FILE_STATE_DIR: loaded.config.runtime.file_state_dir,
395
+ QLING_FILE_CACHE_DIR: loaded.config.runtime.file_cache_dir,
396
+ },
397
+ });
398
+ return;
399
+ }
400
+ if (decision.mode === "exports") {
401
+ const report = await listSessionExportFiles({
402
+ workspaceDir: loaded.config.runtime.workspace_dir ?? process.cwd(),
403
+ agentLoop: {
404
+ getWorkspaceDir: () => loaded.config.runtime.workspace_dir ?? process.cwd(),
405
+ getRuntimeRootDir: () => loaded.config.runtime.file_state_dir,
406
+ },
407
+ writeLine: () => { },
408
+ writeError: () => { },
409
+ }, {
410
+ count: parseSessionExportCount(decision.subArgs[0]),
411
+ env: {
412
+ ...process.env,
413
+ QLING_FILE_STATE_DIR: loaded.config.runtime.file_state_dir,
414
+ },
415
+ });
416
+ console.log(formatSessionExportIndex(report).join("\n"));
417
+ return;
418
+ }
419
+ if (decision.mode === "sessions") {
420
+ const report = await listLocalSessions(loaded.config.runtime.file_state_dir, {
421
+ count: parseSessionListCount(decision.subArgs[0]),
422
+ });
423
+ console.log(formatSessionListReport(report).join("\n"));
424
+ return;
425
+ }
426
+ if (decision.mode === "checkpoint") {
427
+ try {
428
+ const result = await createLocalSessionCheckpoint(loaded.config.runtime.file_state_dir, parseLocalSessionCheckpointArgs(decision.subArgs));
429
+ console.log(formatLocalSessionCheckpointResult(result).join("\n"));
430
+ return;
431
+ }
432
+ catch (err) {
433
+ console.error(err instanceof Error ? err.message : String(err));
434
+ process.exit(1);
435
+ }
436
+ }
437
+ if (decision.mode === "tasks") {
438
+ const [rawSub, ...taskArgs] = decision.subArgs;
439
+ const sub = normalizeTasksSubcommand(rawSub);
440
+ try {
441
+ if (sub === "list") {
442
+ const report = await listLocalSessionTasks(stateDir, {
443
+ count: parseSessionTaskCount(taskArgs[0]),
444
+ });
445
+ console.log(formatSessionTaskReport(report).join("\n"));
446
+ return;
447
+ }
448
+ if (sub === "cancel") {
449
+ const taskId = taskArgs[0];
450
+ if (!taskId) {
451
+ console.error("用法: qling tasks cancel <id>");
452
+ process.exit(1);
453
+ }
454
+ const task = await cancelLocalSessionTask(stateDir, taskId);
455
+ console.log(formatCanceledSessionTask(task).join("\n"));
456
+ return;
457
+ }
458
+ console.error("用法: qling tasks list [count] | cancel <id>");
459
+ process.exit(1);
460
+ }
461
+ catch (err) {
462
+ console.error(err instanceof Error ? err.message : String(err));
463
+ process.exit(1);
464
+ }
465
+ }
466
+ if (decision.mode === "goal") {
467
+ const [rawSub, ...goalArgs] = decision.subArgs;
468
+ const sub = normalizeGoalSubcommand(rawSub);
469
+ try {
470
+ if (sub === "status") {
471
+ const report = await listLocalSessionGoals(stateDir, {
472
+ sessionRef: goalArgs[0],
473
+ });
474
+ console.log(formatSessionGoalReport(report).join("\n"));
475
+ return;
476
+ }
477
+ if (sub === "set") {
478
+ const parsed = parseGoalSetArgs(goalArgs);
479
+ if (!parsed.condition) {
480
+ console.error("用法: qling goal set [--session <session>] \"完成条件\"");
481
+ process.exit(1);
482
+ }
483
+ const result = await setLocalSessionGoal(stateDir, parsed.condition, {
484
+ sessionRef: parsed.sessionRef,
485
+ });
486
+ console.log(formatSessionGoalMutation("set", result).join("\n"));
487
+ return;
488
+ }
489
+ if (sub === "clear") {
490
+ const result = await clearLocalSessionGoal(stateDir, {
491
+ sessionRef: goalArgs[0],
492
+ });
493
+ console.log(formatSessionGoalMutation("clear", result).join("\n"));
494
+ return;
495
+ }
496
+ console.error("用法: qling goal status [session] | set [--session <session>] \"完成条件\" | clear [session]");
497
+ process.exit(1);
498
+ }
499
+ catch (err) {
500
+ console.error(err instanceof Error ? err.message : String(err));
501
+ process.exit(1);
502
+ }
503
+ }
504
+ if (decision.mode === "memory") {
505
+ const [rawSub, ...memoryArgs] = decision.subArgs;
506
+ const sub = normalizeMemorySubcommand(rawSub);
507
+ try {
508
+ if (sub === "list") {
509
+ const count = rawSub && normalizeMemorySubcommand(rawSub) === "list" ? memoryArgs[0] : rawSub;
510
+ const report = await buildLocalMemoryReport(stateDir, {
511
+ count: parseMemoryReportCount(count),
512
+ });
513
+ console.log(formatLocalMemoryReport(report).join("\n"));
514
+ return;
515
+ }
516
+ if (sub === "show") {
517
+ const memoryId = memoryArgs[0];
518
+ if (!memoryId) {
519
+ console.error("用法: qling memory show <id>");
520
+ process.exit(1);
521
+ }
522
+ const entry = await findLocalMemoryEntry(stateDir, memoryId);
523
+ if (!entry) {
524
+ console.error(`未找到指定本地记忆: ${memoryId}`);
525
+ process.exit(1);
526
+ }
527
+ console.log(formatLocalMemoryEntry(entry).join("\n"));
528
+ return;
529
+ }
530
+ if (sub === "search") {
531
+ const request = parseMemorySearchArgs(memoryArgs);
532
+ if (!request.query) {
533
+ console.error("用法: qling memory search <query> [count]");
534
+ process.exit(1);
535
+ }
536
+ const report = await searchLocalMemoryEntries(stateDir, request);
537
+ console.log(formatLocalMemorySearchReport(report).join("\n"));
538
+ return;
539
+ }
540
+ if (sub === "practices") {
541
+ const report = await listLocalMemoryPractices(stateDir, {
542
+ count: parseMemoryReportCount(memoryArgs[0]),
543
+ });
544
+ console.log(formatLocalMemoryPracticesReport(report).join("\n"));
545
+ return;
546
+ }
547
+ if (sub === "sources") {
548
+ const report = await buildLocalMemorySourcesReport(stateDir);
549
+ console.log(formatLocalMemorySourcesReport(report).join("\n"));
550
+ return;
551
+ }
552
+ if (sub === "graph") {
553
+ const report = await listLocalMemoryGraph(stateDir, {
554
+ count: parseMemoryReportCount(memoryArgs[0]),
555
+ });
556
+ console.log(formatLocalMemoryGraphReport(report).join("\n"));
557
+ return;
558
+ }
559
+ if (sub !== "reindex") {
560
+ console.error("用法: qling memory status [count] | list [count] | search <query> [count] | sources | practices [count] | graph [count] | show <id> | reindex [--full]");
561
+ process.exit(1);
562
+ }
563
+ }
564
+ catch (err) {
565
+ console.error(err instanceof Error ? err.message : String(err));
566
+ process.exit(1);
567
+ }
568
+ }
569
+ if (decision.mode === "privacy") {
570
+ const report = await buildLocalPrivacyReport({
571
+ workspaceDir: loaded.config.runtime.workspace_dir ?? process.cwd(),
572
+ stateDir: loaded.config.runtime.file_state_dir,
573
+ cacheDir: loaded.config.runtime.file_cache_dir,
574
+ model: loaded.config.llm.model,
575
+ });
576
+ console.log(formatPrivacyReport(report).join("\n"));
577
+ return;
578
+ }
579
+ if (decision.mode === "context") {
580
+ const report = await buildLocalContextReport({
581
+ workspaceDir: loaded.config.runtime.workspace_dir ?? process.cwd(),
582
+ stateDir: loaded.config.runtime.file_state_dir,
583
+ cacheDir: loaded.config.runtime.file_cache_dir,
584
+ maxTokens: loaded.config.runtime.max_token_budget,
585
+ });
586
+ console.log(formatContextReport(report).join("\n"));
587
+ return;
588
+ }
589
+ if (decision.mode === "shortcuts") {
590
+ console.log(SHORTCUT_LINES.join("\n"));
591
+ return;
592
+ }
593
+ // P3: knowledge top-level (完整支持中文 RAG 入口)
594
+ if (decision.mode === "knowledge") {
595
+ const args = decision.subArgs || [];
596
+ const first = (args[0] || "").toLowerCase();
597
+ const rest = args.slice(1).join(" ").trim();
598
+ const query = first && !["index", "索引"].includes(first) ? args.join(" ").trim() : rest;
599
+ console.log("");
600
+ console.log("📚 【轻灵知识库】本地优先 · 中文 RAG");
601
+ console.log("-----------------------------------------");
602
+ if (first === "index" || first === "索引") {
603
+ console.log(`正在索引: ${rest || process.cwd()} (中文 chunk 策略)`);
604
+ console.log("提示: 建议切换到 TUI 使用 /knowledge index 以完整集成 memory");
605
+ }
606
+ else if (query) {
607
+ console.log(`查询: ${query}`);
608
+ console.log("结果示例: 运行 /knowledge <问题> 以获得真实引用和置信度");
609
+ console.log("推荐: DeepSeek / Qwen / GLM + 中文 embedding");
610
+ }
611
+ else {
612
+ console.log("用法: qling knowledge <查询> | qling knowledge index <路径>");
613
+ console.log("默认模型推荐: DeepSeek / Qwen / GLM + 中文 embedding");
614
+ }
615
+ console.log("-----------------------------------------");
616
+ console.log("边界: 仅本地,不上传。");
617
+ console.log("");
618
+ return;
619
+ }
620
+ if (decision.mode === "connect") {
621
+ const [platform, action] = decision.subArgs || [];
622
+ console.log("");
623
+ console.log("🔗 【轻灵连接器】国内平台引导 (top-level P4)");
624
+ console.log("-----------------------------------------");
625
+ const plat = (platform || "").toLowerCase();
626
+ if (plat) {
627
+ console.log(`平台: ${plat}`);
628
+ if (action === "test" || action === "测试") {
629
+ const envKey = plat === "telegram" ? "QLING_CHANNEL_TELEGRAM_TOKEN" : plat === "slack" ? "QLING_CHANNEL_SLACK_BOT_TOKEN" : "";
630
+ const token = envKey ? process.env[envKey] : "";
631
+ if (!token) {
632
+ console.log(`❌ ${plat} 测试: 未设置 ${envKey || "token"}`);
633
+ }
634
+ else {
635
+ console.log(`✅ ${plat} token 已设置 (脱敏验证通过)`);
636
+ }
637
+ console.log("提示: 完整连通使用 /connect " + plat + " test 或 doctor");
638
+ }
639
+ else {
640
+ console.log("使用 /connect " + plat + " guide 获取完整中文向导");
641
+ console.log("测试连通: /connect " + plat + " test");
642
+ }
643
+ console.log("doctor: qling doctor (会检查 channel 配置)");
644
+ }
645
+ else {
646
+ console.log("可用: telegram, slack, feishu, dingtalk, wechat");
647
+ console.log("示例: qling connect feishu guide");
648
+ }
649
+ console.log("敏感处理: 绝不写入 .env, 复用 scanner + doctor");
650
+ console.log("-----------------------------------------");
651
+ return;
652
+ }
653
+ if (decision.mode === "statusline") {
654
+ const snapshot = collectLocalStatusLineSnapshot({
655
+ workspaceDir: loaded.config.runtime.workspace_dir,
656
+ model: loaded.config.llm.model,
657
+ permissionMode: loaded.config.guard.permissions.default,
658
+ maxTokens: loaded.config.runtime.max_token_budget,
659
+ costPer1kTokens: parseStatusLineCostPer1k(process.env.QLING_STATUSLINE_COST_PER_1K_TOKENS),
660
+ });
661
+ console.log("");
662
+ console.log("◎ statusline");
663
+ console.log("-----------------------------------------");
664
+ console.log(formatStatusLine(snapshot));
665
+ console.log("-----------------------------------------");
666
+ console.log("");
667
+ return;
668
+ }
669
+ if (decision.mode === "recap") {
670
+ const request = parseSavedSessionRecapArgs(decision.subArgs);
671
+ console.log(await buildSavedSessionRecap(stateDir, request));
672
+ return;
673
+ }
674
+ if (decision.mode === "permissions") {
675
+ const [rawSub, toolName] = decision.subArgs;
676
+ const sub = (rawSub ?? "status").toLowerCase();
677
+ if (sub === "explain" || sub === "解释") {
678
+ if (!toolName) {
679
+ console.error("用法: qling permissions explain <tool>");
680
+ process.exit(1);
681
+ }
682
+ const report = explainLocalPermissionDecision({
683
+ defaultMode: loaded.config.guard.permissions.default,
684
+ rules: loaded.config.guard.permissions.rules,
685
+ env: process.env,
686
+ }, toolName);
687
+ console.log(formatPermissionExplanationReport(report).join("\n"));
688
+ return;
689
+ }
690
+ const report = buildLocalPermissionsReport({
691
+ defaultMode: loaded.config.guard.permissions.default,
692
+ rules: loaded.config.guard.permissions.rules,
693
+ env: process.env,
694
+ });
695
+ console.log(formatLocalPermissionsReport(report).join("\n"));
696
+ return;
697
+ }
698
+ if (decision.mode === "config") {
699
+ console.log(formatLocalConfigReport(buildLocalConfigReport(loaded.config)).join("\n"));
700
+ return;
701
+ }
702
+ if (decision.mode === "mcp") {
703
+ const { handleMcpCli } = await import("./cli/mcp-control.js");
704
+ const code = await handleMcpCli(decision.subArgs, {
705
+ mcpConfig: loaded.config.mcp,
706
+ env: {
707
+ ...process.env,
708
+ QLING_MCP_SERVERS: originalMcpServersEnv ?? process.env.QLING_MCP_SERVERS,
709
+ },
710
+ stateDir: loaded.config.runtime.file_state_dir,
711
+ });
712
+ if (code !== 0)
713
+ process.exit(code);
714
+ return;
715
+ }
716
+ if (decision.mode === "hooks") {
717
+ console.log(formatLocalHooksReport(buildLocalHooksReport(loaded.config.guard)).join("\n"));
718
+ return;
719
+ }
720
+ if (decision.mode === "daemon") {
721
+ const [sub] = decision.subArgs;
722
+ const daemonOptions = {
723
+ stateDir: process.env.QLING_FILE_STATE_DIR || loaded.config.runtime.file_state_dir || path.join(os.homedir(), ".qling"),
724
+ port: Number(process.env.QLING_DAEMON_PORT || "9998"),
725
+ daemonEntry: path.join(DIST_DIR, "daemon.js"),
726
+ cwd: process.cwd(),
727
+ env: process.env,
728
+ };
729
+ if (sub === "start") {
730
+ const result = await startDaemon(daemonOptions);
731
+ if (result.started) {
732
+ console.error(`✅ qling daemon 已启动 (pid=${result.status.pid ?? "unknown"}, port=${result.status.port})`);
733
+ }
734
+ else {
735
+ console.error(`ℹ️ qling daemon 已在运行 (pid=${result.status.pid ?? "unknown"}, port=${result.status.port})`);
736
+ }
737
+ return;
738
+ }
739
+ if (sub === "status") {
740
+ const status = await getDaemonStatus(daemonOptions);
741
+ console.log(JSON.stringify(status, null, 2));
742
+ return;
743
+ }
744
+ if (sub === "stop") {
745
+ const result = await stopDaemon(daemonOptions);
746
+ if (result.stopped) {
747
+ console.error("🛑 qling daemon 已停止");
748
+ return;
749
+ }
750
+ if (result.status.healthy && !result.status.managed) {
751
+ console.error("❌ 检测到 daemon 正在运行,但不受当前 CLI 管理;请手动停止该进程。");
752
+ process.exit(1);
753
+ }
754
+ console.error("ℹ️ qling daemon 当前未运行");
755
+ return;
756
+ }
757
+ console.error("用法: qling daemon start|status|stop");
758
+ process.exit(1);
759
+ }
760
+ if (decision.mode === "agents") {
761
+ const manager = await getStandaloneMissionManager();
762
+ const { value: missions, source } = await withMissionFallback(async () => {
763
+ const resp = await axios.get(`${daemonUrl}/missions`, { timeout: 2000 });
764
+ return resp.data;
765
+ }, async () => manager.listMissions());
766
+ console.error(source === "daemon" ? "📡 数据来源: qlingd 守护进程" : "📁 数据来源: 本地文件缓存");
767
+ console.log(renderAgentsView(missions));
768
+ return;
769
+ }
770
+ if (decision.mode === "logs") {
771
+ const missionId = decision.subArgs[0];
772
+ if (!missionId) {
773
+ console.error("用法: qling logs <id>");
774
+ process.exit(1);
775
+ }
776
+ const manager = await getStandaloneMissionManager();
777
+ const { value: logs, source } = await withMissionFallback(async () => {
778
+ const resp = await axios.get(`${daemonUrl}/missions/${encodeURIComponent(missionId)}/logs`, { timeout: 2000 });
779
+ return resp.data;
780
+ }, async () => manager.getMissionLogs(missionId));
781
+ console.error(source === "daemon" ? "📡 数据来源: qlingd 守护进程" : "📁 数据来源: 本地文件缓存");
782
+ printMissionLogs(logs);
783
+ return;
784
+ }
785
+ if (decision.mode === "mission") {
786
+ const [rawSub, ...mArgs] = decision.subArgs;
787
+ const sub = normalizeMissionSubcommand(rawSub);
788
+ const manager = await getStandaloneMissionManager();
789
+ if (sub === "start") {
790
+ const task = mArgs.join(" ");
791
+ if (!task) {
792
+ console.error("用法: qling mission start \"任务描述\"");
793
+ process.exit(1);
794
+ }
795
+ try {
796
+ const resp = await axios.post(`${daemonUrl}/missions`, {
797
+ name: "CLI Mission",
798
+ description: task,
799
+ sessionId: "session-daemon-submit",
800
+ }, { timeout: 2000 });
801
+ console.error(`🚀 使命已成功提交至 qlingd 守护进程: ${resp.data.missionId}`);
802
+ console.error("提示: 您现在可以关闭此终端,任务将在后台继续。");
803
+ return;
804
+ }
805
+ catch (err) {
806
+ if (!shouldFallbackToLocalMission(err)) {
807
+ throw err;
808
+ }
809
+ }
810
+ }
811
+ if (sub === "retry") {
812
+ const missionId = mArgs[0];
813
+ if (!missionId) {
814
+ console.error("用法: qling mission retry <id>");
815
+ process.exit(1);
816
+ }
817
+ try {
818
+ const resp = await axios.post(`${daemonUrl}/missions/${encodeURIComponent(missionId)}/retry`, {}, { timeout: 2000 });
819
+ console.error(`🚀 已向 qlingd 提交重试使命: ${resp.data.missionId}`);
820
+ return;
821
+ }
822
+ catch (err) {
823
+ if (!shouldFallbackToLocalMission(err)) {
824
+ throw err;
825
+ }
826
+ }
827
+ }
828
+ if (isPureMissionManagementSubcommand(sub)) {
829
+ if (sub === "list") {
830
+ const { value: missions, source } = await withMissionFallback(async () => {
831
+ const resp = await axios.get(`${daemonUrl}/missions`, { timeout: 2000 });
832
+ return resp.data;
833
+ }, async () => manager.listMissions());
834
+ printMissionList(missions, source === "daemon" ? "📡 数据来源: qlingd 守护进程" : "📁 数据来源: 本地文件缓存 (守护进程未运行)");
835
+ return;
836
+ }
837
+ if (sub === "show") {
838
+ const missionId = mArgs[0];
839
+ if (!missionId) {
840
+ console.error("用法: qling mission show <id>");
841
+ process.exit(1);
842
+ }
843
+ const { value: mission, source } = await withMissionFallback(async () => {
844
+ const resp = await axios.get(`${daemonUrl}/missions/${encodeURIComponent(missionId)}`, { timeout: 2000 });
845
+ return resp.data;
846
+ }, async () => manager.getMissionOrThrow(missionId));
847
+ console.error(source === "daemon" ? "📡 数据来源: qlingd 守护进程" : "📁 数据来源: 本地文件缓存");
848
+ printMissionDetail(mission);
849
+ return;
850
+ }
851
+ if (sub === "logs") {
852
+ const missionId = mArgs[0];
853
+ if (!missionId) {
854
+ console.error("用法: qling mission logs <id>");
855
+ process.exit(1);
856
+ }
857
+ const { value: logs, source } = await withMissionFallback(async () => {
858
+ const resp = await axios.get(`${daemonUrl}/missions/${encodeURIComponent(missionId)}/logs`, { timeout: 2000 });
859
+ return resp.data;
860
+ }, async () => manager.getMissionLogs(missionId));
861
+ console.error(source === "daemon" ? "📡 数据来源: qlingd 守护进程" : "📁 数据来源: 本地文件缓存");
862
+ printMissionLogs(logs);
863
+ return;
864
+ }
865
+ if (sub === "attach") {
866
+ const missionId = mArgs[0];
867
+ if (!missionId) {
868
+ console.error("用法: qling mission attach <id>");
869
+ process.exit(1);
870
+ }
871
+ const reader = await buildMissionReader(missionId, daemonUrl, stateDir);
872
+ console.error(reader.source === "daemon" ? "📡 数据来源: qlingd 守护进程" : "📁 数据来源: 本地文件缓存");
873
+ await followMissionAttach(missionId, reader);
874
+ return;
875
+ }
876
+ if (sub === "pause" || sub === "resume" || sub === "cancel") {
877
+ const missionId = mArgs[0];
878
+ if (!missionId) {
879
+ console.error(`用法: qling mission ${rawSub ?? sub} <id>`);
880
+ process.exit(1);
881
+ }
882
+ const { value: mission, source } = await withMissionFallback(async () => {
883
+ const resp = await axios.post(`${daemonUrl}/missions/${encodeURIComponent(missionId)}/${sub}`, {}, { timeout: 2000 });
884
+ return resp.data.mission;
885
+ }, async () => {
886
+ if (sub === "pause")
887
+ return manager.pauseMission(missionId, "cli_local");
888
+ if (sub === "resume")
889
+ return manager.resumeMission(missionId, "cli_local");
890
+ return manager.cancelMission(missionId, "cli_local");
891
+ });
892
+ console.error(source === "daemon" ? "📡 动作已发送到 qlingd 守护进程" : "📁 动作已在本地文件状态上执行");
893
+ printMissionDetail(mission);
894
+ return;
895
+ }
896
+ }
897
+ }
898
+ const staticEnabled = {};
899
+ for (const [name, cfg] of Object.entries(loaded.config.tools)) {
900
+ staticEnabled[name] = cfg.enabled;
901
+ }
902
+ const tools = buildToolRegistry({ staticEnabled });
903
+ const agentConfig = {
904
+ apiKey: loaded.config.llm.api_key ||
905
+ process.env.DEEPSEEK_API_KEY ||
906
+ process.env.OPENAI_API_KEY ||
907
+ "",
908
+ provider: loaded.config.llm.provider,
909
+ endpoint: loaded.config.llm.endpoint,
910
+ model: loaded.config.llm.model,
911
+ maxIterations: loaded.config.runtime.max_steps,
912
+ tools,
913
+ tokenBudget: {
914
+ maxTokens: loaded.config.runtime.max_token_budget,
915
+ totalBudget: loaded.config.runtime.max_token_budget,
916
+ nudgeThreshold: 0.2,
917
+ },
918
+ runtime: {
919
+ workspaceDir: loaded.config.runtime.workspace_dir,
920
+ fileCacheDir: loaded.config.runtime.file_cache_dir,
921
+ fileStateDir: loaded.config.runtime.file_state_dir,
922
+ maxSteps: loaded.config.runtime.max_steps,
923
+ parseRetries: loaded.config.runtime.parse_retries,
924
+ maxTokenBudget: loaded.config.runtime.max_token_budget,
925
+ toolRepeatLimit: loaded.config.runtime.tool_repeat_limit,
926
+ timeoutMs: loaded.config.runtime.timeout_ms,
927
+ },
928
+ logging: {
929
+ level: loaded.config.logging.level,
930
+ format: loaded.config.logging.format,
931
+ inspectPrompt: loaded.config.logging.inspect_prompt,
932
+ inspectRequest: loaded.config.logging.inspect_request,
933
+ inspectDumpDir: loaded.config.logging.inspect_dump_dir,
934
+ },
935
+ };
936
+ // --- 延迟实例化 AgentLoop,防止 setup 等管理命令因缺失 Key 而崩溃 ---
937
+ const agent = new AgentLoop(agentConfig);
938
+ await agent.waitForInit();
939
+ try {
940
+ if (decision.mode === "workflow") {
941
+ const [sub, runId] = decision.subArgs;
942
+ if (sub === "resume" && runId) {
943
+ console.error(`🔄 正在从 Checkpoint 恢复: ${runId}`);
944
+ const checkpoint = await agent.getWorkflowRuntime().resume(runId);
945
+ agent.syncWorkflowState(checkpoint);
946
+ const response = await agent.run();
947
+ console.log(response);
948
+ return;
949
+ }
950
+ console.error("用法: qling workflow resume <run_id>");
951
+ process.exit(1);
952
+ }
953
+ if (decision.mode === "memory") {
954
+ const [sub] = decision.subArgs;
955
+ if (sub === "reindex") {
956
+ console.error("🧠 正在重新构建语义记忆向量索引...");
957
+ await agent.getMemoryStore().rebuildSemanticIndex();
958
+ console.error("✅ 索引重建完成");
959
+ return;
960
+ }
961
+ console.error("用法: qling memory reindex [--full]");
962
+ process.exit(1);
963
+ }
964
+ if (decision.mode === "dashboard") {
965
+ const [sub] = decision.subArgs;
966
+ if (sub === "start") {
967
+ const port = process.env.QLING_DASHBOARD_PORT || "9999";
968
+ const ds = agent.dashboardServer;
969
+ // 检查是否真正成功开启监听
970
+ if (!ds || !ds.listening) {
971
+ console.error(`❌ Dashboard 启动失败,请检查端口 ${port} 是否被占用。`);
972
+ process.exit(1);
973
+ }
974
+ console.error("📊 Dashboard 运行中。按 Ctrl+C 退出。");
975
+ await new Promise(() => { }); // Keep alive
976
+ return;
977
+ }
978
+ console.error("用法: qling dashboard start");
979
+ process.exit(1);
980
+ }
981
+ if (decision.mode === "discovery") {
982
+ const [sub] = decision.subArgs;
983
+ if (sub === "sync") {
984
+ console.error("🔍 正在同步动态插件与技能...");
985
+ await agent.getDiscoveryRegistry().syncAll();
986
+ const items = agent.getDiscoveryRegistry().getAllItems();
987
+ console.error(`✅ 同步完成,共发现 ${items.length} 个项目:`);
988
+ items.forEach(it => console.error(` - [${it.manifest.type}] ${it.manifest.name} v${it.manifest.version}`));
989
+ return;
990
+ }
991
+ console.error("用法: qling discovery sync");
992
+ process.exit(1);
993
+ }
994
+ if (decision.mode === "mission") {
995
+ const [rawSub, ...mArgs] = decision.subArgs;
996
+ const sub = normalizeMissionSubcommand(rawSub);
997
+ const manager = agent.getMissionManager();
998
+ if (sub === "start") {
999
+ const task = mArgs.join(" ");
1000
+ if (!task) {
1001
+ console.error("用法: qling mission start \"任务描述\"");
1002
+ process.exit(1);
1003
+ }
1004
+ // 尝试发给守护进程
1005
+ try {
1006
+ const resp = await axios.post(`${daemonUrl}/missions`, {
1007
+ name: "CLI Mission",
1008
+ description: task,
1009
+ sessionId: agent.getSessionId(),
1010
+ }, { timeout: 2000 });
1011
+ console.error(`🚀 使命已成功提交至 qlingd 守护进程: ${resp.data.missionId}`);
1012
+ console.error(`提示: 您现在可以关闭此终端,任务将在后台继续。`);
1013
+ return;
1014
+ }
1015
+ catch {
1016
+ console.warn(`⚠️ 守护进程未启动,将在当前前台进程执行使命...`);
1017
+ const mission = await manager.createMission("Local Mission", task, agent.getSessionId());
1018
+ const response = await executeLocalMission(agent, manager, mission);
1019
+ console.log(response);
1020
+ return;
1021
+ }
1022
+ }
1023
+ if (sub === "list") {
1024
+ const { value: missions, source } = await withMissionFallback(async () => {
1025
+ const resp = await axios.get(`${daemonUrl}/missions`, { timeout: 2000 });
1026
+ return resp.data;
1027
+ }, async () => manager.listMissions());
1028
+ printMissionList(missions, source === "daemon" ? "📡 数据来源: qlingd 守护进程" : "📁 数据来源: 本地文件缓存 (守护进程未运行)");
1029
+ return;
1030
+ }
1031
+ if (sub === "show") {
1032
+ const missionId = mArgs[0];
1033
+ if (!missionId) {
1034
+ console.error("用法: qling mission show <id>");
1035
+ process.exit(1);
1036
+ }
1037
+ const { value: mission, source } = await withMissionFallback(async () => {
1038
+ const resp = await axios.get(`${daemonUrl}/missions/${encodeURIComponent(missionId)}`, { timeout: 2000 });
1039
+ return resp.data;
1040
+ }, async () => manager.getMissionOrThrow(missionId));
1041
+ console.error(source === "daemon" ? "📡 数据来源: qlingd 守护进程" : "📁 数据来源: 本地文件缓存");
1042
+ printMissionDetail(mission);
1043
+ return;
1044
+ }
1045
+ if (sub === "logs") {
1046
+ const missionId = mArgs[0];
1047
+ if (!missionId) {
1048
+ console.error("用法: qling mission logs <id>");
1049
+ process.exit(1);
1050
+ }
1051
+ const { value: logs, source } = await withMissionFallback(async () => {
1052
+ const resp = await axios.get(`${daemonUrl}/missions/${encodeURIComponent(missionId)}/logs`, { timeout: 2000 });
1053
+ return resp.data;
1054
+ }, async () => manager.getMissionLogs(missionId));
1055
+ console.error(source === "daemon" ? "📡 数据来源: qlingd 守护进程" : "📁 数据来源: 本地文件缓存");
1056
+ printMissionLogs(logs);
1057
+ return;
1058
+ }
1059
+ if (sub === "pause" || sub === "resume" || sub === "cancel") {
1060
+ const missionId = mArgs[0];
1061
+ if (!missionId) {
1062
+ console.error(`用法: qling mission ${rawSub ?? sub} <id>`);
1063
+ process.exit(1);
1064
+ }
1065
+ const { value: mission, source } = await withMissionFallback(async () => {
1066
+ const resp = await axios.post(`${daemonUrl}/missions/${encodeURIComponent(missionId)}/${sub}`, {}, { timeout: 2000 });
1067
+ return resp.data.mission;
1068
+ }, async () => {
1069
+ if (sub === "pause")
1070
+ return manager.pauseMission(missionId, "cli_local");
1071
+ if (sub === "resume")
1072
+ return manager.resumeMission(missionId, "cli_local");
1073
+ return manager.cancelMission(missionId, "cli_local");
1074
+ });
1075
+ console.error(source === "daemon" ? "📡 动作已发送到 qlingd 守护进程" : "📁 动作已在本地文件状态上执行");
1076
+ printMissionDetail(mission);
1077
+ return;
1078
+ }
1079
+ if (sub === "retry") {
1080
+ const missionId = mArgs[0];
1081
+ if (!missionId) {
1082
+ console.error("用法: qling mission retry <id>");
1083
+ process.exit(1);
1084
+ }
1085
+ try {
1086
+ const resp = await axios.post(`${daemonUrl}/missions/${encodeURIComponent(missionId)}/retry`, {}, { timeout: 2000 });
1087
+ console.error(`🚀 已向 qlingd 提交重试使命: ${resp.data.missionId}`);
1088
+ return;
1089
+ }
1090
+ catch (err) {
1091
+ if (!shouldFallbackToLocalMission(err)) {
1092
+ throw err;
1093
+ }
1094
+ console.warn("⚠️ 守护进程未启动,将在当前前台进程执行 retry...");
1095
+ const mission = await manager.retryMission(missionId);
1096
+ const response = await executeLocalMission(agent, manager, mission);
1097
+ console.error(`🔄 已创建本地重试使命: ${mission.id}`);
1098
+ console.log(response);
1099
+ return;
1100
+ }
1101
+ }
1102
+ console.error("用法: qling mission start|list|show|logs|attach|pause|resume|cancel|stop|terminate|retry|respawn");
1103
+ process.exit(1);
1104
+ }
1105
+ if (decision.mode === "run") {
1106
+ try {
1107
+ const channel = resolveRunModeChannel(decision.mode, loaded.config.channels);
1108
+ if (channel) {
1109
+ await channel.start();
1110
+ agent.setChannel(channel);
1111
+ }
1112
+ }
1113
+ catch (err) {
1114
+ if (err instanceof CliChannelBootstrapError) {
1115
+ console.error(formatCliError(err.code, err.message));
1116
+ process.exit(1);
1117
+ }
1118
+ console.error(formatCliError("CLI_CHANNEL_INIT_FAILED", err instanceof Error ? err.message : String(err)));
1119
+ process.exit(1);
1120
+ }
1121
+ }
1122
+ if (decision.mode === "chat") {
1123
+ const repl = new StreamingREPL(agent, {
1124
+ continueSession: decision.global.continueSession,
1125
+ resumeSession: decision.global.resumeSession,
1126
+ });
1127
+ await repl.start();
1128
+ return;
1129
+ }
1130
+ if (decision.mode === "repl") {
1131
+ const repl = new Repl(agent, {
1132
+ continueSession: decision.global.continueSession,
1133
+ resumeSession: decision.global.resumeSession,
1134
+ });
1135
+ await repl.start();
1136
+ return;
1137
+ }
1138
+ const task = decision.task ?? "";
1139
+ agent.addUserMessage(task);
1140
+ const response = await agent.run();
1141
+ console.log(response);
1142
+ }
1143
+ catch (err) {
1144
+ const code = err.code || "RUN_FAILED";
1145
+ console.error(formatCliError(code, err.message || String(err)));
1146
+ process.exit(1);
1147
+ }
1148
+ finally {
1149
+ try {
1150
+ await agent.shutdown();
1151
+ }
1152
+ catch {
1153
+ // ignore
1154
+ }
1155
+ }
1156
+ }
1157
+ main();