@jingyi0605/codingns 0.2.0 → 0.3.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 (328) hide show
  1. package/README.md +44 -0
  2. package/bin/codingns.mjs +918 -55
  3. package/dist/public/assets/{TerminalPage-BlbQuWi1.js → TerminalPage-Dfw1QUqW.js} +19 -19
  4. package/dist/public/assets/index-DR2rPNi7.css +1 -0
  5. package/dist/public/assets/index-DTOruahn.js +114 -0
  6. package/dist/public/index.html +2 -2
  7. package/dist/server/config/env.d.ts +3 -0
  8. package/dist/server/config/env.js +35 -3
  9. package/dist/server/config/env.js.map +1 -1
  10. package/dist/server/modules/assistant-capability/assistant-capability-controller.d.ts +89 -0
  11. package/dist/server/modules/assistant-capability/assistant-capability-controller.js +138 -0
  12. package/dist/server/modules/assistant-capability/assistant-capability-controller.js.map +1 -0
  13. package/dist/server/modules/assistant-capability/assistant-capability-service.d.ts +115 -0
  14. package/dist/server/modules/assistant-capability/assistant-capability-service.js +241 -0
  15. package/dist/server/modules/assistant-capability/assistant-capability-service.js.map +1 -0
  16. package/dist/server/modules/butler/butler-control-session-service.d.ts +3 -1
  17. package/dist/server/modules/butler/butler-control-session-service.js +96 -33
  18. package/dist/server/modules/butler/butler-control-session-service.js.map +1 -1
  19. package/dist/server/modules/butler/butler-follow-up-scheduler.d.ts +9 -0
  20. package/dist/server/modules/butler/butler-follow-up-scheduler.js +47 -11
  21. package/dist/server/modules/butler/butler-follow-up-scheduler.js.map +1 -1
  22. package/dist/server/modules/butler/butler-follow-up-service.d.ts +7 -1
  23. package/dist/server/modules/butler/butler-follow-up-service.js +10 -0
  24. package/dist/server/modules/butler/butler-follow-up-service.js.map +1 -1
  25. package/dist/server/modules/butler/butler-session-service.d.ts +3 -1
  26. package/dist/server/modules/butler/butler-session-service.js +82 -16
  27. package/dist/server/modules/butler/butler-session-service.js.map +1 -1
  28. package/dist/server/modules/butler/butler-session-summary-service.d.ts +8 -1
  29. package/dist/server/modules/butler/butler-session-summary-service.js +34 -7
  30. package/dist/server/modules/butler/butler-session-summary-service.js.map +1 -1
  31. package/dist/server/modules/butler/context-aggregator.js +44 -13
  32. package/dist/server/modules/butler/context-aggregator.js.map +1 -1
  33. package/dist/server/modules/butler/patrol-scheduler.d.ts +9 -0
  34. package/dist/server/modules/butler/patrol-scheduler.js +63 -9
  35. package/dist/server/modules/butler/patrol-scheduler.js.map +1 -1
  36. package/dist/server/modules/butler/session-summary-scheduler.d.ts +9 -0
  37. package/dist/server/modules/butler/session-summary-scheduler.js +47 -11
  38. package/dist/server/modules/butler/session-summary-scheduler.js.map +1 -1
  39. package/dist/server/modules/debug-target/debug-runtime-reconciliation-scheduler.d.ts +38 -0
  40. package/dist/server/modules/debug-target/debug-runtime-reconciliation-scheduler.js +99 -0
  41. package/dist/server/modules/debug-target/debug-runtime-reconciliation-scheduler.js.map +1 -0
  42. package/dist/server/modules/debug-target/debug-target-controller.d.ts +70 -0
  43. package/dist/server/modules/debug-target/debug-target-controller.js +113 -0
  44. package/dist/server/modules/debug-target/debug-target-controller.js.map +1 -0
  45. package/dist/server/modules/debug-target/debug-target-service.d.ts +105 -0
  46. package/dist/server/modules/debug-target/debug-target-service.js +1644 -0
  47. package/dist/server/modules/debug-target/debug-target-service.js.map +1 -0
  48. package/dist/server/modules/debug-target/framework-compatibility-matrix.d.ts +4 -0
  49. package/dist/server/modules/debug-target/framework-compatibility-matrix.js +45 -0
  50. package/dist/server/modules/debug-target/framework-compatibility-matrix.js.map +1 -0
  51. package/dist/server/modules/debug-target/launch-adapter-registry.d.ts +25 -0
  52. package/dist/server/modules/debug-target/launch-adapter-registry.js +445 -0
  53. package/dist/server/modules/debug-target/launch-adapter-registry.js.map +1 -0
  54. package/dist/server/modules/file/file-constants.d.ts +1 -0
  55. package/dist/server/modules/file/file-constants.js +1 -0
  56. package/dist/server/modules/file/file-constants.js.map +1 -1
  57. package/dist/server/modules/file/file-content-service.d.ts +2 -1
  58. package/dist/server/modules/file/file-content-service.js +53 -0
  59. package/dist/server/modules/file/file-content-service.js.map +1 -1
  60. package/dist/server/modules/file/file-controller.js +12 -3
  61. package/dist/server/modules/file/file-controller.js.map +1 -1
  62. package/dist/server/modules/file/file-preview-link-service.js +6 -37
  63. package/dist/server/modules/file/file-preview-link-service.js.map +1 -1
  64. package/dist/server/modules/file/file-preview-service.d.ts +6 -12
  65. package/dist/server/modules/file/file-preview-service.js +114 -28
  66. package/dist/server/modules/file/file-preview-service.js.map +1 -1
  67. package/dist/server/modules/file/file-preview-types.d.ts +37 -0
  68. package/dist/server/modules/file/file-preview-types.js +84 -0
  69. package/dist/server/modules/file/file-preview-types.js.map +1 -0
  70. package/dist/server/modules/git/commit-orchestrator.d.ts +4 -1
  71. package/dist/server/modules/git/commit-orchestrator.js +18 -1
  72. package/dist/server/modules/git/commit-orchestrator.js.map +1 -1
  73. package/dist/server/modules/git/git-auth.d.ts +25 -0
  74. package/dist/server/modules/git/git-auth.js +88 -0
  75. package/dist/server/modules/git/git-auth.js.map +1 -0
  76. package/dist/server/modules/git/git-controller.d.ts +12 -0
  77. package/dist/server/modules/git/git-controller.js +18 -1
  78. package/dist/server/modules/git/git-controller.js.map +1 -1
  79. package/dist/server/modules/git/git-read-service.d.ts +3 -1
  80. package/dist/server/modules/git/git-read-service.js +119 -2
  81. package/dist/server/modules/git/git-read-service.js.map +1 -1
  82. package/dist/server/modules/git/git-remote-credential-service.d.ts +9 -0
  83. package/dist/server/modules/git/git-remote-credential-service.js +76 -0
  84. package/dist/server/modules/git/git-remote-credential-service.js.map +1 -0
  85. package/dist/server/modules/git/git-write-service.d.ts +5 -2
  86. package/dist/server/modules/git/git-write-service.js +33 -17
  87. package/dist/server/modules/git/git-write-service.js.map +1 -1
  88. package/dist/server/modules/git/types.d.ts +26 -0
  89. package/dist/server/modules/git/workspace-repo-guard.js +3 -2
  90. package/dist/server/modules/git/workspace-repo-guard.js.map +1 -1
  91. package/dist/server/modules/provider/codex-model-options.d.ts +3 -1
  92. package/dist/server/modules/provider/codex-model-options.js +4 -1
  93. package/dist/server/modules/provider/codex-model-options.js.map +1 -1
  94. package/dist/server/modules/provider/opencode-model-options.d.ts +3 -1
  95. package/dist/server/modules/provider/opencode-model-options.js +5 -1
  96. package/dist/server/modules/provider/opencode-model-options.js.map +1 -1
  97. package/dist/server/modules/provider/provider-discovery-helper-client.d.ts +24 -0
  98. package/dist/server/modules/provider/provider-discovery-helper-client.js +14 -0
  99. package/dist/server/modules/provider/provider-discovery-helper-client.js.map +1 -1
  100. package/dist/server/modules/provider/provider-discovery-helper-process.js +54 -0
  101. package/dist/server/modules/provider/provider-discovery-helper-process.js.map +1 -1
  102. package/dist/server/modules/sessions/session-activity-authority-service.js +13 -1
  103. package/dist/server/modules/sessions/session-activity-authority-service.js.map +1 -1
  104. package/dist/server/modules/sessions/session-activity-inspector.js +21 -5
  105. package/dist/server/modules/sessions/session-activity-inspector.js.map +1 -1
  106. package/dist/server/modules/sessions/session-controller.d.ts +5 -0
  107. package/dist/server/modules/sessions/session-controller.js +16 -0
  108. package/dist/server/modules/sessions/session-controller.js.map +1 -1
  109. package/dist/server/modules/sessions/session-history-service.d.ts +27 -7
  110. package/dist/server/modules/sessions/session-history-service.js +439 -81
  111. package/dist/server/modules/sessions/session-history-service.js.map +1 -1
  112. package/dist/server/modules/sessions/session-live-runtime-service.d.ts +2 -1
  113. package/dist/server/modules/sessions/session-live-runtime-service.js +12 -0
  114. package/dist/server/modules/sessions/session-live-runtime-service.js.map +1 -1
  115. package/dist/server/modules/skills/skill-controller.d.ts +23 -0
  116. package/dist/server/modules/skills/skill-controller.js +35 -0
  117. package/dist/server/modules/skills/skill-controller.js.map +1 -0
  118. package/dist/server/modules/skills/skill-manager-service.d.ts +86 -0
  119. package/dist/server/modules/skills/skill-manager-service.js +557 -0
  120. package/dist/server/modules/skills/skill-manager-service.js.map +1 -0
  121. package/dist/server/modules/skills/skill-reconciler.d.ts +21 -0
  122. package/dist/server/modules/skills/skill-reconciler.js +99 -0
  123. package/dist/server/modules/skills/skill-reconciler.js.map +1 -0
  124. package/dist/server/modules/skills/skill-sync-planner.d.ts +8 -0
  125. package/dist/server/modules/skills/skill-sync-planner.js +20 -0
  126. package/dist/server/modules/skills/skill-sync-planner.js.map +1 -0
  127. package/dist/server/modules/skills/skill-target-adapter.d.ts +34 -0
  128. package/dist/server/modules/skills/skill-target-adapter.js +65 -0
  129. package/dist/server/modules/skills/skill-target-adapter.js.map +1 -0
  130. package/dist/server/modules/tailscale/tailscale-controller.d.ts +15 -0
  131. package/dist/server/modules/tailscale/tailscale-controller.js +33 -0
  132. package/dist/server/modules/tailscale/tailscale-controller.js.map +1 -0
  133. package/dist/server/modules/tailscale/tailscale-helper-client.d.ts +41 -0
  134. package/dist/server/modules/tailscale/tailscale-helper-client.js +135 -0
  135. package/dist/server/modules/tailscale/tailscale-helper-client.js.map +1 -0
  136. package/dist/server/modules/tailscale/tailscale-helper-process.d.ts +1 -0
  137. package/dist/server/modules/tailscale/tailscale-helper-process.js +327 -0
  138. package/dist/server/modules/tailscale/tailscale-helper-process.js.map +1 -0
  139. package/dist/server/modules/tailscale/tailscale-manager.d.ts +41 -0
  140. package/dist/server/modules/tailscale/tailscale-manager.js +259 -0
  141. package/dist/server/modules/tailscale/tailscale-manager.js.map +1 -0
  142. package/dist/server/modules/tailscale/tailscale-service.d.ts +43 -0
  143. package/dist/server/modules/tailscale/tailscale-service.js +201 -0
  144. package/dist/server/modules/tailscale/tailscale-service.js.map +1 -0
  145. package/dist/server/modules/tasks/event-loop-monitor.d.ts +21 -0
  146. package/dist/server/modules/tasks/event-loop-monitor.js +64 -0
  147. package/dist/server/modules/tasks/event-loop-monitor.js.map +1 -0
  148. package/dist/server/modules/tasks/observability-controller.d.ts +30 -0
  149. package/dist/server/modules/tasks/observability-controller.js +44 -0
  150. package/dist/server/modules/tasks/observability-controller.js.map +1 -0
  151. package/dist/server/modules/tasks/observability-service.d.ts +32 -0
  152. package/dist/server/modules/tasks/observability-service.js +104 -0
  153. package/dist/server/modules/tasks/observability-service.js.map +1 -0
  154. package/dist/server/modules/tasks/scheduler-metrics.d.ts +41 -0
  155. package/dist/server/modules/tasks/scheduler-metrics.js +92 -0
  156. package/dist/server/modules/tasks/scheduler-metrics.js.map +1 -0
  157. package/dist/server/modules/tasks/task-activity-log.d.ts +39 -0
  158. package/dist/server/modules/tasks/task-activity-log.js +43 -0
  159. package/dist/server/modules/tasks/task-activity-log.js.map +1 -0
  160. package/dist/server/modules/tasks/task-helper-client.d.ts +11 -0
  161. package/dist/server/modules/tasks/task-helper-client.js +132 -0
  162. package/dist/server/modules/tasks/task-helper-client.js.map +1 -0
  163. package/dist/server/modules/tasks/task-helper-process-handlers.d.ts +16 -0
  164. package/dist/server/modules/tasks/task-helper-process-handlers.js +14 -0
  165. package/dist/server/modules/tasks/task-helper-process-handlers.js.map +1 -0
  166. package/dist/server/modules/tasks/task-helper-process.d.ts +1 -0
  167. package/dist/server/modules/tasks/task-helper-process.js +49 -0
  168. package/dist/server/modules/tasks/task-helper-process.js.map +1 -0
  169. package/dist/server/modules/tasks/task-lane-executors.d.ts +2 -0
  170. package/dist/server/modules/tasks/task-lane-executors.js +15 -0
  171. package/dist/server/modules/tasks/task-lane-executors.js.map +1 -0
  172. package/dist/server/modules/tasks/task-manager.d.ts +15 -0
  173. package/dist/server/modules/tasks/task-manager.js +36 -0
  174. package/dist/server/modules/tasks/task-manager.js.map +1 -0
  175. package/dist/server/modules/tasks/task-metrics.d.ts +9 -0
  176. package/dist/server/modules/tasks/task-metrics.js +81 -0
  177. package/dist/server/modules/tasks/task-metrics.js.map +1 -0
  178. package/dist/server/modules/tasks/task-registry.d.ts +7 -0
  179. package/dist/server/modules/tasks/task-registry.js +21 -0
  180. package/dist/server/modules/tasks/task-registry.js.map +1 -0
  181. package/dist/server/modules/tasks/task-scheduler.d.ts +31 -0
  182. package/dist/server/modules/tasks/task-scheduler.js +473 -0
  183. package/dist/server/modules/tasks/task-scheduler.js.map +1 -0
  184. package/dist/server/modules/tasks/task-types.d.ts +106 -0
  185. package/dist/server/modules/tasks/task-types.js +23 -0
  186. package/dist/server/modules/tasks/task-types.js.map +1 -0
  187. package/dist/server/modules/terminal/command-template-service.d.ts +4 -0
  188. package/dist/server/modules/terminal/command-template-service.js +5 -3
  189. package/dist/server/modules/terminal/command-template-service.js.map +1 -1
  190. package/dist/server/modules/terminal/runtime/terminal-log-spooler.d.ts +7 -3
  191. package/dist/server/modules/terminal/runtime/terminal-log-spooler.js +95 -15
  192. package/dist/server/modules/terminal/runtime/terminal-log-spooler.js.map +1 -1
  193. package/dist/server/modules/terminal/runtime/terminal-log-writer-client.d.ts +21 -0
  194. package/dist/server/modules/terminal/runtime/terminal-log-writer-client.js +144 -0
  195. package/dist/server/modules/terminal/runtime/terminal-log-writer-client.js.map +1 -0
  196. package/dist/server/modules/terminal/runtime/terminal-log-writer-process.d.ts +1 -0
  197. package/dist/server/modules/terminal/runtime/terminal-log-writer-process.js +187 -0
  198. package/dist/server/modules/terminal/runtime/terminal-log-writer-process.js.map +1 -0
  199. package/dist/server/modules/terminal/terminal-service.d.ts +12 -0
  200. package/dist/server/modules/terminal/terminal-service.js +34 -17
  201. package/dist/server/modules/terminal/terminal-service.js.map +1 -1
  202. package/dist/server/modules/workbench/workbench-service.d.ts +23 -2
  203. package/dist/server/modules/workbench/workbench-service.js +126 -15
  204. package/dist/server/modules/workbench/workbench-service.js.map +1 -1
  205. package/dist/server/modules/workbench/workspace-panel-snapshot-service.d.ts +5 -1
  206. package/dist/server/modules/workbench/workspace-panel-snapshot-service.js +88 -19
  207. package/dist/server/modules/workbench/workspace-panel-snapshot-service.js.map +1 -1
  208. package/dist/server/modules/workspace/workspace-code-composition.d.ts +2 -0
  209. package/dist/server/modules/workspace/workspace-code-composition.js +154 -0
  210. package/dist/server/modules/workspace/workspace-code-composition.js.map +1 -0
  211. package/dist/server/modules/workspace/workspace-controller.d.ts +14 -0
  212. package/dist/server/modules/workspace/workspace-controller.js +19 -0
  213. package/dist/server/modules/workspace/workspace-controller.js.map +1 -1
  214. package/dist/server/modules/workspace/workspace-service.d.ts +21 -14
  215. package/dist/server/modules/workspace/workspace-service.js +183 -234
  216. package/dist/server/modules/workspace/workspace-service.js.map +1 -1
  217. package/dist/server/modules/worktree/worktree-cleanup-service.d.ts +35 -0
  218. package/dist/server/modules/worktree/worktree-cleanup-service.js +210 -0
  219. package/dist/server/modules/worktree/worktree-cleanup-service.js.map +1 -0
  220. package/dist/server/modules/worktree/worktree-controller.d.ts +44 -0
  221. package/dist/server/modules/worktree/worktree-controller.js +40 -0
  222. package/dist/server/modules/worktree/worktree-controller.js.map +1 -0
  223. package/dist/server/modules/worktree/worktree-manager.d.ts +34 -0
  224. package/dist/server/modules/worktree/worktree-manager.js +292 -0
  225. package/dist/server/modules/worktree/worktree-manager.js.map +1 -0
  226. package/dist/server/modules/worktree/worktree-merge-service.d.ts +52 -0
  227. package/dist/server/modules/worktree/worktree-merge-service.js +293 -0
  228. package/dist/server/modules/worktree/worktree-merge-service.js.map +1 -0
  229. package/dist/server/modules/worktree/worktree-sync-service.d.ts +23 -0
  230. package/dist/server/modules/worktree/worktree-sync-service.js +166 -0
  231. package/dist/server/modules/worktree/worktree-sync-service.js.map +1 -0
  232. package/dist/server/routes/assistant.d.ts +3 -0
  233. package/dist/server/routes/assistant.js +15 -0
  234. package/dist/server/routes/assistant.js.map +1 -0
  235. package/dist/server/routes/debug-targets.d.ts +3 -0
  236. package/dist/server/routes/debug-targets.js +15 -0
  237. package/dist/server/routes/debug-targets.js.map +1 -0
  238. package/dist/server/routes/git.js +2 -0
  239. package/dist/server/routes/git.js.map +1 -1
  240. package/dist/server/routes/observability.d.ts +3 -0
  241. package/dist/server/routes/observability.js +7 -0
  242. package/dist/server/routes/observability.js.map +1 -0
  243. package/dist/server/routes/skills.d.ts +3 -0
  244. package/dist/server/routes/skills.js +7 -0
  245. package/dist/server/routes/skills.js.map +1 -0
  246. package/dist/server/routes/system.d.ts +3 -0
  247. package/dist/server/routes/system.js +9 -0
  248. package/dist/server/routes/system.js.map +1 -0
  249. package/dist/server/routes/workspaces.js +2 -0
  250. package/dist/server/routes/workspaces.js.map +1 -1
  251. package/dist/server/routes/worktrees.d.ts +3 -0
  252. package/dist/server/routes/worktrees.js +8 -0
  253. package/dist/server/routes/worktrees.js.map +1 -0
  254. package/dist/server/server/create-server.d.ts +46 -0
  255. package/dist/server/server/create-server.js +141 -12
  256. package/dist/server/server/create-server.js.map +1 -1
  257. package/dist/server/shared/utils/command-availability.d.ts +1 -0
  258. package/dist/server/shared/utils/command-availability.js +26 -3
  259. package/dist/server/shared/utils/command-availability.js.map +1 -1
  260. package/dist/server/shared/utils/secret-box.d.ts +2 -0
  261. package/dist/server/shared/utils/secret-box.js +29 -0
  262. package/dist/server/shared/utils/secret-box.js.map +1 -0
  263. package/dist/server/shared/utils/terminal-debug-log.js +5 -3
  264. package/dist/server/shared/utils/terminal-debug-log.js.map +1 -1
  265. package/dist/server/storage/repositories/ai-fallback-edit-repository.d.ts +11 -0
  266. package/dist/server/storage/repositories/ai-fallback-edit-repository.js +118 -0
  267. package/dist/server/storage/repositories/ai-fallback-edit-repository.js.map +1 -0
  268. package/dist/server/storage/repositories/debug-runtime-session-repository.d.ts +11 -0
  269. package/dist/server/storage/repositories/debug-runtime-session-repository.js +100 -0
  270. package/dist/server/storage/repositories/debug-runtime-session-repository.js.map +1 -0
  271. package/dist/server/storage/repositories/debug-service-repository.d.ts +9 -0
  272. package/dist/server/storage/repositories/debug-service-repository.js +99 -0
  273. package/dist/server/storage/repositories/debug-service-repository.js.map +1 -0
  274. package/dist/server/storage/repositories/debug-target-repository.d.ts +11 -0
  275. package/dist/server/storage/repositories/debug-target-repository.js +100 -0
  276. package/dist/server/storage/repositories/debug-target-repository.js.map +1 -0
  277. package/dist/server/storage/repositories/framework-analysis-result-repository.d.ts +9 -0
  278. package/dist/server/storage/repositories/framework-analysis-result-repository.js +98 -0
  279. package/dist/server/storage/repositories/framework-analysis-result-repository.js.map +1 -0
  280. package/dist/server/storage/repositories/git-remote-credential-repository.d.ts +9 -0
  281. package/dist/server/storage/repositories/git-remote-credential-repository.js +51 -0
  282. package/dist/server/storage/repositories/git-remote-credential-repository.js.map +1 -0
  283. package/dist/server/storage/repositories/instance-tailscale-repository.d.ts +10 -0
  284. package/dist/server/storage/repositories/instance-tailscale-repository.js +112 -0
  285. package/dist/server/storage/repositories/instance-tailscale-repository.js.map +1 -0
  286. package/dist/server/storage/repositories/managed-skill-repository.d.ts +11 -0
  287. package/dist/server/storage/repositories/managed-skill-repository.js +102 -0
  288. package/dist/server/storage/repositories/managed-skill-repository.js.map +1 -0
  289. package/dist/server/storage/repositories/port-lease-repository.d.ts +12 -0
  290. package/dist/server/storage/repositories/port-lease-repository.js +124 -0
  291. package/dist/server/storage/repositories/port-lease-repository.js.map +1 -0
  292. package/dist/server/storage/repositories/runtime-binding-repository.d.ts +10 -0
  293. package/dist/server/storage/repositories/runtime-binding-repository.js +89 -0
  294. package/dist/server/storage/repositories/runtime-binding-repository.js.map +1 -0
  295. package/dist/server/storage/repositories/skill-target-binding-repository.d.ts +10 -0
  296. package/dist/server/storage/repositories/skill-target-binding-repository.js +77 -0
  297. package/dist/server/storage/repositories/skill-target-binding-repository.js.map +1 -0
  298. package/dist/server/storage/repositories/terminal-command-template-repository.js +77 -4
  299. package/dist/server/storage/repositories/terminal-command-template-repository.js.map +1 -1
  300. package/dist/server/storage/repositories/terminal-instance-repository.js +89 -7
  301. package/dist/server/storage/repositories/terminal-instance-repository.js.map +1 -1
  302. package/dist/server/storage/repositories/workspace-navigation-state-repository.d.ts +9 -0
  303. package/dist/server/storage/repositories/workspace-navigation-state-repository.js +49 -0
  304. package/dist/server/storage/repositories/workspace-navigation-state-repository.js.map +1 -0
  305. package/dist/server/storage/repositories/workspace-repository.d.ts +7 -1
  306. package/dist/server/storage/repositories/workspace-repository.js +32 -8
  307. package/dist/server/storage/repositories/workspace-repository.js.map +1 -1
  308. package/dist/server/storage/repositories/workspace-worktree-repository.d.ts +13 -0
  309. package/dist/server/storage/repositories/workspace-worktree-repository.js +158 -0
  310. package/dist/server/storage/repositories/workspace-worktree-repository.js.map +1 -0
  311. package/dist/server/storage/sqlite/client.js +311 -0
  312. package/dist/server/storage/sqlite/client.js.map +1 -1
  313. package/dist/server/storage/sqlite/schema.sql +303 -0
  314. package/dist/server/types/domain.d.ts +303 -0
  315. package/dist/server/ws/workbench-ws-hub.js +33 -9
  316. package/dist/server/ws/workbench-ws-hub.js.map +1 -1
  317. package/dist/server/ws/ws-server.js +4 -4
  318. package/dist/server/ws/ws-server.js.map +1 -1
  319. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.js +18 -6
  320. package/node_modules/@codingns/session-sync-core/dist/providers/claude-code.js.map +1 -1
  321. package/node_modules/@codingns/session-sync-core/dist/providers/codex.js +14 -2
  322. package/node_modules/@codingns/session-sync-core/dist/providers/codex.js.map +1 -1
  323. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.js +25 -1
  324. package/node_modules/@codingns/session-sync-core/dist/providers/opencode.js.map +1 -1
  325. package/node_modules/@codingns/session-sync-core/dist/types.d.ts +6 -0
  326. package/package.json +1 -1
  327. package/dist/public/assets/index-1VIm8lVL.css +0 -1
  328. package/dist/public/assets/index-Dti93O2S.js +0 -109
