@di-code/coding-agent 0.1.6 → 0.1.8

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 (338) hide show
  1. package/README.md +112 -68
  2. package/compositions/base.yml +54 -0
  3. package/compositions/interactive.yml +14 -0
  4. package/compositions/json.yml +6 -0
  5. package/compositions/print.yml +5 -0
  6. package/compositions/rpc.yml +12 -0
  7. package/compositions/webui.yml +9 -0
  8. package/dist/cli.d.ts +22 -1
  9. package/dist/cli.d.ts.map +1 -1
  10. package/dist/cli.js +97 -3
  11. package/dist/cli.js.map +1 -1
  12. package/dist/composition-loader-entry.d.ts +11 -0
  13. package/dist/composition-loader-entry.d.ts.map +1 -0
  14. package/dist/composition-loader-entry.js +12 -0
  15. package/dist/composition-loader-entry.js.map +1 -0
  16. package/dist/compositions.d.ts +32 -0
  17. package/dist/compositions.d.ts.map +1 -0
  18. package/dist/compositions.js +173 -0
  19. package/dist/compositions.js.map +1 -0
  20. package/dist/core/session/session-manager.d.ts +9 -2
  21. package/dist/core/session/session-manager.d.ts.map +1 -1
  22. package/dist/core/session/session-manager.js +28 -0
  23. package/dist/core/session/session-manager.js.map +1 -1
  24. package/dist/core/session/session-storage.d.ts.map +1 -1
  25. package/dist/core/session/session-storage.js +20 -3
  26. package/dist/core/session/session-storage.js.map +1 -1
  27. package/dist/core/session/types.d.ts +11 -2
  28. package/dist/core/session/types.d.ts.map +1 -1
  29. package/dist/core/session/types.js.map +1 -1
  30. package/dist/core/session-tools.d.ts +5 -0
  31. package/dist/core/session-tools.d.ts.map +1 -0
  32. package/dist/core/session-tools.js +17 -0
  33. package/dist/core/session-tools.js.map +1 -0
  34. package/dist/core/session.d.ts +21 -7
  35. package/dist/core/session.d.ts.map +1 -1
  36. package/dist/core/session.js +77 -41
  37. package/dist/core/session.js.map +1 -1
  38. package/dist/core/tools/bash.d.ts +1 -38
  39. package/dist/core/tools/bash.d.ts.map +1 -1
  40. package/dist/core/tools/bash.js +1 -207
  41. package/dist/core/tools/bash.js.map +1 -1
  42. package/dist/core/tools/edit-diff.d.ts +1 -24
  43. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  44. package/dist/core/tools/edit-diff.js +1 -135
  45. package/dist/core/tools/edit-diff.js.map +1 -1
  46. package/dist/core/tools/edit.d.ts +1 -26
  47. package/dist/core/tools/edit.d.ts.map +1 -1
  48. package/dist/core/tools/edit.js +1 -140
  49. package/dist/core/tools/edit.js.map +1 -1
  50. package/dist/core/tools/file-mutation-queue.d.ts +1 -1
  51. package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
  52. package/dist/core/tools/file-mutation-queue.js +1 -23
  53. package/dist/core/tools/file-mutation-queue.js.map +1 -1
  54. package/dist/core/tools/file-search.d.ts +1 -13
  55. package/dist/core/tools/file-search.d.ts.map +1 -1
  56. package/dist/core/tools/file-search.js +1 -98
  57. package/dist/core/tools/file-search.js.map +1 -1
  58. package/dist/core/tools/glob.d.ts +1 -10
  59. package/dist/core/tools/glob.d.ts.map +1 -1
  60. package/dist/core/tools/glob.js +1 -43
  61. package/dist/core/tools/glob.js.map +1 -1
  62. package/dist/core/tools/grep.d.ts +1 -12
  63. package/dist/core/tools/grep.d.ts.map +1 -1
  64. package/dist/core/tools/grep.js +1 -66
  65. package/dist/core/tools/grep.js.map +1 -1
  66. package/dist/core/tools/load-skill.d.ts +1 -9
  67. package/dist/core/tools/load-skill.d.ts.map +1 -1
  68. package/dist/core/tools/load-skill.js +1 -21
  69. package/dist/core/tools/load-skill.js.map +1 -1
  70. package/dist/core/tools/path-boundary.d.ts +1 -4
  71. package/dist/core/tools/path-boundary.d.ts.map +1 -1
  72. package/dist/core/tools/path-boundary.js +1 -65
  73. package/dist/core/tools/path-boundary.js.map +1 -1
  74. package/dist/core/tools/read.d.ts +1 -16
  75. package/dist/core/tools/read.d.ts.map +1 -1
  76. package/dist/core/tools/read.js +1 -131
  77. package/dist/core/tools/read.js.map +1 -1
  78. package/dist/core/tools/write.d.ts +1 -16
  79. package/dist/core/tools/write.d.ts.map +1 -1
  80. package/dist/core/tools/write.js +1 -44
  81. package/dist/core/tools/write.js.map +1 -1
  82. package/dist/entry.js +30 -28
  83. package/dist/entry.js.map +1 -1
  84. package/dist/i18n.d.ts.map +1 -1
  85. package/dist/i18n.js +2 -0
  86. package/dist/i18n.js.map +1 -1
  87. package/dist/index.d.ts +6 -3
  88. package/dist/index.d.ts.map +1 -1
  89. package/dist/index.js +6 -3
  90. package/dist/index.js.map +1 -1
  91. package/dist/interactive/builtin.d.ts +17 -0
  92. package/dist/interactive/builtin.d.ts.map +1 -0
  93. package/dist/interactive/builtin.js +47 -0
  94. package/dist/interactive/builtin.js.map +1 -0
  95. package/dist/interactive/controller.d.ts +85 -0
  96. package/dist/interactive/controller.d.ts.map +1 -0
  97. package/dist/interactive/controller.js +211 -0
  98. package/dist/interactive/controller.js.map +1 -0
  99. package/dist/interactive/index.d.ts +3 -0
  100. package/dist/interactive/index.d.ts.map +1 -0
  101. package/dist/interactive/index.js +3 -0
  102. package/dist/interactive/index.js.map +1 -0
  103. package/dist/interactive-host-entry.d.ts +7 -0
  104. package/dist/interactive-host-entry.d.ts.map +1 -0
  105. package/dist/interactive-host-entry.js +123 -0
  106. package/dist/interactive-host-entry.js.map +1 -0
  107. package/dist/interactive-profile.d.ts +18 -0
  108. package/dist/interactive-profile.d.ts.map +1 -0
  109. package/dist/interactive-profile.js +290 -0
  110. package/dist/interactive-profile.js.map +1 -0
  111. package/dist/interactive-resources-entry.d.ts +7 -0
  112. package/dist/interactive-resources-entry.d.ts.map +1 -0
  113. package/dist/interactive-resources-entry.js +42 -0
  114. package/dist/interactive-resources-entry.js.map +1 -0
  115. package/dist/legacy-main.d.ts +39 -0
  116. package/dist/legacy-main.d.ts.map +1 -0
  117. package/dist/legacy-main.js +611 -0
  118. package/dist/legacy-main.js.map +1 -0
  119. package/dist/main.d.ts +15 -34
  120. package/dist/main.d.ts.map +1 -1
  121. package/dist/main.js +130 -513
  122. package/dist/main.js.map +1 -1
  123. package/dist/mcp/entries.d.ts +42 -0
  124. package/dist/mcp/entries.d.ts.map +1 -0
  125. package/dist/mcp/entries.js +98 -0
  126. package/dist/mcp/entries.js.map +1 -0
  127. package/dist/mcp-client-entry.d.ts +5 -0
  128. package/dist/mcp-client-entry.d.ts.map +1 -0
  129. package/dist/mcp-client-entry.js +6 -0
  130. package/dist/mcp-client-entry.js.map +1 -0
  131. package/dist/mcp-config-entry.d.ts +5 -0
  132. package/dist/mcp-config-entry.d.ts.map +1 -0
  133. package/dist/mcp-config-entry.js +6 -0
  134. package/dist/mcp-config-entry.js.map +1 -0
  135. package/dist/mcp-tools-entry.d.ts +5 -0
  136. package/dist/mcp-tools-entry.d.ts.map +1 -0
  137. package/dist/mcp-tools-entry.js +6 -0
  138. package/dist/mcp-tools-entry.js.map +1 -0
  139. package/dist/mcp-transport-entry.d.ts +5 -0
  140. package/dist/mcp-transport-entry.d.ts.map +1 -0
  141. package/dist/mcp-transport-entry.js +6 -0
  142. package/dist/mcp-transport-entry.js.map +1 -0
  143. package/dist/modes/interactive-entry.d.ts +18 -0
  144. package/dist/modes/interactive-entry.d.ts.map +1 -0
  145. package/dist/modes/interactive-entry.js +21 -0
  146. package/dist/modes/interactive-entry.js.map +1 -0
  147. package/dist/modes/interactive-state.js +1 -1
  148. package/dist/modes/interactive-state.js.map +1 -1
  149. package/dist/modes/interactive.d.ts +16 -6
  150. package/dist/modes/interactive.d.ts.map +1 -1
  151. package/dist/modes/interactive.js +99 -33
  152. package/dist/modes/interactive.js.map +1 -1
  153. package/dist/modes/json-entry.d.ts +13 -0
  154. package/dist/modes/json-entry.d.ts.map +1 -0
  155. package/dist/modes/json-entry.js +14 -0
  156. package/dist/modes/json-entry.js.map +1 -0
  157. package/dist/modes/json.d.ts +4 -1
  158. package/dist/modes/json.d.ts.map +1 -1
  159. package/dist/modes/json.js +3 -3
  160. package/dist/modes/json.js.map +1 -1
  161. package/dist/modes/print-entry.d.ts +10 -0
  162. package/dist/modes/print-entry.d.ts.map +1 -0
  163. package/dist/modes/print-entry.js +11 -0
  164. package/dist/modes/print-entry.js.map +1 -0
  165. package/dist/modes/tree-selector.d.ts.map +1 -1
  166. package/dist/modes/tree-selector.js +4 -0
  167. package/dist/modes/tree-selector.js.map +1 -1
  168. package/dist/plugin-dump-composition.d.ts +6 -0
  169. package/dist/plugin-dump-composition.d.ts.map +1 -0
  170. package/dist/plugin-dump-composition.js +7 -0
  171. package/dist/plugin-dump-composition.js.map +1 -0
  172. package/dist/plugin-inventory.d.ts +7 -0
  173. package/dist/plugin-inventory.d.ts.map +1 -0
  174. package/dist/plugin-inventory.js +8 -0
  175. package/dist/plugin-inventory.js.map +1 -0
  176. package/dist/plugin-manager.d.ts +6 -0
  177. package/dist/plugin-manager.d.ts.map +1 -0
  178. package/dist/plugin-manager.js +7 -0
  179. package/dist/plugin-manager.js.map +1 -0
  180. package/dist/plugin-trace.d.ts +6 -0
  181. package/dist/plugin-trace.d.ts.map +1 -0
  182. package/dist/plugin-trace.js +7 -0
  183. package/dist/plugin-trace.js.map +1 -0
  184. package/dist/plugins/dynamic-broker.d.ts +76 -0
  185. package/dist/plugins/dynamic-broker.d.ts.map +1 -0
  186. package/dist/plugins/dynamic-broker.js +852 -0
  187. package/dist/plugins/dynamic-broker.js.map +1 -0
  188. package/dist/plugins/profile.d.ts +15 -0
  189. package/dist/plugins/profile.d.ts.map +1 -0
  190. package/dist/plugins/profile.js +34 -0
  191. package/dist/plugins/profile.js.map +1 -0
  192. package/dist/plugins/runtime-host.d.ts +37 -0
  193. package/dist/plugins/runtime-host.d.ts.map +1 -0
  194. package/dist/plugins/runtime-host.js +95 -0
  195. package/dist/plugins/runtime-host.js.map +1 -0
  196. package/dist/plugins/trust.d.ts +8 -0
  197. package/dist/plugins/trust.d.ts.map +1 -0
  198. package/dist/plugins/trust.js +59 -0
  199. package/dist/plugins/trust.js.map +1 -0
  200. package/dist/project-trust-entry.d.ts +15 -0
  201. package/dist/project-trust-entry.d.ts.map +1 -0
  202. package/dist/project-trust-entry.js +15 -0
  203. package/dist/project-trust-entry.js.map +1 -0
  204. package/dist/rpc/client.d.ts +78 -6
  205. package/dist/rpc/client.d.ts.map +1 -1
  206. package/dist/rpc/client.js +172 -4
  207. package/dist/rpc/client.js.map +1 -1
  208. package/dist/rpc/dispatcher.d.ts +121 -0
  209. package/dist/rpc/dispatcher.d.ts.map +1 -0
  210. package/dist/rpc/dispatcher.js +994 -0
  211. package/dist/rpc/dispatcher.js.map +1 -0
  212. package/dist/rpc/index.d.ts +2 -0
  213. package/dist/rpc/index.d.ts.map +1 -1
  214. package/dist/rpc/index.js +2 -0
  215. package/dist/rpc/index.js.map +1 -1
  216. package/dist/rpc/lifecycle.d.ts +6 -0
  217. package/dist/rpc/lifecycle.d.ts.map +1 -0
  218. package/dist/rpc/lifecycle.js +24 -0
  219. package/dist/rpc/lifecycle.js.map +1 -0
  220. package/dist/rpc/protocol.d.ts +112 -31
  221. package/dist/rpc/protocol.d.ts.map +1 -1
  222. package/dist/rpc/protocol.js +569 -117
  223. package/dist/rpc/protocol.js.map +1 -1
  224. package/dist/rpc/server-service.d.ts +7 -0
  225. package/dist/rpc/server-service.d.ts.map +1 -0
  226. package/dist/rpc/server-service.js +3 -0
  227. package/dist/rpc/server-service.js.map +1 -0
  228. package/dist/rpc/server.d.ts +16 -19
  229. package/dist/rpc/server.d.ts.map +1 -1
  230. package/dist/rpc/server.js +59 -115
  231. package/dist/rpc/server.js.map +1 -1
  232. package/dist/rpc-client-sdk-entry.d.ts +12 -0
  233. package/dist/rpc-client-sdk-entry.d.ts.map +1 -0
  234. package/dist/rpc-client-sdk-entry.js +11 -0
  235. package/dist/rpc-client-sdk-entry.js.map +1 -0
  236. package/dist/rpc-entry.js +50 -18
  237. package/dist/rpc-entry.js.map +1 -1
  238. package/dist/rpc-server-entry.d.ts +8 -0
  239. package/dist/rpc-server-entry.d.ts.map +1 -0
  240. package/dist/rpc-server-entry.js +67 -0
  241. package/dist/rpc-server-entry.js.map +1 -0
  242. package/dist/runtime/attachment-store.d.ts +13 -0
  243. package/dist/runtime/attachment-store.d.ts.map +1 -0
  244. package/dist/runtime/attachment-store.js +93 -0
  245. package/dist/runtime/attachment-store.js.map +1 -0
  246. package/dist/runtime/bootstrap.d.ts +14 -0
  247. package/dist/runtime/bootstrap.d.ts.map +1 -0
  248. package/dist/runtime/bootstrap.js +29 -0
  249. package/dist/runtime/bootstrap.js.map +1 -0
  250. package/dist/runtime/interactive-host-service.d.ts +22 -0
  251. package/dist/runtime/interactive-host-service.d.ts.map +1 -0
  252. package/dist/runtime/interactive-host-service.js +2 -0
  253. package/dist/runtime/interactive-host-service.js.map +1 -0
  254. package/dist/runtime/interactive-resource-service.d.ts +11 -0
  255. package/dist/runtime/interactive-resource-service.d.ts.map +1 -0
  256. package/dist/runtime/interactive-resource-service.js +3 -0
  257. package/dist/runtime/interactive-resource-service.js.map +1 -0
  258. package/dist/runtime/plugin-inventory-entry.d.ts +5 -0
  259. package/dist/runtime/plugin-inventory-entry.d.ts.map +1 -0
  260. package/dist/runtime/plugin-inventory-entry.js +18 -0
  261. package/dist/runtime/plugin-inventory-entry.js.map +1 -0
  262. package/dist/runtime/plugin-inventory-service.d.ts +8 -0
  263. package/dist/runtime/plugin-inventory-service.d.ts.map +1 -0
  264. package/dist/runtime/plugin-inventory-service.js +3 -0
  265. package/dist/runtime/plugin-inventory-service.js.map +1 -0
  266. package/dist/runtime/plugin-manager-entry.d.ts +20 -0
  267. package/dist/runtime/plugin-manager-entry.d.ts.map +1 -0
  268. package/dist/runtime/plugin-manager-entry.js +96 -0
  269. package/dist/runtime/plugin-manager-entry.js.map +1 -0
  270. package/dist/runtime/plugin-observability-entry.d.ts +12 -0
  271. package/dist/runtime/plugin-observability-entry.d.ts.map +1 -0
  272. package/dist/runtime/plugin-observability-entry.js +73 -0
  273. package/dist/runtime/plugin-observability-entry.js.map +1 -0
  274. package/dist/runtime/product-host.d.ts +91 -0
  275. package/dist/runtime/product-host.d.ts.map +1 -0
  276. package/dist/runtime/product-host.js +529 -0
  277. package/dist/runtime/product-host.js.map +1 -0
  278. package/dist/runtime/session-factory.d.ts +17 -0
  279. package/dist/runtime/session-factory.d.ts.map +1 -0
  280. package/dist/runtime/session-factory.js +75 -0
  281. package/dist/runtime/session-factory.js.map +1 -0
  282. package/dist/runtime/session-host.d.ts +152 -0
  283. package/dist/runtime/session-host.d.ts.map +1 -0
  284. package/dist/runtime/session-host.js +895 -0
  285. package/dist/runtime/session-host.js.map +1 -0
  286. package/dist/runtime-core-entry.d.ts +11 -0
  287. package/dist/runtime-core-entry.d.ts.map +1 -0
  288. package/dist/runtime-core-entry.js +9 -0
  289. package/dist/runtime-core-entry.js.map +1 -0
  290. package/dist/session-factory-entry.d.ts +7 -0
  291. package/dist/session-factory-entry.d.ts.map +1 -0
  292. package/dist/session-factory-entry.js +9 -0
  293. package/dist/session-factory-entry.js.map +1 -0
  294. package/dist/session-store-jsonl-entry.d.ts +7 -0
  295. package/dist/session-store-jsonl-entry.d.ts.map +1 -0
  296. package/dist/session-store-jsonl-entry.js +33 -0
  297. package/dist/session-store-jsonl-entry.js.map +1 -0
  298. package/dist/startup.d.ts +21 -1
  299. package/dist/startup.d.ts.map +1 -1
  300. package/dist/startup.js +179 -10
  301. package/dist/startup.js.map +1 -1
  302. package/dist/subagents/index.d.ts +2 -0
  303. package/dist/subagents/index.d.ts.map +1 -0
  304. package/dist/subagents/index.js +2 -0
  305. package/dist/subagents/index.js.map +1 -0
  306. package/dist/subagents/service.d.ts +50 -0
  307. package/dist/subagents/service.d.ts.map +1 -0
  308. package/dist/subagents/service.js +521 -0
  309. package/dist/subagents/service.js.map +1 -0
  310. package/dist/ui-host.d.ts +125 -0
  311. package/dist/ui-host.d.ts.map +1 -0
  312. package/dist/ui-host.js +275 -0
  313. package/dist/ui-host.js.map +1 -0
  314. package/dist/web/assets/index-BwfuGMvv.css +1 -0
  315. package/dist/web/assets/index-DPUaJqFJ.js +41 -0
  316. package/dist/web/assets/index-DPUaJqFJ.js.map +1 -0
  317. package/dist/web/index.html +14 -0
  318. package/dist/web-command.d.ts +11 -0
  319. package/dist/web-command.d.ts.map +1 -0
  320. package/dist/web-command.js +114 -0
  321. package/dist/web-command.js.map +1 -0
  322. package/dist/web-frontend.d.ts +73 -0
  323. package/dist/web-frontend.d.ts.map +1 -0
  324. package/dist/web-frontend.js +249 -0
  325. package/dist/web-frontend.js.map +1 -0
  326. package/dist/web.d.ts +254 -0
  327. package/dist/web.d.ts.map +1 -0
  328. package/dist/web.js +740 -0
  329. package/dist/web.js.map +1 -0
  330. package/dist/webui-entry.d.ts +3 -0
  331. package/dist/webui-entry.d.ts.map +1 -0
  332. package/dist/webui-entry.js +73 -0
  333. package/dist/webui-entry.js.map +1 -0
  334. package/dist/webui.d.ts +91 -0
  335. package/dist/webui.d.ts.map +1 -0
  336. package/dist/webui.js +882 -0
  337. package/dist/webui.js.map +1 -0
  338. package/package.json +89 -8