package/bin/codingns.mjs CHANGED
@@ -14,61 +14,485 @@ if (!command || command === "help" || command === "--help" || command === "-h")
14
14
  printHelp(0);
15
15
  }
16
16
 
17
- if (command !== "start") {
18
- console.error(`[codingns] 不支持的命令:${command}`);
19
- printHelp(1);
17
+ switch (command) {
18
+ case "start":
19
+ await runStartCommand(argv);
20
+ break;
21
+ case "assistant":
22
+ await runAssistantCommand(argv);
23
+ break;
24
+ case "skills":
25
+ await runSkillsCommand(argv);
26
+ break;
27
+ default:
28
+ console.error(`[codingns] 不支持的命令:${command}`);
29
+ printHelp(1);
20
30
  }
21
31
 
22
- const options = parseArgs(argv);
32
+ async function runStartCommand(argv) {
33
+ const options = parseArgs(argv, {
34
+ supportedOptions: ["host", "port", "data-dir"],
35
+ supportedFlags: ["demo"]
36
+ });
23
37
 
24
- if (options.help) {
25
- printHelp(0);
38
+ if (options.help) {
39
+ printHelp(0);
40
+ }
41
+
42
+ if (options.errors.length > 0) {
43
+ for (const error of options.errors) {
44
+ console.error(`[codingns] ${error}`);
45
+ }
46
+ printHelp(1);
47
+ }
48
+
49
+ const host = readStringOption(
50
+ options.values.host,
51
+ process.env.HOST,
52
+ process.env.CODINGNS_HOST,
53
+ "0.0.0.0"
54
+ );
55
+ const port = parsePort(
56
+ readStringOption(options.values.port, process.env.PORT, process.env.CODINGNS_PORT, "3002")
57
+ );
58
+ const dataDir = resolveDataDir(
59
+ readStringOption(
60
+ options.values["data-dir"],
61
+ process.env.CODINGNS_DATA_DIR,
62
+ path.join(os.homedir(), ".codingns")
63
+ )
64
+ );
65
+ const demoMode = options.flags.demo || process.env.DEMO_MODE === "true";
66
+
67
+ fs.mkdirSync(dataDir, { recursive: true });
68
+ fs.mkdirSync(path.join(dataDir, "releases"), { recursive: true });
69
+
70
+ const { startHost } = await import("../dist/server/server/start-host.js");
71
+
72
+ await startHost({
73
+ host,
74
+ port,
75
+ webUiDir: path.join(distRoot, "public"),
76
+ webUiPort: port,
77
+ databasePath: path.join(dataDir, "host.sqlite"),
78
+ releaseManifestRoot: path.join(dataDir, "releases"),
79
+ serverUpdatePackageName: "@jingyi0605/codingns",
80
+ demoMode
81
+ });
82
+ }
83
+
84
+ async function runAssistantCommand(argv) {
85
+ const [group, action, ...rest] = argv;
86
+
87
+ if (!group || group === "help" || group === "--help" || group === "-h") {
88
+ const topic = buildAssistantHelpTopic(action, rest);
89
+ printAssistantHelpTopic(topic, 0);
90
+ }
91
+
92
+ if (!action || action === "help" || action === "--help" || action === "-h") {
93
+ printAssistantHelpTopic(group, 0);
94
+ }
95
+
96
+ if (rest.length > 0 && isHelpToken(rest[0])) {
97
+ printAssistantHelpTopic(`${group}.${action}`, 0);
98
+ }
99
+
100
+ switch (`${group}:${action ?? ""}`) {
101
+ case "capabilities:list":
102
+ await printAssistantResponse(await requestAssistant({
103
+ method: "GET",
104
+ path: "/api/assistant/capabilities",
105
+ argv: rest,
106
+ helpTopic: "capabilities.list"
107
+ }));
108
+ return;
109
+ case "projects:list":
110
+ await printAssistantResponse(await requestAssistant({
111
+ method: "GET",
112
+ path: "/api/assistant/projects",
113
+ argv: rest,
114
+ supportedOptions: ["workspace-id", "status", "risk-level"],
115
+ helpTopic: "projects.list"
116
+ }, (options) => ({
117
+ workspaceId: readOptionalTrimmedValue(options.values["workspace-id"]),
118
+ status: readOptionalTrimmedValue(options.values.status),
119
+ riskLevel: readOptionalTrimmedValue(options.values["risk-level"])
120
+ })));
121
+ return;
122
+ case "projects:get": {
123
+ const [projectId, ...tail] = rest;
124
+ await printAssistantResponse(await requestAssistant({
125
+ method: "GET",
126
+ path: `/api/assistant/projects/${requirePositional(projectId, "projectId")}`,
127
+ argv: tail,
128
+ helpTopic: "projects.get"
129
+ }));
130
+ return;
131
+ }
132
+ case "sessions:list": {
133
+ await printAssistantResponse(await requestAssistant({
134
+ method: "GET",
135
+ path: `/api/assistant/projects/${requireOptionPositional(rest, "--project", "projectId")}/sessions`,
136
+ argv: stripConsumedOption(rest, "--project"),
137
+ supportedOptions: [],
138
+ helpTopic: "sessions.list"
139
+ }));
140
+ return;
141
+ }
142
+ case "sessions:get": {
143
+ const [sessionId, ...tail] = rest;
144
+ await printAssistantResponse(await requestAssistant({
145
+ method: "GET",
146
+ path: `/api/assistant/sessions/${requirePositional(sessionId, "sessionId")}`,
147
+ argv: tail,
148
+ helpTopic: "sessions.get"
149
+ }));
150
+ return;
151
+ }
152
+ case "sessions:messages": {
153
+ const [sessionId, ...tail] = rest;
154
+ await printAssistantResponse(await requestAssistant({
155
+ method: "GET",
156
+ path: `/api/assistant/sessions/${requirePositional(sessionId, "sessionId")}/messages`,
157
+ argv: tail,
158
+ supportedOptions: ["cursor", "limit", "direction"],
159
+ helpTopic: "sessions.messages"
160
+ }, (options) => ({
161
+ cursor: readOptionalTrimmedValue(options.values.cursor),
162
+ limit: readOptionalTrimmedValue(options.values.limit),
163
+ direction: readOptionalTrimmedValue(options.values.direction)
164
+ })));
165
+ return;
166
+ }
167
+ case "sessions:runtime": {
168
+ const [sessionId, ...tail] = rest;
169
+ await printAssistantResponse(await requestAssistant({
170
+ method: "GET",
171
+ path: `/api/assistant/sessions/${requirePositional(sessionId, "sessionId")}/runtime`,
172
+ argv: tail,
173
+ helpTopic: "sessions.runtime"
174
+ }));
175
+ return;
176
+ }
177
+ case "sessions:send": {
178
+ const [sessionId, ...tail] = rest;
179
+ await printAssistantResponse(await requestAssistant({
180
+ method: "POST",
181
+ path: `/api/assistant/sessions/${requirePositional(sessionId, "sessionId")}/messages`,
182
+ argv: tail,
183
+ supportedOptions: ["message", "client-request-id", "model", "reasoning-level", "permission-mode"],
184
+ helpTopic: "sessions.send"
185
+ }, (options) => ({
186
+ content: requireOptionValue(options.values.message, "message"),
187
+ clientRequestId: readOptionalTrimmedValue(options.values["client-request-id"]),
188
+ model: readOptionalTrimmedValue(options.values.model),
189
+ reasoningLevel: readOptionalTrimmedValue(options.values["reasoning-level"]),
190
+ permissionMode: readOptionalTrimmedValue(options.values["permission-mode"])
191
+ })));
192
+ return;
193
+ }
194
+ case "sessions:fork": {
195
+ const [sessionId, ...tail] = rest;
196
+ await printAssistantResponse(await requestAssistant({
197
+ method: "POST",
198
+ path: `/api/assistant/sessions/${requirePositional(sessionId, "sessionId")}/forks`,
199
+ argv: tail,
200
+ supportedOptions: ["source-type", "message-id", "strategy", "target-provider"],
201
+ helpTopic: "sessions.fork"
202
+ }, (options) => ({
203
+ sourceType: readOptionalTrimmedValue(options.values["source-type"]),
204
+ sourceMessageId: readOptionalTrimmedValue(options.values["message-id"]),
205
+ strategy: readOptionalTrimmedValue(options.values.strategy),
206
+ targetProvider: readOptionalTrimmedValue(options.values["target-provider"])
207
+ })));
208
+ return;
209
+ }
210
+ case "terminals:list":
211
+ await printAssistantResponse(await requestAssistant({
212
+ method: "GET",
213
+ path: "/api/assistant/terminals",
214
+ argv: rest,
215
+ supportedOptions: ["workspace-id", "project-id"],
216
+ helpTopic: "terminals.list"
217
+ }, (options) => ({
218
+ workspaceId: readOptionalTrimmedValue(options.values["workspace-id"]),
219
+ projectId: readOptionalTrimmedValue(options.values["project-id"])
220
+ })));
221
+ return;
222
+ case "terminals:history": {
223
+ const [terminalId, ...tail] = rest;
224
+ await printAssistantResponse(await requestAssistant({
225
+ method: "GET",
226
+ path: `/api/assistant/terminals/${requirePositional(terminalId, "terminalId")}/history`,
227
+ argv: tail,
228
+ supportedOptions: ["before-seq", "limit"],
229
+ helpTopic: "terminals.history"
230
+ }, (options) => ({
231
+ beforeSeq: readOptionalTrimmedValue(options.values["before-seq"]),
232
+ limit: readOptionalTrimmedValue(options.values.limit)
233
+ })));
234
+ return;
235
+ }
236
+ case "terminals:send": {
237
+ const [terminalId, ...tail] = rest;
238
+ await printAssistantResponse(await requestAssistant({
239
+ method: "POST",
240
+ path: `/api/assistant/terminals/${requirePositional(terminalId, "terminalId")}/input`,
241
+ argv: tail,
242
+ supportedOptions: ["input"],
243
+ helpTopic: "terminals.send"
244
+ }, (options) => ({
245
+ content: requireOptionValue(options.values.input, "input")
246
+ })));
247
+ return;
248
+ }
249
+ default:
250
+ console.error(`[codingns] 不支持的 assistant 子命令:${group}${action ? ` ${action}` : ""}`);
251
+ printAssistantHelpTopic("assistant", 1);
252
+ }
253
+ }
254
+
255
+ async function runSkillsCommand(argv) {
256
+ const [action, ...rest] = argv;
257
+
258
+ if (!action || action === "help" || action === "--help" || action === "-h") {
259
+ printSkillsHelpTopic(buildSkillsHelpTopic(rest[0]), 0);
260
+ }
261
+
262
+ if (rest.length > 0 && isHelpToken(rest[0])) {
263
+ printSkillsHelpTopic(buildSkillsHelpTopic(action), 0);
264
+ }
265
+
266
+ switch (action) {
267
+ case "overview":
268
+ await printAssistantResponse(await requestSkills({
269
+ method: "GET",
270
+ path: "/api/skills/overview",
271
+ argv: rest,
272
+ supportedOptions: ["target"],
273
+ repeatableOptions: ["target"],
274
+ helpTopic: "skills.overview"
275
+ }, (options) => {
276
+ const targets = readMultiOptionValues(options.values.target);
277
+
278
+ return targets.length > 0
279
+ ? { targetCli: targets.join(",") }
280
+ : null;
281
+ }));
282
+ return;
283
+ case "add":
284
+ await printAssistantResponse(await requestSkills({
285
+ method: "POST",
286
+ path: "/api/skills",
287
+ argv: rest,
288
+ supportedOptions: ["source", "target", "source-type"],
289
+ repeatableOptions: ["target"],
290
+ helpTopic: "skills.add"
291
+ }, (options) => ({
292
+ sourcePath: requireOptionValue(options.values.source, "source"),
293
+ targetCli: requireMultiOptionValues(options.values.target, "target"),
294
+ sourceType: readOptionalTrimmedValue(options.values["source-type"]) ?? "local-import"
295
+ })));
296
+ return;
297
+ case "import":
298
+ await printAssistantResponse(await requestSkills({
299
+ method: "POST",
300
+ path: "/api/skills/import",
301
+ argv: rest,
302
+ supportedOptions: ["cli", "path", "expected-hash", "target"],
303
+ repeatableOptions: ["target"],
304
+ helpTopic: "skills.import"
305
+ }, (options) => ({
306
+ targetCli: requireOptionValue(options.values.cli, "cli"),
307
+ directoryPath: requireOptionValue(options.values.path, "path"),
308
+ expectedContentHash: readOptionalTrimmedValue(options.values["expected-hash"]),
309
+ additionalTargetCli: readMultiOptionValues(options.values.target)
310
+ })));
311
+ return;
312
+ case "sync": {
313
+ const [skillId, ...tail] = rest;
314
+ await printAssistantResponse(await requestSkills({
315
+ method: "POST",
316
+ path: "/api/skills/sync",
317
+ argv: tail,
318
+ supportedOptions: ["target"],
319
+ repeatableOptions: ["target"],
320
+ helpTopic: "skills.sync"
321
+ }, (options) => ({
322
+ skillId: requirePositional(skillId, "skillId"),
323
+ targetCli: requireMultiOptionValues(options.values.target, "target")
324
+ })));
325
+ return;
326
+ }
327
+ default:
328
+ console.error(`[codingns] 不支持的 skills 子命令:${action}`);
329
+ printSkillsHelpTopic("skills", 1);
330
+ }
331
+ }
332
+
333
+ async function requestAssistant(command, buildPayload) {
334
+ const options = parseArgs(command.argv, {
335
+ supportedOptions: [
336
+ "base-url",
337
+ "token",
338
+ ...(command.supportedOptions ?? [])
339
+ ]
340
+ });
341
+
342
+ if (options.help) {
343
+ printAssistantHelpTopic(command.helpTopic ?? "assistant", 0);
344
+ }
345
+
346
+ if (options.errors.length > 0) {
347
+ for (const error of options.errors) {
348
+ console.error(`[codingns] ${error}`);
349
+ }
350
+ printAssistantHelpTopic(command.helpTopic ?? "assistant", 1);
351
+ }
352
+
353
+ const baseUrl = resolveAssistantBaseUrl(options.values["base-url"]);
354
+ const accessToken = resolveAssistantAccessToken(options.values.token);
355
+ const url = new URL(command.path, appendTrailingSlash(baseUrl));
356
+ const payload = buildPayload ? buildPayload(options) : null;
357
+
358
+ if (command.method === "GET" && payload) {
359
+ for (const [key, value] of Object.entries(payload)) {
360
+ if (typeof value === "string" && value.length > 0) {
361
+ url.searchParams.set(key, value);
362
+ }
363
+ }
364
+ }
365
+
366
+ let response;
367
+
368
+ try {
369
+ response = await fetch(url, {
370
+ method: command.method,
371
+ headers: {
372
+ Authorization: `Bearer ${accessToken}`,
373
+ ...(command.method === "POST" ? { "Content-Type": "application/json" } : {})
374
+ },
375
+ body: command.method === "POST" ? JSON.stringify(payload ?? {}) : undefined
376
+ });
377
+ } catch (error) {
378
+ const message = error instanceof Error ? error.message : "未知网络错误";
379
+ console.error(JSON.stringify({
380
+ ok: false,
381
+ detail: `助手能力请求失败:${message}`,
382
+ target: url.toString()
383
+ }, null, 2));
384
+ process.exit(1);
385
+ }
386
+
387
+ const rawBody = await response.text();
388
+ const responseBody = tryParseJson(rawBody);
389
+
390
+ if (!response.ok) {
391
+ const detail = typeof responseBody?.detail === "string"
392
+ ? responseBody.detail
393
+ : `HTTP ${response.status}`;
394
+ console.error(JSON.stringify({
395
+ ok: false,
396
+ status: response.status,
397
+ detail,
398
+ body: responseBody ?? rawBody
399
+ }, null, 2));
400
+ process.exit(1);
401
+ }
402
+
403
+ return responseBody ?? rawBody;
404
+ }
405
+
406
+ async function requestSkills(command, buildPayload) {
407
+ const options = parseArgs(command.argv, {
408
+ supportedOptions: [
409
+ "base-url",
410
+ "token",
411
+ ...(command.supportedOptions ?? [])
412
+ ],
413
+ repeatableOptions: command.repeatableOptions ?? []
414
+ });
415
+
416
+ if (options.help) {
417
+ printSkillsHelpTopic(command.helpTopic ?? "skills", 0);
418
+ }
419
+
420
+ if (options.errors.length > 0) {
421
+ for (const error of options.errors) {
422
+ console.error(`[codingns] ${error}`);
423
+ }
424
+ printSkillsHelpTopic(command.helpTopic ?? "skills", 1);
425
+ }
426
+
427
+ const baseUrl = resolveAssistantBaseUrl(options.values["base-url"]);
428
+ const accessToken = resolveAssistantAccessToken(options.values.token);
429
+ const url = new URL(command.path, appendTrailingSlash(baseUrl));
430
+ const payload = buildPayload ? buildPayload(options) : null;
431
+
432
+ if (command.method === "GET" && payload) {
433
+ for (const [key, value] of Object.entries(payload)) {
434
+ if (typeof value === "string" && value.length > 0) {
435
+ url.searchParams.set(key, value);
436
+ }
437
+ }
438
+ }
439
+
440
+ let response;
441
+
442
+ try {
443
+ response = await fetch(url, {
444
+ method: command.method,
445
+ headers: {
446
+ Authorization: `Bearer ${accessToken}`,
447
+ ...(command.method === "POST" ? { "Content-Type": "application/json" } : {})
448
+ },
449
+ body: command.method === "POST" ? JSON.stringify(payload ?? {}) : undefined
450
+ });
451
+ } catch (error) {
452
+ const message = error instanceof Error ? error.message : "未知网络错误";
453
+ console.error(JSON.stringify({
454
+ ok: false,
455
+ detail: `Skill 管理请求失败:${message}`,
456
+ target: url.toString()
457
+ }, null, 2));
458
+ process.exit(1);
459
+ }
460
+
461
+ const rawBody = await response.text();
462
+ const responseBody = tryParseJson(rawBody);
463
+
464
+ if (!response.ok) {
465
+ const detail = typeof responseBody?.detail === "string"
466
+ ? responseBody.detail
467
+ : `HTTP ${response.status}`;
468
+ console.error(JSON.stringify({
469
+ ok: false,
470
+ status: response.status,
471
+ detail,
472
+ body: responseBody ?? rawBody
473
+ }, null, 2));
474
+ process.exit(1);
475
+ }
476
+
477
+ return responseBody ?? rawBody;
26
478
  }
27
479
 
28
- if (options.errors.length > 0) {
29
- for (const error of options.errors) {
30
- console.error(`[codingns] ${error}`);
31
- }
32
- printHelp(1);
33
- }
34
-
35
- const host = readStringOption(
36
- options.values.host,
37
- process.env.HOST,
38
- process.env.CODINGNS_HOST,
39
- "0.0.0.0"
40
- );
41
- const port = parsePort(
42
- readStringOption(options.values.port, process.env.PORT, process.env.CODINGNS_PORT, "3002")
43
- );
44
- const dataDir = resolveDataDir(
45
- readStringOption(
46
- options.values["data-dir"],
47
- process.env.CODINGNS_DATA_DIR,
48
- path.join(os.homedir(), ".codingns")
49
- )
50
- );
51
- const demoMode = options.flags.demo || process.env.DEMO_MODE === "true";
52
-
53
- fs.mkdirSync(dataDir, { recursive: true });
54
- fs.mkdirSync(path.join(dataDir, "releases"), { recursive: true });
55
-
56
- const { startHost } = await import("../dist/server/server/start-host.js");
57
-
58
- await startHost({
59
- host,
60
- port,
61
- webUiDir: path.join(distRoot, "public"),
62
- databasePath: path.join(dataDir, "host.sqlite"),
63
- releaseManifestRoot: path.join(dataDir, "releases"),
64
- serverUpdatePackageName: "@jingyi0605/codingns",
65
- demoMode
66
- });
67
-
68
- function parseArgs(argv) {
480
+ async function printAssistantResponse(payload) {
481
+ if (typeof payload === "string") {
482
+ console.log(payload);
483
+ return;
484
+ }
485
+
486
+ console.log(JSON.stringify(payload, null, 2));
487
+ }
488
+
489
+ function parseArgs(argv, input = {}) {
69
490
  const values = {};
70
491
  const flags = {};
71
492
  const errors = [];
493
+ const supportedOptions = new Set(input.supportedOptions ?? []);
494
+ const supportedFlags = new Set(input.supportedFlags ?? []);
495
+ const repeatableOptions = new Set(input.repeatableOptions ?? []);
72
496
  let index = 0;
73
497
 
74
498
  while (index < argv.length) {
@@ -98,20 +522,25 @@ function parseArgs(argv) {
98
522
  }
99
523
 
100
524
  // 布尔标志(不需要值)
101
- if (isSupportedFlag(rawName)) {
525
+ if (supportedFlags.has(rawName)) {
102
526
  flags[rawName] = true;
103
527
  index += 1;
104
528
  continue;
105
529
  }
106
530
 
107
- if (!isSupportedOption(rawName)) {
531
+ if (!supportedOptions.has(rawName)) {
108
532
  errors.push(`不支持的参数:${token}`);
109
533
  index += 1;
110
534
  continue;
111
535
  }
112
536
 
113
537
  if (inlineValue !== undefined) {
114
- values[rawName] = inlineValue;
538
+ if (repeatableOptions.has(rawName)) {
539
+ const current = values[rawName];
540
+ values[rawName] = Array.isArray(current) ? [...current, inlineValue] : current ? [current, inlineValue] : [inlineValue];
541
+ } else {
542
+ values[rawName] = inlineValue;
543
+ }
115
544
  index += 1;
116
545
  continue;
117
546
  }
@@ -124,7 +553,12 @@ function parseArgs(argv) {
124
553
  continue;
125
554
  }
126
555
 
127
- values[rawName] = nextValue;
556
+ if (repeatableOptions.has(rawName)) {
557
+ const current = values[rawName];
558
+ values[rawName] = Array.isArray(current) ? [...current, nextValue] : current ? [current, nextValue] : [nextValue];
559
+ } else {
560
+ values[rawName] = nextValue;
561
+ }
128
562
  index += 2;
129
563
  }
130
564
 
@@ -136,12 +570,33 @@ function parseArgs(argv) {
136
570
  };
137
571
  }
138
572
 
139
- function isSupportedOption(name) {
140
- return name === "host" || name === "port" || name === "data-dir";
573
+ function resolveAssistantBaseUrl(input) {
574
+ const baseUrl = readStringOption(
575
+ input,
576
+ process.env.CODINGNS_BASE_URL,
577
+ process.env.CODINGNS_SERVER_BASE_URL,
578
+ "http://127.0.0.1:3002"
579
+ );
580
+
581
+ try {
582
+ return new URL(baseUrl).toString();
583
+ } catch {
584
+ fail(`助手调用 baseUrl 非法:${baseUrl}`);
585
+ }
141
586
  }
142
587
 
143
- function isSupportedFlag(name) {
144
- return name === "demo";
588
+ function resolveAssistantAccessToken(input) {
589
+ const accessToken = readStringOption(
590
+ input,
591
+ process.env.CODINGNS_ACCESS_TOKEN,
592
+ process.env.CODINGNS_TOKEN
593
+ );
594
+
595
+ if (!accessToken) {
596
+ fail("缺少助手调用 access token,请传 --token 或设置 CODINGNS_ACCESS_TOKEN");
597
+ }
598
+
599
+ return accessToken;
145
600
  }
146
601
 
147
602
  function readStringOption(...values) {
@@ -154,6 +609,102 @@ function readStringOption(...values) {
154
609
  return "";
155
610
  }
156
611
 
612
+ function readOptionalTrimmedValue(value) {
613
+ const normalized = typeof value === "string" ? value.trim() : "";
614
+ return normalized.length > 0 ? normalized : null;
615
+ }
616
+
617
+ function readMultiOptionValues(value) {
618
+ const values = Array.isArray(value)
619
+ ? value
620
+ : typeof value === "string"
621
+ ? [value]
622
+ : [];
623
+
624
+ return values
625
+ .flatMap((item) => item.split(","))
626
+ .map((item) => item.trim())
627
+ .filter((item) => item.length > 0);
628
+ }
629
+
630
+ function requireOptionValue(value, field) {
631
+ const normalized = readOptionalTrimmedValue(value);
632
+
633
+ if (!normalized) {
634
+ fail(`参数 --${field} 不能为空`);
635
+ }
636
+
637
+ return normalized;
638
+ }
639
+
640
+ function requireMultiOptionValues(value, field) {
641
+ const normalized = readMultiOptionValues(value);
642
+
643
+ if (normalized.length === 0) {
644
+ fail(`参数 --${field} 不能为空`);
645
+ }
646
+
647
+ return normalized;
648
+ }
649
+
650
+ function requirePositional(value, field) {
651
+ const normalized = typeof value === "string" ? value.trim() : "";
652
+
653
+ if (!normalized) {
654
+ fail(`缺少位置参数:${field}`);
655
+ }
656
+
657
+ return normalized;
658
+ }
659
+
660
+ function requireOptionPositional(argv, optionName, field) {
661
+ const index = argv.findIndex((token) => token === optionName || token.startsWith(`${optionName}=`));
662
+
663
+ if (index < 0) {
664
+ fail(`缺少必要参数:${optionName}`);
665
+ }
666
+
667
+ const token = argv[index];
668
+
669
+ if (token.includes("=")) {
670
+ return requirePositional(token.split("=", 2)[1], field);
671
+ }
672
+
673
+ return requirePositional(argv[index + 1], field);
674
+ }
675
+
676
+ function stripConsumedOption(argv, optionName) {
677
+ const index = argv.findIndex((token) => token === optionName || token.startsWith(`${optionName}=`));
678
+
679
+ if (index < 0) {
680
+ return argv;
681
+ }
682
+
683
+ const token = argv[index];
684
+
685
+ if (token.includes("=")) {
686
+ return argv.filter((_, currentIndex) => currentIndex !== index);
687
+ }
688
+
689
+ return argv.filter((_, currentIndex) => currentIndex !== index && currentIndex !== index + 1);
690
+ }
691
+
692
+ function appendTrailingSlash(value) {
693
+ return value.endsWith("/") ? value : `${value}/`;
694
+ }
695
+
696
+ function tryParseJson(input) {
697
+ if (!input) {
698
+ return null;
699
+ }
700
+
701
+ try {
702
+ return JSON.parse(input);
703
+ } catch {
704
+ return null;
705
+ }
706
+ }
707
+
157
708
  function parsePort(input) {
158
709
  const port = Number.parseInt(input, 10);
159
710
 
@@ -187,6 +738,8 @@ function printHelp(exitCode) {
187
738
  codingns 用法:
188
739
 
189
740
  codingns start [--host 0.0.0.0] [--port 3002] [--data-dir ~/.codingns] [--demo]
741
+ codingns assistant <group> <action> [options]
742
+ codingns skills <action> [options]
190
743
 
191
744
  说明:
192
745
 
@@ -195,6 +748,19 @@ codingns 用法:
195
748
  --data-dir 数据目录,默认 ~/.codingns
196
749
  --demo 以演示模式启动(自动创建 demo 账户、15 分钟会话超时、开放 CORS)
197
750
  --help 显示帮助
751
+
752
+ assistant 例子:
753
+
754
+ codingns assistant capabilities list --token <token>
755
+ codingns assistant projects list --status active --token <token>
756
+ codingns assistant sessions send <sessionId> --message "继续修复类型错误" --token <token>
757
+ codingns assistant terminals send <terminalId> --input "npm test\\n" --token <token>
758
+
759
+ skills 例子:
760
+
761
+ codingns skills overview --token <token>
762
+ codingns skills add --source ./my-skill --target codex --token <token>
763
+ codingns skills sync <skillId> --target gemini --token <token>
198
764
  `.trim();
199
765
 
200
766
  if (exitCode === 0) {
@@ -206,6 +772,303 @@ codingns 用法:
206
772
  process.exit(exitCode);
207
773
  }
208
774
 
775
+ function printAssistantHelpTopic(topic, exitCode) {
776
+ const output = getAssistantHelpText(topic);
777
+
778
+ if (exitCode === 0) {
779
+ console.log(output);
780
+ } else {
781
+ console.error(output);
782
+ }
783
+
784
+ process.exit(exitCode);
785
+ }
786
+
787
+ function printSkillsHelpTopic(topic, exitCode) {
788
+ const output = getSkillsHelpText(topic);
789
+
790
+ if (exitCode === 0) {
791
+ console.log(output);
792
+ } else {
793
+ console.error(output);
794
+ }
795
+
796
+ process.exit(exitCode);
797
+ }
798
+
799
+ function getAssistantHelpText(topic) {
800
+ switch (topic) {
801
+ case "capabilities":
802
+ case "capabilities.list":
803
+ return `
804
+ codingns assistant capabilities
805
+
806
+ 用途:
807
+ 查看当前 Host 开放了哪些助手能力,以及版本和限制。
808
+
809
+ 用法:
810
+ codingns assistant capabilities list [--base-url http://127.0.0.1:3002] --token <token>
811
+ `.trim();
812
+ case "projects":
813
+ return `
814
+ codingns assistant projects
815
+
816
+ 可用动作:
817
+ list 列出托管项目
818
+ get 读取单个项目详情
819
+
820
+ 示例:
821
+ codingns assistant projects list --status active --token <token>
822
+ codingns assistant projects get <projectId> --token <token>
823
+ `.trim();
824
+ case "projects.list":
825
+ return `
826
+ codingns assistant projects list
827
+
828
+ 用途:
829
+ 按工作区、生命周期、风险等级筛选托管项目。
830
+
831
+ 用法:
832
+ codingns assistant projects list [--workspace-id <id>] [--status active|paused|archived] [--risk-level low|medium|high] --token <token>
833
+ `.trim();
834
+ case "projects.get":
835
+ return `
836
+ codingns assistant projects get
837
+
838
+ 用途:
839
+ 读取项目详情、概况,以及该项目下可操作会话。
840
+
841
+ 用法:
842
+ codingns assistant projects get <projectId> --token <token>
843
+ `.trim();
844
+ case "sessions":
845
+ return `
846
+ codingns assistant sessions
847
+
848
+ 可用动作:
849
+ list 列出指定项目下的会话
850
+ get 读取会话详情
851
+ messages 读取消息窗口
852
+ runtime 读取运行态
853
+ send 向真实项目会话发送消息
854
+ fork 从会话或消息点 fork 新会话
855
+
856
+ 示例:
857
+ codingns assistant sessions list --project <projectId> --token <token>
858
+ codingns assistant sessions send <sessionId> --message "继续修复" --token <token>
859
+ `.trim();
860
+ case "sessions.list":
861
+ return `
862
+ codingns assistant sessions list
863
+
864
+ 用途:
865
+ 列出指定项目下当前可操作的真实会话。
866
+
867
+ 用法:
868
+ codingns assistant sessions list --project <projectId> --token <token>
869
+ `.trim();
870
+ case "sessions.get":
871
+ return `
872
+ codingns assistant sessions get
873
+
874
+ 用途:
875
+ 读取会话详情,包括当前状态和可继续操作的引用。
876
+
877
+ 用法:
878
+ codingns assistant sessions get <sessionId> --token <token>
879
+ `.trim();
880
+ case "sessions.messages":
881
+ return `
882
+ codingns assistant sessions messages
883
+
884
+ 用途:
885
+ 分页读取某个会话的消息窗口。
886
+
887
+ 用法:
888
+ codingns assistant sessions messages <sessionId> [--cursor <cursor>] [--limit 40] [--direction forward|backward] --token <token>
889
+ `.trim();
890
+ case "sessions.runtime":
891
+ return `
892
+ codingns assistant sessions runtime
893
+
894
+ 用途:
895
+ 读取会话当前运行态,用来判断能否继续发送或是否还在执行。
896
+
897
+ 用法:
898
+ codingns assistant sessions runtime <sessionId> --token <token>
899
+ `.trim();
900
+ case "sessions.send":
901
+ return `
902
+ codingns assistant sessions send
903
+
904
+ 用途:
905
+ 向真实项目会话发送消息,推进开发,但不直接改本地代码。
906
+
907
+ 用法:
908
+ codingns assistant sessions send <sessionId> --message "..." [--client-request-id <id>] [--model <model>] [--reasoning-level <level>] [--permission-mode <mode>] --token <token>
909
+ `.trim();
910
+ case "sessions.fork":
911
+ return `
912
+ codingns assistant sessions fork
913
+
914
+ 用途:
915
+ 从现有会话或消息点 fork 一个新分支会话。
916
+
917
+ 用法:
918
+ codingns assistant sessions fork <sessionId> [--source-type session|message] [--message-id <id>] [--strategy auto|native-only|reconstruct-only] [--target-provider <provider>] --token <token>
919
+ `.trim();
920
+ case "terminals":
921
+ return `
922
+ codingns assistant terminals
923
+
924
+ 可用动作:
925
+ list 列出项目或工作区下的终端
926
+ history 读取终端历史输出
927
+ send 向受控终端发送输入
928
+
929
+ 示例:
930
+ codingns assistant terminals list --project-id <projectId> --token <token>
931
+ codingns assistant terminals send <terminalId> --input "npm test\\n" --token <token>
932
+ `.trim();
933
+ case "terminals.list":
934
+ return `
935
+ codingns assistant terminals list
936
+
937
+ 用途:
938
+ 列出指定项目或工作区下的受控终端。
939
+
940
+ 用法:
941
+ codingns assistant terminals list [--workspace-id <id> | --project-id <id>] --token <token>
942
+ `.trim();
943
+ case "terminals.history":
944
+ return `
945
+ codingns assistant terminals history
946
+
947
+ 用途:
948
+ 分页读取终端历史输出。
949
+
950
+ 用法:
951
+ codingns assistant terminals history <terminalId> [--before-seq <n>] [--limit 20] --token <token>
952
+ `.trim();
953
+ case "terminals.send":
954
+ return `
955
+ codingns assistant terminals send
956
+
957
+ 用途:
958
+ 向受控终端发送输入,比如测试命令或构建命令。
959
+
960
+ 用法:
961
+ codingns assistant terminals send <terminalId> --input "npm test\\n" --token <token>
962
+ `.trim();
963
+ default:
964
+ return `
965
+ codingns assistant 用法:
966
+
967
+ codingns assistant help [capabilities|projects|sessions|terminals] [action]
968
+ codingns assistant capabilities list [--base-url http://127.0.0.1:3002] --token <token>
969
+ codingns assistant projects list [--workspace-id <id>] [--status active|paused|archived] [--risk-level low|medium|high] --token <token>
970
+ codingns assistant projects get <projectId> [--base-url ...] --token <token>
971
+ codingns assistant sessions list --project <projectId> [--base-url ...] --token <token>
972
+ codingns assistant sessions get <sessionId> [--base-url ...] --token <token>
973
+ codingns assistant sessions messages <sessionId> [--cursor <cursor>] [--limit 40] [--direction forward|backward] --token <token>
974
+ codingns assistant sessions runtime <sessionId> [--base-url ...] --token <token>
975
+ codingns assistant sessions send <sessionId> --message "..." [--client-request-id <id>] [--model <model>] [--reasoning-level <level>] [--permission-mode <mode>] --token <token>
976
+ codingns assistant sessions fork <sessionId> [--source-type session|message] [--message-id <id>] [--strategy auto|native-only|reconstruct-only] [--target-provider <provider>] --token <token>
977
+ codingns assistant terminals list [--workspace-id <id> | --project-id <id>] --token <token>
978
+ codingns assistant terminals history <terminalId> [--before-seq <n>] [--limit 20] --token <token>
979
+ codingns assistant terminals send <terminalId> --input "npm test\\n" --token <token>
980
+
981
+ 环境变量:
982
+
983
+ CODINGNS_BASE_URL 默认 Host 地址,未传时默认 http://127.0.0.1:3002
984
+ CODINGNS_ACCESS_TOKEN 默认 Bearer token
985
+ `.trim();
986
+ }
987
+ }
988
+
989
+ function getSkillsHelpText(topic) {
990
+ switch (topic) {
991
+ case "skills.overview":
992
+ return `
993
+ codingns skills overview
994
+
995
+ 用途:
996
+ 查看当前 Host 聚合后的 skill 概况,包括受管、未纳管、冲突和诊断结果。
997
+
998
+ 用法:
999
+ codingns skills overview [--target codex] [--target gemini] --token <token>
1000
+ `.trim();
1001
+ case "skills.add":
1002
+ return `
1003
+ codingns skills add
1004
+
1005
+ 用途:
1006
+ 把本地 skill 目录纳入统一管理,并只同步到你指定的目标 CLI。
1007
+
1008
+ 用法:
1009
+ codingns skills add --source <path> --target <cli> [--target <cli>] [--source-type local-import|builtin|managed-copy] --token <token>
1010
+ `.trim();
1011
+ case "skills.import":
1012
+ return `
1013
+ codingns skills import
1014
+
1015
+ 用途:
1016
+ 把某个 CLI 目录里已存在但未纳管的 skill 导入 SSOT,并可顺带同步到其他目标。
1017
+
1018
+ 用法:
1019
+ codingns skills import --cli <cli> --path <directoryPath> [--expected-hash <hash>] [--target <cli>] --token <token>
1020
+ `.trim();
1021
+ case "skills.sync":
1022
+ return `
1023
+ codingns skills sync
1024
+
1025
+ 用途:
1026
+ 把指定受管 skill 再同步到一个或多个目标 CLI。
1027
+
1028
+ 用法:
1029
+ codingns skills sync <skillId> --target <cli> [--target <cli>] --token <token>
1030
+ `.trim();
1031
+ default:
1032
+ return `
1033
+ codingns skills 用法:
1034
+
1035
+ codingns skills overview [--target <cli>] --token <token>
1036
+ codingns skills add --source <path> --target <cli> [--target <cli>] [--source-type local-import|builtin|managed-copy] --token <token>
1037
+ codingns skills import --cli <cli> --path <directoryPath> [--expected-hash <hash>] [--target <cli>] --token <token>
1038
+ codingns skills sync <skillId> --target <cli> [--target <cli>] --token <token>
1039
+
1040
+ 环境变量:
1041
+
1042
+ CODINGNS_BASE_URL 默认 Host 地址,未传时默认 http://127.0.0.1:3002
1043
+ CODINGNS_ACCESS_TOKEN 默认 Bearer token
1044
+ `.trim();
1045
+ }
1046
+ }
1047
+
1048
+ function buildAssistantHelpTopic(action, rest) {
1049
+ if (!action || action === "--help" || action === "-h") {
1050
+ return "assistant";
1051
+ }
1052
+
1053
+ if (rest.length === 0) {
1054
+ return action;
1055
+ }
1056
+
1057
+ return `${action}.${rest[0]}`;
1058
+ }
1059
+
1060
+ function buildSkillsHelpTopic(action) {
1061
+ if (!action || action === "--help" || action === "-h") {
1062
+ return "skills";
1063
+ }
1064
+
1065
+ return `skills.${action}`;
1066
+ }
1067
+
1068
+ function isHelpToken(value) {
1069
+ return value === "help" || value === "--help" || value === "-h";
1070
+ }
1071
+
209
1072
  function fail(message) {
210
1073
  console.error(`[codingns] ${message}`);
211
1074
  process.exit(1);