@@ -0,0 +1,611 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { access, readdir, stat } from "node:fs/promises";
3
+ import { homedir } from "node:os";
4
+ import { basename, dirname, extname, join, resolve } from "node:path";
5
+ import { createBuiltinCommandRegistry, createModeRegistry, createRendererRegistry } from "@di-code/builtins";
6
+ import { truncateToWidth } from "@di-code/tui";
7
+ import { createCliParser, runCli } from "./cli.js";
8
+ import { loadImageInputs } from "./core/image-input.js";
9
+ import { loadResources } from "./core/resources/loader.js";
10
+ import { SessionManager } from "./core/session/session-manager.js";
11
+ import { AgentSession } from "./core/session.js";
12
+ import { buildSystemPrompt } from "./core/system-prompt.js";
13
+ import { workspaceStorageKey } from "./core/user-data.js";
14
+ import { ProjectTrustManager } from "./extensions/trust.js";
15
+ import { DEFAULT_LOCALE, translate } from "./i18n.js";
16
+ import { addMcpConfig, getMcpConfig, listMcpConfig, removeMcpConfig } from "./mcp/config.js";
17
+ import { loadProjectMcp } from "./mcp/loader.js";
18
+ import { runInteractiveMode } from "./modes/interactive-entry.js";
19
+ import { runJsonModeEntry } from "./modes/json-entry.js";
20
+ import { runPrintModeEntry } from "./modes/print-entry.js";
21
+ import { loadPlugins } from "./plugins/loader.js";
22
+ import { PluginManager } from "./plugins/manager.js";
23
+ import { resolveThinkingLevelPreference } from "./startup.js";
24
+ const MAX_SESSION_QUESTION_LENGTH = 72;
25
+ function defaultSessionDirectory(agentDir, cwd) {
26
+ return join(agentDir, "sessions", workspaceStorageKey(cwd));
27
+ }
28
+ const STARTUP_STATUS_COLORS = {
29
+ error: "\x1b[31m",
30
+ success: "\x1b[32m",
31
+ warning: "\x1b[33m",
32
+ reset: "\x1b[0m",
33
+ };
34
+ function formatMcpStatus(status) {
35
+ switch (status.state) {
36
+ case "connecting":
37
+ return `${STARTUP_STATUS_COLORS.warning}MCP [loading]${STARTUP_STATUS_COLORS.reset} ${status.serverId}`;
38
+ case "connected":
39
+ return `${STARTUP_STATUS_COLORS.success}MCP [ok]${STARTUP_STATUS_COLORS.reset} ${status.serverId} (${status.tools} tools, ${status.resources} resources, ${status.prompts} prompts)`;
40
+ case "failed":
41
+ return `${STARTUP_STATUS_COLORS.error}MCP [error]${STARTUP_STATUS_COLORS.reset} ${status.serverId} (${status.stage}): ${status.message}`;
42
+ }
43
+ }
44
+ function formatMcpDiagnostic(serverId, stage, message) {
45
+ return `${STARTUP_STATUS_COLORS.error}MCP [error]${STARTUP_STATUS_COLORS.reset} ${serverId ?? "configuration"} (${stage}): ${message}\n`;
46
+ }
47
+ function formatPluginStatus(status) {
48
+ switch (status.state) {
49
+ case "loading":
50
+ return `${STARTUP_STATUS_COLORS.warning}Plugin [loading]${STARTUP_STATUS_COLORS.reset} ${status.pluginId}`;
51
+ case "loaded":
52
+ return `${STARTUP_STATUS_COLORS.success}Plugin [ok]${STARTUP_STATUS_COLORS.reset} ${status.pluginId} (${status.tools} tools, ${status.commands} commands)`;
53
+ case "failed":
54
+ return `${STARTUP_STATUS_COLORS.error}Plugin [error]${STARTUP_STATUS_COLORS.reset} ${status.pluginId ?? "plugin"} (${status.stage}): ${status.message}`;
55
+ }
56
+ }
57
+ function formatPluginDiagnostic(pluginId, stage, message) {
58
+ return `${STARTUP_STATUS_COLORS.error}Plugin [error]${STARTUP_STATUS_COLORS.reset} ${pluginId ?? "plugin"} (${stage}): ${message}\n`;
59
+ }
60
+ function pluginStatusKey(status) {
61
+ if (status.state === "failed" && status.pluginId === undefined)
62
+ return `plugin:${status.sourcePath}`;
63
+ return `plugin:${status.pluginId}`;
64
+ }
65
+ /** Renders startup states in place so terminal history retains only their final outcome. */
66
+ export class StartupStatusRenderer {
67
+ lines = [];
68
+ indexes = new Map();
69
+ write;
70
+ replaceInPlace;
71
+ width;
72
+ constructor(write, replaceInPlace, width = 80) {
73
+ this.write = write;
74
+ this.replaceInPlace = replaceInPlace;
75
+ this.width = width;
76
+ }
77
+ update(key, text) {
78
+ const line = truncateToWidth(text.replace(/[\r\n]+/g, " "), Math.max(1, this.width), "...");
79
+ const index = this.indexes.get(key);
80
+ if (index === undefined || !this.replaceInPlace) {
81
+ this.indexes.set(key, this.lines.length);
82
+ this.lines.push(line);
83
+ this.write(`${line}\n`);
84
+ return;
85
+ }
86
+ this.lines[index] = line;
87
+ const offset = this.lines.length - index;
88
+ this.write(`\x1b[${offset}A\r\x1b[2K${line}\x1b[${offset}B\r`);
89
+ }
90
+ }
91
+ function startupStatusRenderer(write, interactive) {
92
+ const width = typeof process.stderr.columns === "number" && process.stderr.columns > 0 ? process.stderr.columns : 80;
93
+ return new StartupStatusRenderer(write, interactive && process.stderr.isTTY === true, width);
94
+ }
95
+ async function openOrCreateSession(filePath, cwd, now) {
96
+ try {
97
+ await access(filePath);
98
+ return await SessionManager.open(filePath, { now });
99
+ }
100
+ catch (cause) {
101
+ if (!(cause instanceof Error && "code" in cause && cause.code === "ENOENT"))
102
+ throw cause;
103
+ return SessionManager.create({ filePath, cwd, now, deferCreate: true });
104
+ }
105
+ }
106
+ function newSessionPath(sessionDirectory, now) {
107
+ return join(sessionDirectory, `session-${now()}-${randomUUID().slice(0, 8)}.jsonl`);
108
+ }
109
+ async function mostRecentSessionPath(sessionDirectory) {
110
+ let names;
111
+ try {
112
+ names = (await readdir(sessionDirectory, { withFileTypes: true }))
113
+ .filter((entry) => entry.isFile() && extname(entry.name) === ".jsonl")
114
+ .map((entry) => entry.name);
115
+ }
116
+ catch (cause) {
117
+ if (cause instanceof Error && "code" in cause && cause.code === "ENOENT")
118
+ return undefined;
119
+ throw cause;
120
+ }
121
+ const candidates = await Promise.all(names.map(async (name) => {
122
+ const filePath = join(sessionDirectory, name);
123
+ try {
124
+ return { filePath, modifiedAt: (await stat(filePath)).mtimeMs };
125
+ }
126
+ catch (cause) {
127
+ if (cause instanceof Error && "code" in cause && cause.code === "ENOENT")
128
+ return undefined;
129
+ throw cause;
130
+ }
131
+ }));
132
+ return candidates
133
+ .filter((candidate) => candidate !== undefined)
134
+ .sort((left, right) => right.modifiedAt - left.modifiedAt || right.filePath.localeCompare(left.filePath))[0]
135
+ ?.filePath;
136
+ }
137
+ async function hasProjectLocalCapabilities(cwd) {
138
+ const directories = [
139
+ join(cwd, ".di-code", "skills"),
140
+ join(cwd, ".agents", "skills"),
141
+ join(cwd, ".di-code", "extensions"),
142
+ join(cwd, ".di-code", "plugins"),
143
+ join(cwd, ".di-code", "mcp.local.json"),
144
+ join(cwd, ".mcp.json"),
145
+ ];
146
+ const results = await Promise.all(directories.map(async (directory) => {
147
+ try {
148
+ const metadata = await stat(directory);
149
+ return metadata.isDirectory() || metadata.isFile();
150
+ }
151
+ catch (cause) {
152
+ if (cause instanceof Error && "code" in cause && cause.code === "ENOENT")
153
+ return false;
154
+ return false;
155
+ }
156
+ }));
157
+ return results.some(Boolean);
158
+ }
159
+ async function selectStartupSession(command, allowedRoot, agentDir, now) {
160
+ const sessionDirectory = defaultSessionDirectory(agentDir, allowedRoot);
161
+ if (command.sessionPath !== undefined) {
162
+ return openOrCreateSession(resolve(allowedRoot, command.sessionPath), allowedRoot, now);
163
+ }
164
+ if (command.continueSession) {
165
+ const recentPath = await mostRecentSessionPath(sessionDirectory);
166
+ if (recentPath !== undefined)
167
+ return SessionManager.open(recentPath, { now });
168
+ }
169
+ return SessionManager.create({
170
+ filePath: newSessionPath(sessionDirectory, now),
171
+ cwd: allowedRoot,
172
+ now,
173
+ deferCreate: true,
174
+ });
175
+ }
176
+ function formatSessionTimestamp(timestamp, fallback, timeZone) {
177
+ const date = new Date(timestamp);
178
+ if (Number.isNaN(date.getTime()))
179
+ return fallback;
180
+ try {
181
+ const parts = new Map(new Intl.DateTimeFormat("en-CA", {
182
+ timeZone: timeZone ?? Intl.DateTimeFormat().resolvedOptions().timeZone,
183
+ year: "numeric",
184
+ month: "2-digit",
185
+ day: "2-digit",
186
+ hour: "2-digit",
187
+ minute: "2-digit",
188
+ hourCycle: "h23",
189
+ })
190
+ .formatToParts(date)
191
+ .filter((part) => part.type !== "literal")
192
+ .map((part) => [part.type, part.value]));
193
+ const year = parts.get("year");
194
+ const month = parts.get("month");
195
+ const day = parts.get("day");
196
+ const hour = parts.get("hour");
197
+ const minute = parts.get("minute");
198
+ if (!year || !month || !day || !hour || !minute)
199
+ return fallback;
200
+ return `${year}-${month}-${day} ${hour}:${minute}`;
201
+ }
202
+ catch {
203
+ return fallback;
204
+ }
205
+ }
206
+ export function formatSessionLabel(manager, timeZone) {
207
+ const firstUserEntry = manager.entries.find((entry) => entry.type === "message" && entry.message.role === "user");
208
+ const fileName = basename(manager.filePath, extname(manager.filePath));
209
+ if (firstUserEntry?.type !== "message" || firstUserEntry.message.role !== "user") {
210
+ return `${fileName} (${formatSessionTimestamp(Date.parse(manager.header.timestamp), manager.header.timestamp, timeZone)})`;
211
+ }
212
+ const question = firstUserEntry.message.content
213
+ .filter((content) => content.type === "text")
214
+ .map((content) => content.text)
215
+ .join(" ")
216
+ .replace(/\s+/g, " ")
217
+ .trim();
218
+ const label = question.length > MAX_SESSION_QUESTION_LENGTH
219
+ ? `${question.slice(0, MAX_SESSION_QUESTION_LENGTH - 3)}...`
220
+ : question || fileName;
221
+ const timestamp = formatSessionTimestamp(firstUserEntry.message.timestamp, firstUserEntry.timestamp, timeZone);
222
+ return `${label} (${timestamp})`;
223
+ }
224
+ async function sessionChoices(sessionDirectory, currentFile, open) {
225
+ let names = [];
226
+ try {
227
+ names = (await readdir(sessionDirectory, { withFileTypes: true }))
228
+ .filter((entry) => entry.isFile() && extname(entry.name) === ".jsonl")
229
+ .map((entry) => entry.name)
230
+ .sort();
231
+ }
232
+ catch (cause) {
233
+ if (!(cause instanceof Error && "code" in cause && cause.code === "ENOENT"))
234
+ throw cause;
235
+ }
236
+ return Promise.all(names
237
+ .filter((name) => resolve(sessionDirectory, name) !== resolve(currentFile))
238
+ .map(async (name) => {
239
+ const filePath = join(sessionDirectory, name);
240
+ const id = basename(name, extname(name));
241
+ let label = id;
242
+ try {
243
+ label = formatSessionLabel(await SessionManager.open(filePath));
244
+ }
245
+ catch {
246
+ // Keep damaged sessions selectable so opening one can report the detailed load error.
247
+ }
248
+ return {
249
+ id,
250
+ label,
251
+ description: filePath,
252
+ open: () => open(filePath),
253
+ };
254
+ }));
255
+ }
256
+ export async function runMain(args, options) {
257
+ const dependencies = {
258
+ stdout: options.stdout,
259
+ stderr: options.stderr,
260
+ version: options.version,
261
+ locale: options.locale ?? options.startupConfiguration?.locale ?? DEFAULT_LOCALE,
262
+ parser: createCliParser(),
263
+ plugin: async (command) => {
264
+ const agentDir = resolve(options.agentDir ?? join(homedir(), ".di-code"));
265
+ const manager = new PluginManager({ agentDir });
266
+ try {
267
+ switch (command.action) {
268
+ case "list":
269
+ for (const plugin of await manager.list())
270
+ options.stdout(`${plugin.id}\t${plugin.enabled ? "enabled" : "disabled"}\t${plugin.manifest.version}\n`);
271
+ return 0;
272
+ case "get": {
273
+ const plugin = (await manager.list()).find((item) => item.id === command.argument);
274
+ if (!plugin)
275
+ throw new Error(`Unknown plugin: ${command.argument ?? ""}`);
276
+ options.stdout(`${JSON.stringify({
277
+ id: plugin.id,
278
+ enabled: plugin.enabled,
279
+ version: plugin.manifest.version,
280
+ installedAt: plugin.installedAt,
281
+ })}\n`);
282
+ return 0;
283
+ }
284
+ case "install": {
285
+ const plugin = await manager.install(command.argument);
286
+ options.stdout(`Installed ${plugin.id}\n`);
287
+ return 0;
288
+ }
289
+ case "enable":
290
+ await manager.enable(command.argument);
291
+ return 0;
292
+ case "disable":
293
+ await manager.disable(command.argument);
294
+ return 0;
295
+ case "update":
296
+ await manager.update(command.argument);
297
+ return 0;
298
+ case "remove":
299
+ await manager.remove(command.argument);
300
+ return 0;
301
+ }
302
+ }
303
+ catch (cause) {
304
+ options.stderr(`${cause instanceof Error ? cause.message : String(cause)}\n`);
305
+ return 1;
306
+ }
307
+ },
308
+ mcp: async (command) => {
309
+ const cwd = resolve(options.allowedRoot ?? process.cwd());
310
+ const scope = command.scope;
311
+ const trustManager = new ProjectTrustManager(join(options.agentDir ?? join(homedir(), ".di-code"), "trust.json"));
312
+ const requireProjectTrust = async (selected) => {
313
+ if ((selected === "local" || selected === "project") && (await trustManager.get(cwd)) !== true)
314
+ throw new Error(`Project trust is required to modify the ${selected} MCP scope.`);
315
+ };
316
+ try {
317
+ switch (command.action) {
318
+ case "add": {
319
+ const selected = scope ?? "local";
320
+ await requireProjectTrust(selected);
321
+ const config = command.transport === "stdio"
322
+ ? {
323
+ command: command.command,
324
+ ...(command.args && command.args.length > 0 ? { args: command.args } : {}),
325
+ }
326
+ : { type: "http", url: command.url };
327
+ await addMcpConfig(cwd, selected, command.serverId, config);
328
+ options.stdout(`Added MCP server "${command.serverId}" to ${selected} scope.\n`);
329
+ return 0;
330
+ }
331
+ case "list": {
332
+ const scopes = scope ? [scope] : ["local", "project", "user"];
333
+ for (const selected of scopes) {
334
+ for (const entry of await listMcpConfig(cwd, selected))
335
+ options.stdout(`${entry.id}\t${entry.scope}\t${JSON.stringify(entry.config)}\n`);
336
+ }
337
+ return 0;
338
+ }
339
+ case "get": {
340
+ const entry = await getMcpConfig(cwd, command.serverId, scope);
341
+ if (!entry)
342
+ throw new Error(`MCP server "${command.serverId}" was not found.`);
343
+ options.stdout(`${JSON.stringify({ id: entry.id, scope: entry.scope, config: entry.config })}\n`);
344
+ return 0;
345
+ }
346
+ case "remove": {
347
+ const selected = scope ?? "local";
348
+ await requireProjectTrust(selected);
349
+ await removeMcpConfig(cwd, selected, command.serverId);
350
+ options.stdout(`Removed MCP server "${command.serverId}" from ${selected} scope.\n`);
351
+ return 0;
352
+ }
353
+ }
354
+ }
355
+ catch (cause) {
356
+ options.stderr(`${cause instanceof Error ? cause.message : String(cause)}\n`);
357
+ return 1;
358
+ }
359
+ },
360
+ run: async (command) => {
361
+ const allowedRoot = resolve(options.allowedRoot ?? process.cwd());
362
+ const now = options.now ?? Date.now;
363
+ const agentDir = resolve(options.agentDir ?? join(homedir(), ".di-code"));
364
+ const trustManager = new ProjectTrustManager(join(agentDir, "trust.json"));
365
+ if (command.projectTrust !== undefined)
366
+ await trustManager.set(allowedRoot, command.projectTrust);
367
+ let persistedTrust = await trustManager.get(allowedRoot);
368
+ const shouldPromptForTrust = command.mode === "interactive" &&
369
+ options.isInteractiveTerminal === true &&
370
+ command.projectTrust === undefined &&
371
+ persistedTrust === null &&
372
+ options.promptProjectTrust !== undefined &&
373
+ (await hasProjectLocalCapabilities(allowedRoot));
374
+ if (shouldPromptForTrust) {
375
+ let decision = false;
376
+ try {
377
+ decision = await options.promptProjectTrust(allowedRoot);
378
+ }
379
+ catch {
380
+ // Fail closed when the prompt is interrupted or unavailable.
381
+ }
382
+ await trustManager.set(allowedRoot, decision);
383
+ persistedTrust = decision;
384
+ }
385
+ const runtime = await options.createRuntime(command);
386
+ if (runtime === undefined)
387
+ return 0;
388
+ const resources = await loadResources({
389
+ cwd: allowedRoot,
390
+ agentDir,
391
+ projectTrusted: persistedTrust === true,
392
+ noSkills: command.noSkills,
393
+ noContextFiles: command.noContextFiles,
394
+ skillPaths: command.skillPaths,
395
+ });
396
+ for (const diagnostic of resources.diagnostics) {
397
+ if (diagnostic.kind !== "skill")
398
+ continue;
399
+ options.stderr(`${JSON.stringify({ type: "skill_diagnostic", path: diagnostic.path, stage: diagnostic.stage, severity: diagnostic.severity, message: diagnostic.message })}\n`);
400
+ }
401
+ const interactivePluginStatus = command.mode === "interactive";
402
+ const startupStatus = startupStatusRenderer(options.stderr, interactivePluginStatus);
403
+ const pluginStatusFailures = new Set();
404
+ const extensions = await loadPlugins({
405
+ cwd: allowedRoot,
406
+ agentDir,
407
+ trustManager,
408
+ mode: command.mode,
409
+ ...(interactivePluginStatus
410
+ ? {
411
+ onPluginLoadStatus: (status) => {
412
+ if (status.state === "failed")
413
+ pluginStatusFailures.add(status.sourcePath);
414
+ startupStatus.update(pluginStatusKey(status), formatPluginStatus(status));
415
+ },
416
+ }
417
+ : {}),
418
+ });
419
+ for (const diagnostic of extensions.diagnostics) {
420
+ if (interactivePluginStatus) {
421
+ if (pluginStatusFailures.has(diagnostic.sourcePath))
422
+ continue;
423
+ options.stderr(formatPluginDiagnostic(diagnostic.pluginId, diagnostic.stage, diagnostic.message));
424
+ continue;
425
+ }
426
+ options.stderr(`${JSON.stringify({ type: "plugin_diagnostic", pluginId: diagnostic.pluginId, stage: diagnostic.stage, sourcePath: diagnostic.sourcePath, severity: diagnostic.severity, message: diagnostic.message })}\n`);
427
+ }
428
+ const interactiveMcpStatus = command.mode === "interactive";
429
+ const mcp = await loadProjectMcp({
430
+ cwd: allowedRoot,
431
+ projectTrusted: persistedTrust === true,
432
+ homeDirectory: homedir(),
433
+ reservedToolNames: [
434
+ "read",
435
+ "write",
436
+ "edit",
437
+ "bash",
438
+ "load_skill",
439
+ ...extensions.host.listTools().map((tool) => tool.name),
440
+ ],
441
+ ...(interactiveMcpStatus
442
+ ? {
443
+ onServerConnectionStatus: (status) => startupStatus.update(`mcp:${status.serverId}`, formatMcpStatus(status)),
444
+ }
445
+ : {}),
446
+ });
447
+ for (const diagnostic of mcp.diagnostics) {
448
+ if (interactiveMcpStatus) {
449
+ if (diagnostic.serverId && (diagnostic.stage === "connect" || diagnostic.stage === "list_tools"))
450
+ continue;
451
+ options.stderr(formatMcpDiagnostic(diagnostic.serverId, diagnostic.stage, diagnostic.message));
452
+ continue;
453
+ }
454
+ options.stderr(`${JSON.stringify({ type: "mcp_diagnostic", serverId: diagnostic.serverId, stage: diagnostic.stage, message: diagnostic.message })}\n`);
455
+ }
456
+ const systemPrompt = buildSystemPrompt({ cwd: allowedRoot, ...resources });
457
+ const manager = await selectStartupSession(command, allowedRoot, agentDir, now);
458
+ const sessionFile = manager.filePath;
459
+ const thinkingLevel = resolveThinkingLevelPreference(options.startupConfiguration, runtime);
460
+ const session = new AgentSession({
461
+ allowedRoot,
462
+ provider: runtime.provider,
463
+ model: runtime.model,
464
+ ...(thinkingLevel === undefined ? {} : { thinkingLevel }),
465
+ systemPrompt,
466
+ skills: resources.skills,
467
+ now: options.now,
468
+ sessionManager: manager,
469
+ extensionHost: extensions.host,
470
+ externalTools: mcp.tools,
471
+ });
472
+ const imagePaths = command.imagePaths ?? [];
473
+ const promptRunner = {
474
+ prompt: async (text) => session.promptWithImages(text, await loadImageInputs(imagePaths, allowedRoot)),
475
+ subscribe: session.subscribe.bind(session),
476
+ };
477
+ const modes = createModeRegistry();
478
+ const renderers = createRendererRegistry();
479
+ renderers.register({ name: "json", render: (event) => JSON.stringify({ version: 2, event }) });
480
+ const commandRegistry = (() => {
481
+ const registry = createBuiltinCommandRegistry();
482
+ for (const command of extensions.host.listCommands()) {
483
+ if (registry.list().some((entry) => entry.name === command.name))
484
+ continue;
485
+ registry.register({
486
+ name: command.name,
487
+ description: command.description,
488
+ run: (input) => {
489
+ const args = typeof input === "object" && input !== null && "args" in input && typeof input.args === "string"
490
+ ? input.args
491
+ : "";
492
+ return extensions.host.runCommand(command.name, args).then(() => 0);
493
+ },
494
+ });
495
+ }
496
+ return registry;
497
+ })();
498
+ const sessions = [
499
+ {
500
+ id: "new-session",
501
+ label: translate(options.locale ?? options.startupConfiguration?.locale ?? DEFAULT_LOCALE, "newSession"),
502
+ description: translate(options.locale ?? options.startupConfiguration?.locale ?? DEFAULT_LOCALE, "newSessionDescription"),
503
+ open: async () => {
504
+ const filePath = newSessionPath(dirname(sessionFile), now);
505
+ const nextManager = await SessionManager.create({ filePath, cwd: allowedRoot, now, deferCreate: true });
506
+ return new AgentSession({
507
+ allowedRoot,
508
+ provider: runtime.provider,
509
+ model: runtime.model,
510
+ ...(thinkingLevel === undefined ? {} : { thinkingLevel }),
511
+ systemPrompt,
512
+ skills: resources.skills,
513
+ now: options.now,
514
+ sessionManager: nextManager,
515
+ extensionHost: extensions.host,
516
+ externalTools: mcp.tools,
517
+ });
518
+ },
519
+ },
520
+ ...(await sessionChoices(dirname(sessionFile), sessionFile, async (filePath) => {
521
+ const nextManager = await SessionManager.open(filePath, { now });
522
+ return new AgentSession({
523
+ allowedRoot,
524
+ provider: runtime.provider,
525
+ model: runtime.model,
526
+ ...(thinkingLevel === undefined ? {} : { thinkingLevel }),
527
+ systemPrompt,
528
+ skills: resources.skills,
529
+ now: options.now,
530
+ sessionManager: nextManager,
531
+ extensionHost: extensions.host,
532
+ externalTools: mcp.tools,
533
+ });
534
+ })),
535
+ ];
536
+ let interactiveMode;
537
+ const interactiveContext = {
538
+ sessionChoices: () => sessions,
539
+ cancel: () => interactiveMode?.cancelActivePrompt(),
540
+ retry: () => interactiveMode?.retryLastPrompt(),
541
+ theme: () => "dark",
542
+ setTheme: (_value) => undefined,
543
+ keybindings: () => undefined,
544
+ };
545
+ modes.register({
546
+ name: "json",
547
+ run: async () => {
548
+ await extensions.host.emit({ type: "session_start", cwd: allowedRoot });
549
+ try {
550
+ return await runJsonModeEntry({
551
+ prompt: command.prompt,
552
+ runner: promptRunner,
553
+ io: options,
554
+ renderer: renderers.find("json"),
555
+ onStart: () => undefined,
556
+ onStop: () => undefined,
557
+ });
558
+ }
559
+ finally {
560
+ await extensions.host.emit({ type: "session_shutdown", reason: "user" });
561
+ await mcp.manager.close();
562
+ }
563
+ },
564
+ });
565
+ modes.register({
566
+ name: "interactive",
567
+ run: async () => {
568
+ const result = runInteractiveMode({
569
+ session,
570
+ agentDir,
571
+ locale: options.locale ?? options.startupConfiguration?.locale ?? DEFAULT_LOCALE,
572
+ commandRegistry,
573
+ context: interactiveContext,
574
+ onCreated: (mode) => {
575
+ interactiveMode = mode;
576
+ },
577
+ onExit: () => void mcp.manager.close(),
578
+ extensionHost: extensions.host,
579
+ ...(options.startupConfiguration
580
+ ? { providerOnboarding: { configuration: options.startupConfiguration, agentDir } }
581
+ : {}),
582
+ initialPrompt: command.prompt,
583
+ });
584
+ return result;
585
+ },
586
+ });
587
+ modes.register({
588
+ name: "print",
589
+ run: async () => {
590
+ await extensions.host.emit({ type: "session_start", cwd: allowedRoot });
591
+ try {
592
+ return await runPrintModeEntry({
593
+ prompt: command.prompt,
594
+ runner: promptRunner,
595
+ io: options,
596
+ onStart: () => undefined,
597
+ onStop: () => undefined,
598
+ });
599
+ }
600
+ finally {
601
+ await extensions.host.emit({ type: "session_shutdown", reason: "user" });
602
+ await mcp.manager.close();
603
+ }
604
+ },
605
+ });
606
+ return modes.execute(command.mode, {});
607
+ },
608
+ };
609
+ return runCli(args, dependencies);
610
+ }
611
+ //# sourceMappingURL=legacy-main.js.map