@hoangsonw/forge 0.1.1 → 0.1.2-nightly.20260425

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 (583) hide show
  1. package/README.md +135 -63
  2. package/bin/README.md +118 -0
  3. package/bin/forge.js +2 -0
  4. package/dist/agents/architect.d.ts +8 -0
  5. package/dist/agents/architect.d.ts.map +1 -1
  6. package/dist/agents/architect.js +8 -6
  7. package/dist/agents/architect.js.map +1 -1
  8. package/dist/agents/base.d.ts +5 -0
  9. package/dist/agents/base.d.ts.map +1 -1
  10. package/dist/agents/base.js +5 -0
  11. package/dist/agents/base.js.map +1 -1
  12. package/dist/agents/debugger.d.ts +5 -0
  13. package/dist/agents/debugger.d.ts.map +1 -1
  14. package/dist/agents/debugger.js +5 -0
  15. package/dist/agents/debugger.js.map +1 -1
  16. package/dist/agents/executor.d.ts +5 -0
  17. package/dist/agents/executor.d.ts.map +1 -1
  18. package/dist/agents/executor.js +19 -2
  19. package/dist/agents/executor.js.map +1 -1
  20. package/dist/agents/memory.d.ts +3 -1
  21. package/dist/agents/memory.d.ts.map +1 -1
  22. package/dist/agents/memory.js +7 -5
  23. package/dist/agents/memory.js.map +1 -1
  24. package/dist/agents/narrator.d.ts +70 -0
  25. package/dist/agents/narrator.d.ts.map +1 -0
  26. package/dist/agents/narrator.js +186 -0
  27. package/dist/agents/narrator.js.map +1 -0
  28. package/dist/agents/planner.d.ts +5 -0
  29. package/dist/agents/planner.d.ts.map +1 -1
  30. package/dist/agents/planner.js +24 -2
  31. package/dist/agents/planner.js.map +1 -1
  32. package/dist/agents/registry.d.ts +7 -0
  33. package/dist/agents/registry.d.ts.map +1 -1
  34. package/dist/agents/registry.js +7 -0
  35. package/dist/agents/registry.js.map +1 -1
  36. package/dist/agents/reviewer.d.ts +7 -0
  37. package/dist/agents/reviewer.d.ts.map +1 -1
  38. package/dist/agents/reviewer.js +20 -5
  39. package/dist/agents/reviewer.js.map +1 -1
  40. package/dist/classifier/classifier.d.ts +5 -0
  41. package/dist/classifier/classifier.d.ts.map +1 -1
  42. package/dist/classifier/classifier.js +31 -1
  43. package/dist/classifier/classifier.js.map +1 -1
  44. package/dist/classifier/heuristics.d.ts +23 -0
  45. package/dist/classifier/heuristics.d.ts.map +1 -1
  46. package/dist/classifier/heuristics.js +58 -2
  47. package/dist/classifier/heuristics.js.map +1 -1
  48. package/dist/cli/animations.d.ts +8 -0
  49. package/dist/cli/animations.d.ts.map +1 -1
  50. package/dist/cli/animations.js +8 -6
  51. package/dist/cli/animations.js.map +1 -1
  52. package/dist/cli/banners.d.ts +8 -2
  53. package/dist/cli/banners.d.ts.map +1 -1
  54. package/dist/cli/banners.js +48 -18
  55. package/dist/cli/banners.js.map +1 -1
  56. package/dist/cli/bootstrap.d.ts +5 -0
  57. package/dist/cli/bootstrap.d.ts.map +1 -1
  58. package/dist/cli/bootstrap.js +5 -0
  59. package/dist/cli/bootstrap.js.map +1 -1
  60. package/dist/cli/choose.d.ts +34 -0
  61. package/dist/cli/choose.d.ts.map +1 -0
  62. package/dist/cli/choose.js +219 -0
  63. package/dist/cli/choose.js.map +1 -0
  64. package/dist/cli/commands/bundle.d.ts +5 -0
  65. package/dist/cli/commands/bundle.d.ts.map +1 -1
  66. package/dist/cli/commands/bundle.js +5 -0
  67. package/dist/cli/commands/bundle.js.map +1 -1
  68. package/dist/cli/commands/changelog.d.ts +5 -0
  69. package/dist/cli/commands/changelog.d.ts.map +1 -1
  70. package/dist/cli/commands/changelog.js +5 -0
  71. package/dist/cli/commands/changelog.js.map +1 -1
  72. package/dist/cli/commands/config.d.ts +5 -0
  73. package/dist/cli/commands/config.d.ts.map +1 -1
  74. package/dist/cli/commands/config.js +5 -0
  75. package/dist/cli/commands/config.js.map +1 -1
  76. package/dist/cli/commands/container.d.ts +5 -0
  77. package/dist/cli/commands/container.d.ts.map +1 -1
  78. package/dist/cli/commands/container.js +5 -0
  79. package/dist/cli/commands/container.js.map +1 -1
  80. package/dist/cli/commands/cost.d.ts +5 -0
  81. package/dist/cli/commands/cost.d.ts.map +1 -1
  82. package/dist/cli/commands/cost.js +5 -0
  83. package/dist/cli/commands/cost.js.map +1 -1
  84. package/dist/cli/commands/daemon.d.ts +5 -0
  85. package/dist/cli/commands/daemon.d.ts.map +1 -1
  86. package/dist/cli/commands/daemon.js +5 -0
  87. package/dist/cli/commands/daemon.js.map +1 -1
  88. package/dist/cli/commands/dev.d.ts +5 -0
  89. package/dist/cli/commands/dev.d.ts.map +1 -1
  90. package/dist/cli/commands/dev.js +5 -0
  91. package/dist/cli/commands/dev.js.map +1 -1
  92. package/dist/cli/commands/doctor.d.ts +5 -0
  93. package/dist/cli/commands/doctor.d.ts.map +1 -1
  94. package/dist/cli/commands/doctor.js +5 -0
  95. package/dist/cli/commands/doctor.js.map +1 -1
  96. package/dist/cli/commands/init.d.ts +5 -0
  97. package/dist/cli/commands/init.d.ts.map +1 -1
  98. package/dist/cli/commands/init.js +5 -0
  99. package/dist/cli/commands/init.js.map +1 -1
  100. package/dist/cli/commands/mcp.d.ts +6 -0
  101. package/dist/cli/commands/mcp.d.ts.map +1 -1
  102. package/dist/cli/commands/mcp.js +6 -0
  103. package/dist/cli/commands/mcp.js.map +1 -1
  104. package/dist/cli/commands/memory.d.ts +5 -0
  105. package/dist/cli/commands/memory.d.ts.map +1 -1
  106. package/dist/cli/commands/memory.js +5 -0
  107. package/dist/cli/commands/memory.js.map +1 -1
  108. package/dist/cli/commands/migrate.d.ts +5 -0
  109. package/dist/cli/commands/migrate.d.ts.map +1 -1
  110. package/dist/cli/commands/migrate.js +5 -0
  111. package/dist/cli/commands/migrate.js.map +1 -1
  112. package/dist/cli/commands/model.d.ts +5 -0
  113. package/dist/cli/commands/model.d.ts.map +1 -1
  114. package/dist/cli/commands/model.js +5 -0
  115. package/dist/cli/commands/model.js.map +1 -1
  116. package/dist/cli/commands/permissions.d.ts +5 -0
  117. package/dist/cli/commands/permissions.d.ts.map +1 -1
  118. package/dist/cli/commands/permissions.js +5 -0
  119. package/dist/cli/commands/permissions.js.map +1 -1
  120. package/dist/cli/commands/resume.d.ts +5 -0
  121. package/dist/cli/commands/resume.d.ts.map +1 -1
  122. package/dist/cli/commands/resume.js +5 -0
  123. package/dist/cli/commands/resume.js.map +1 -1
  124. package/dist/cli/commands/run.d.ts +5 -0
  125. package/dist/cli/commands/run.d.ts.map +1 -1
  126. package/dist/cli/commands/run.js +21 -8
  127. package/dist/cli/commands/run.js.map +1 -1
  128. package/dist/cli/commands/session.d.ts +8 -0
  129. package/dist/cli/commands/session.d.ts.map +1 -1
  130. package/dist/cli/commands/session.js +8 -0
  131. package/dist/cli/commands/session.js.map +1 -1
  132. package/dist/cli/commands/skills.d.ts +5 -0
  133. package/dist/cli/commands/skills.d.ts.map +1 -1
  134. package/dist/cli/commands/skills.js +5 -0
  135. package/dist/cli/commands/skills.js.map +1 -1
  136. package/dist/cli/commands/spec.d.ts +6 -0
  137. package/dist/cli/commands/spec.d.ts.map +1 -1
  138. package/dist/cli/commands/spec.js +6 -0
  139. package/dist/cli/commands/spec.js.map +1 -1
  140. package/dist/cli/commands/status.d.ts +5 -0
  141. package/dist/cli/commands/status.d.ts.map +1 -1
  142. package/dist/cli/commands/status.js +5 -0
  143. package/dist/cli/commands/status.js.map +1 -1
  144. package/dist/cli/commands/task.d.ts +8 -0
  145. package/dist/cli/commands/task.d.ts.map +1 -1
  146. package/dist/cli/commands/task.js +76 -0
  147. package/dist/cli/commands/task.js.map +1 -1
  148. package/dist/cli/commands/ui.d.ts +5 -0
  149. package/dist/cli/commands/ui.d.ts.map +1 -1
  150. package/dist/cli/commands/ui.js +5 -0
  151. package/dist/cli/commands/ui.js.map +1 -1
  152. package/dist/cli/commands/update.d.ts +5 -0
  153. package/dist/cli/commands/update.d.ts.map +1 -1
  154. package/dist/cli/commands/update.js +5 -0
  155. package/dist/cli/commands/update.js.map +1 -1
  156. package/dist/cli/commands/web.d.ts +5 -0
  157. package/dist/cli/commands/web.d.ts.map +1 -1
  158. package/dist/cli/commands/web.js +5 -0
  159. package/dist/cli/commands/web.js.map +1 -1
  160. package/dist/cli/help.d.ts +2 -0
  161. package/dist/cli/help.d.ts.map +1 -1
  162. package/dist/cli/help.js +2 -0
  163. package/dist/cli/help.js.map +1 -1
  164. package/dist/cli/index.js +14 -0
  165. package/dist/cli/index.js.map +1 -1
  166. package/dist/cli/markdown.d.ts.map +1 -1
  167. package/dist/cli/markdown.js +115 -10
  168. package/dist/cli/markdown.js.map +1 -1
  169. package/dist/cli/progress.d.ts +42 -0
  170. package/dist/cli/progress.d.ts.map +1 -0
  171. package/dist/cli/progress.js +335 -0
  172. package/dist/cli/progress.js.map +1 -0
  173. package/dist/cli/repl-commands.d.ts +2 -0
  174. package/dist/cli/repl-commands.d.ts.map +1 -1
  175. package/dist/cli/repl-commands.js +2 -0
  176. package/dist/cli/repl-commands.js.map +1 -1
  177. package/dist/cli/repl-input.d.ts +3 -0
  178. package/dist/cli/repl-input.d.ts.map +1 -1
  179. package/dist/cli/repl-input.js +87 -39
  180. package/dist/cli/repl-input.js.map +1 -1
  181. package/dist/cli/repl.d.ts.map +1 -1
  182. package/dist/cli/repl.js +109 -29
  183. package/dist/cli/repl.js.map +1 -1
  184. package/dist/cli/ui.d.ts +9 -0
  185. package/dist/cli/ui.d.ts.map +1 -1
  186. package/dist/cli/ui.js +9 -0
  187. package/dist/cli/ui.js.map +1 -1
  188. package/dist/config/loader.d.ts +5 -0
  189. package/dist/config/loader.d.ts.map +1 -1
  190. package/dist/config/loader.js +5 -0
  191. package/dist/config/loader.js.map +1 -1
  192. package/dist/config/paths.d.ts +8 -0
  193. package/dist/config/paths.d.ts.map +1 -1
  194. package/dist/config/paths.js +8 -0
  195. package/dist/config/paths.js.map +1 -1
  196. package/dist/config/schema.d.ts +17 -0
  197. package/dist/config/schema.d.ts.map +1 -1
  198. package/dist/config/schema.js +17 -0
  199. package/dist/config/schema.js.map +1 -1
  200. package/dist/config/xdg.d.ts.map +1 -1
  201. package/dist/config/xdg.js +2 -0
  202. package/dist/config/xdg.js.map +1 -1
  203. package/dist/core/continuity.d.ts.map +1 -1
  204. package/dist/core/continuity.js +2 -0
  205. package/dist/core/continuity.js.map +1 -1
  206. package/dist/core/conversation.d.ts +2 -0
  207. package/dist/core/conversation.d.ts.map +1 -1
  208. package/dist/core/conversation.js +2 -0
  209. package/dist/core/conversation.js.map +1 -1
  210. package/dist/core/estimation.d.ts +2 -0
  211. package/dist/core/estimation.d.ts.map +1 -1
  212. package/dist/core/estimation.js.map +1 -1
  213. package/dist/core/fork.d.ts.map +1 -1
  214. package/dist/core/fork.js +2 -0
  215. package/dist/core/fork.js.map +1 -1
  216. package/dist/core/interactive-host.d.ts +11 -2
  217. package/dist/core/interactive-host.d.ts.map +1 -1
  218. package/dist/core/interactive-host.js +12 -0
  219. package/dist/core/interactive-host.js.map +1 -1
  220. package/dist/core/loop-detection.d.ts +2 -0
  221. package/dist/core/loop-detection.d.ts.map +1 -1
  222. package/dist/core/loop-detection.js.map +1 -1
  223. package/dist/core/loop.d.ts +11 -0
  224. package/dist/core/loop.d.ts.map +1 -1
  225. package/dist/core/loop.js +244 -26
  226. package/dist/core/loop.js.map +1 -1
  227. package/dist/core/mode-policy.d.ts +2 -0
  228. package/dist/core/mode-policy.d.ts.map +1 -1
  229. package/dist/core/mode-policy.js.map +1 -1
  230. package/dist/core/orchestrator.d.ts +14 -0
  231. package/dist/core/orchestrator.d.ts.map +1 -1
  232. package/dist/core/orchestrator.js +79 -1
  233. package/dist/core/orchestrator.js.map +1 -1
  234. package/dist/core/plan-fixer.d.ts +3 -1
  235. package/dist/core/plan-fixer.d.ts.map +1 -1
  236. package/dist/core/plan-fixer.js +10 -0
  237. package/dist/core/plan-fixer.js.map +1 -1
  238. package/dist/core/signals.d.ts.map +1 -1
  239. package/dist/core/signals.js +2 -0
  240. package/dist/core/signals.js.map +1 -1
  241. package/dist/core/spec.d.ts.map +1 -1
  242. package/dist/core/spec.js +2 -0
  243. package/dist/core/spec.js.map +1 -1
  244. package/dist/core/validation.d.ts.map +1 -1
  245. package/dist/core/validation.js +2 -0
  246. package/dist/core/validation.js.map +1 -1
  247. package/dist/daemon/control.d.ts +5 -0
  248. package/dist/daemon/control.d.ts.map +1 -1
  249. package/dist/daemon/control.js +5 -0
  250. package/dist/daemon/control.js.map +1 -1
  251. package/dist/daemon/server.d.ts +2 -0
  252. package/dist/daemon/server.d.ts.map +1 -1
  253. package/dist/daemon/server.js +7 -5
  254. package/dist/daemon/server.js.map +1 -1
  255. package/dist/daemon/updater.d.ts +5 -0
  256. package/dist/daemon/updater.d.ts.map +1 -1
  257. package/dist/daemon/updater.js +20 -6
  258. package/dist/daemon/updater.js.map +1 -1
  259. package/dist/keychain/index.d.ts.map +1 -1
  260. package/dist/keychain/index.js +2 -0
  261. package/dist/keychain/index.js.map +1 -1
  262. package/dist/keychain/windows.d.ts.map +1 -1
  263. package/dist/keychain/windows.js +2 -0
  264. package/dist/keychain/windows.js.map +1 -1
  265. package/dist/logging/logger.d.ts +9 -0
  266. package/dist/logging/logger.d.ts.map +1 -1
  267. package/dist/logging/logger.js +9 -5
  268. package/dist/logging/logger.js.map +1 -1
  269. package/dist/logging/rotation.d.ts.map +1 -1
  270. package/dist/logging/rotation.js +2 -0
  271. package/dist/logging/rotation.js.map +1 -1
  272. package/dist/logging/trace.d.ts +9 -0
  273. package/dist/logging/trace.d.ts.map +1 -1
  274. package/dist/logging/trace.js +9 -0
  275. package/dist/logging/trace.js.map +1 -1
  276. package/dist/mcp/client.d.ts +2 -0
  277. package/dist/mcp/client.d.ts.map +1 -1
  278. package/dist/mcp/client.js +8 -0
  279. package/dist/mcp/client.js.map +1 -1
  280. package/dist/mcp/http-transport.d.ts.map +1 -1
  281. package/dist/mcp/http-transport.js +2 -0
  282. package/dist/mcp/http-transport.js.map +1 -1
  283. package/dist/mcp/oauth.d.ts.map +1 -1
  284. package/dist/mcp/oauth.js +2 -0
  285. package/dist/mcp/oauth.js.map +1 -1
  286. package/dist/mcp/registry.d.ts +6 -0
  287. package/dist/mcp/registry.d.ts.map +1 -1
  288. package/dist/mcp/registry.js +6 -0
  289. package/dist/mcp/registry.js.map +1 -1
  290. package/dist/memory/cold.d.ts.map +1 -1
  291. package/dist/memory/cold.js +2 -0
  292. package/dist/memory/cold.js.map +1 -1
  293. package/dist/memory/graph.d.ts.map +1 -1
  294. package/dist/memory/graph.js +2 -0
  295. package/dist/memory/graph.js.map +1 -1
  296. package/dist/memory/hot.d.ts +2 -0
  297. package/dist/memory/hot.d.ts.map +1 -1
  298. package/dist/memory/hot.js +2 -0
  299. package/dist/memory/hot.js.map +1 -1
  300. package/dist/memory/learning.d.ts.map +1 -1
  301. package/dist/memory/learning.js +2 -0
  302. package/dist/memory/learning.js.map +1 -1
  303. package/dist/memory/retrieval.d.ts.map +1 -1
  304. package/dist/memory/retrieval.js +2 -0
  305. package/dist/memory/retrieval.js.map +1 -1
  306. package/dist/memory/warm.d.ts.map +1 -1
  307. package/dist/memory/warm.js +2 -0
  308. package/dist/memory/warm.js.map +1 -1
  309. package/dist/migrations/runner.d.ts +2 -0
  310. package/dist/migrations/runner.d.ts.map +1 -1
  311. package/dist/migrations/runner.js +2 -0
  312. package/dist/migrations/runner.js.map +1 -1
  313. package/dist/models/adapter.d.ts +2 -0
  314. package/dist/models/adapter.d.ts.map +1 -1
  315. package/dist/models/adapter.js +14 -0
  316. package/dist/models/adapter.js.map +1 -1
  317. package/dist/models/anthropic.d.ts +11 -1
  318. package/dist/models/anthropic.d.ts.map +1 -1
  319. package/dist/models/anthropic.js +128 -5
  320. package/dist/models/anthropic.js.map +1 -1
  321. package/dist/models/cache.d.ts +9 -0
  322. package/dist/models/cache.d.ts.map +1 -1
  323. package/dist/models/cache.js +9 -7
  324. package/dist/models/cache.js.map +1 -1
  325. package/dist/models/circuit-breaker.d.ts +2 -0
  326. package/dist/models/circuit-breaker.d.ts.map +1 -1
  327. package/dist/models/circuit-breaker.js +8 -0
  328. package/dist/models/circuit-breaker.js.map +1 -1
  329. package/dist/models/cost.d.ts +8 -0
  330. package/dist/models/cost.d.ts.map +1 -1
  331. package/dist/models/cost.js +4 -2
  332. package/dist/models/cost.js.map +1 -1
  333. package/dist/models/llamacpp.d.ts +3 -1
  334. package/dist/models/llamacpp.d.ts.map +1 -1
  335. package/dist/models/llamacpp.js +5 -3
  336. package/dist/models/llamacpp.js.map +1 -1
  337. package/dist/models/lmstudio.d.ts +3 -1
  338. package/dist/models/lmstudio.d.ts.map +1 -1
  339. package/dist/models/lmstudio.js +5 -3
  340. package/dist/models/lmstudio.js.map +1 -1
  341. package/dist/models/local-catalog.d.ts +2 -0
  342. package/dist/models/local-catalog.d.ts.map +1 -1
  343. package/dist/models/local-catalog.js.map +1 -1
  344. package/dist/models/ollama.d.ts +24 -1
  345. package/dist/models/ollama.d.ts.map +1 -1
  346. package/dist/models/ollama.js +158 -1
  347. package/dist/models/ollama.js.map +1 -1
  348. package/dist/models/openai.d.ts +11 -1
  349. package/dist/models/openai.d.ts.map +1 -1
  350. package/dist/models/openai.js +108 -5
  351. package/dist/models/openai.js.map +1 -1
  352. package/dist/models/provider.d.ts +5 -0
  353. package/dist/models/provider.d.ts.map +1 -1
  354. package/dist/models/provider.js +5 -0
  355. package/dist/models/provider.js.map +1 -1
  356. package/dist/models/rate-limit.d.ts +2 -0
  357. package/dist/models/rate-limit.d.ts.map +1 -1
  358. package/dist/models/rate-limit.js +7 -0
  359. package/dist/models/rate-limit.js.map +1 -1
  360. package/dist/models/registry.d.ts +5 -0
  361. package/dist/models/registry.d.ts.map +1 -1
  362. package/dist/models/registry.js +5 -0
  363. package/dist/models/registry.js.map +1 -1
  364. package/dist/models/router.d.ts +24 -0
  365. package/dist/models/router.d.ts.map +1 -1
  366. package/dist/models/router.js +163 -3
  367. package/dist/models/router.js.map +1 -1
  368. package/dist/models/vllm.d.ts +3 -1
  369. package/dist/models/vllm.d.ts.map +1 -1
  370. package/dist/models/vllm.js +5 -3
  371. package/dist/models/vllm.js.map +1 -1
  372. package/dist/notifications/manager.d.ts +7 -0
  373. package/dist/notifications/manager.d.ts.map +1 -1
  374. package/dist/notifications/manager.js +7 -0
  375. package/dist/notifications/manager.js.map +1 -1
  376. package/dist/permissions/manager.d.ts +8 -0
  377. package/dist/permissions/manager.d.ts.map +1 -1
  378. package/dist/permissions/manager.js +33 -18
  379. package/dist/permissions/manager.js.map +1 -1
  380. package/dist/permissions/risk.d.ts +3 -1
  381. package/dist/permissions/risk.d.ts.map +1 -1
  382. package/dist/permissions/risk.js +4 -2
  383. package/dist/permissions/risk.js.map +1 -1
  384. package/dist/persistence/compression.d.ts +8 -0
  385. package/dist/persistence/compression.d.ts.map +1 -1
  386. package/dist/persistence/compression.js +8 -6
  387. package/dist/persistence/compression.js.map +1 -1
  388. package/dist/persistence/conversation-store.d.ts +2 -0
  389. package/dist/persistence/conversation-store.d.ts.map +1 -1
  390. package/dist/persistence/conversation-store.js +2 -0
  391. package/dist/persistence/conversation-store.js.map +1 -1
  392. package/dist/persistence/events.d.ts +35 -0
  393. package/dist/persistence/events.d.ts.map +1 -1
  394. package/dist/persistence/events.js +41 -1
  395. package/dist/persistence/events.js.map +1 -1
  396. package/dist/persistence/index-db.d.ts +12 -0
  397. package/dist/persistence/index-db.d.ts.map +1 -1
  398. package/dist/persistence/index-db.js +20 -1
  399. package/dist/persistence/index-db.js.map +1 -1
  400. package/dist/persistence/jsonl.d.ts +2 -0
  401. package/dist/persistence/jsonl.d.ts.map +1 -1
  402. package/dist/persistence/jsonl.js +6 -4
  403. package/dist/persistence/jsonl.js.map +1 -1
  404. package/dist/persistence/sessions.d.ts +7 -0
  405. package/dist/persistence/sessions.d.ts.map +1 -1
  406. package/dist/persistence/sessions.js +7 -0
  407. package/dist/persistence/sessions.js.map +1 -1
  408. package/dist/persistence/tasks.d.ts +15 -0
  409. package/dist/persistence/tasks.d.ts.map +1 -1
  410. package/dist/persistence/tasks.js +32 -2
  411. package/dist/persistence/tasks.js.map +1 -1
  412. package/dist/prompts/assembler.d.ts +6 -0
  413. package/dist/prompts/assembler.d.ts.map +1 -1
  414. package/dist/prompts/assembler.js +6 -0
  415. package/dist/prompts/assembler.js.map +1 -1
  416. package/dist/prompts/layers.d.ts +5 -0
  417. package/dist/prompts/layers.d.ts.map +1 -1
  418. package/dist/prompts/layers.js +5 -0
  419. package/dist/prompts/layers.js.map +1 -1
  420. package/dist/release/download.d.ts.map +1 -1
  421. package/dist/release/download.js +2 -0
  422. package/dist/release/download.js.map +1 -1
  423. package/dist/release/verify.d.ts.map +1 -1
  424. package/dist/release/verify.js +2 -0
  425. package/dist/release/verify.js.map +1 -1
  426. package/dist/sandbox/file-lock.d.ts +40 -0
  427. package/dist/sandbox/file-lock.d.ts.map +1 -0
  428. package/dist/sandbox/file-lock.js +118 -0
  429. package/dist/sandbox/file-lock.js.map +1 -0
  430. package/dist/sandbox/fs.d.ts +5 -0
  431. package/dist/sandbox/fs.d.ts.map +1 -1
  432. package/dist/sandbox/fs.js +24 -1
  433. package/dist/sandbox/fs.js.map +1 -1
  434. package/dist/sandbox/shell.d.ts +5 -0
  435. package/dist/sandbox/shell.d.ts.map +1 -1
  436. package/dist/sandbox/shell.js +5 -0
  437. package/dist/sandbox/shell.js.map +1 -1
  438. package/dist/scheduler/dag.d.ts +5 -0
  439. package/dist/scheduler/dag.d.ts.map +1 -1
  440. package/dist/scheduler/dag.js +5 -0
  441. package/dist/scheduler/dag.js.map +1 -1
  442. package/dist/scheduler/resource-manager.d.ts +2 -0
  443. package/dist/scheduler/resource-manager.d.ts.map +1 -1
  444. package/dist/scheduler/resource-manager.js +7 -0
  445. package/dist/scheduler/resource-manager.js.map +1 -1
  446. package/dist/security/injection.d.ts +2 -0
  447. package/dist/security/injection.d.ts.map +1 -1
  448. package/dist/security/injection.js +2 -0
  449. package/dist/security/injection.js.map +1 -1
  450. package/dist/security/redact.d.ts +2 -0
  451. package/dist/security/redact.d.ts.map +1 -1
  452. package/dist/security/redact.js +2 -0
  453. package/dist/security/redact.js.map +1 -1
  454. package/dist/skills/loader.d.ts +5 -0
  455. package/dist/skills/loader.d.ts.map +1 -1
  456. package/dist/skills/loader.js +5 -0
  457. package/dist/skills/loader.js.map +1 -1
  458. package/dist/skills/marketplace.d.ts.map +1 -1
  459. package/dist/skills/marketplace.js +2 -0
  460. package/dist/skills/marketplace.js.map +1 -1
  461. package/dist/tools/apply-patch.d.ts +3 -1
  462. package/dist/tools/apply-patch.d.ts.map +1 -1
  463. package/dist/tools/apply-patch.js +11 -0
  464. package/dist/tools/apply-patch.js.map +1 -1
  465. package/dist/tools/ask-user.d.ts +9 -0
  466. package/dist/tools/ask-user.d.ts.map +1 -1
  467. package/dist/tools/ask-user.js +30 -5
  468. package/dist/tools/ask-user.js.map +1 -1
  469. package/dist/tools/delete-file.d.ts +5 -0
  470. package/dist/tools/delete-file.d.ts.map +1 -1
  471. package/dist/tools/delete-file.js +5 -0
  472. package/dist/tools/delete-file.js.map +1 -1
  473. package/dist/tools/edit-file.d.ts +5 -0
  474. package/dist/tools/edit-file.d.ts.map +1 -1
  475. package/dist/tools/edit-file.js +61 -34
  476. package/dist/tools/edit-file.js.map +1 -1
  477. package/dist/tools/format.d.ts +7 -0
  478. package/dist/tools/format.d.ts.map +1 -1
  479. package/dist/tools/format.js +7 -5
  480. package/dist/tools/format.js.map +1 -1
  481. package/dist/tools/git.d.ts +7 -0
  482. package/dist/tools/git.d.ts.map +1 -1
  483. package/dist/tools/git.js +7 -0
  484. package/dist/tools/git.js.map +1 -1
  485. package/dist/tools/glob.d.ts +5 -0
  486. package/dist/tools/glob.d.ts.map +1 -1
  487. package/dist/tools/glob.js +5 -0
  488. package/dist/tools/glob.js.map +1 -1
  489. package/dist/tools/grep.d.ts +5 -0
  490. package/dist/tools/grep.d.ts.map +1 -1
  491. package/dist/tools/grep.js +5 -0
  492. package/dist/tools/grep.js.map +1 -1
  493. package/dist/tools/init.d.ts +5 -0
  494. package/dist/tools/init.d.ts.map +1 -1
  495. package/dist/tools/init.js +5 -0
  496. package/dist/tools/init.js.map +1 -1
  497. package/dist/tools/list-dir.d.ts +5 -0
  498. package/dist/tools/list-dir.d.ts.map +1 -1
  499. package/dist/tools/list-dir.js +5 -0
  500. package/dist/tools/list-dir.js.map +1 -1
  501. package/dist/tools/move-file.d.ts +5 -0
  502. package/dist/tools/move-file.d.ts.map +1 -1
  503. package/dist/tools/move-file.js +9 -2
  504. package/dist/tools/move-file.js.map +1 -1
  505. package/dist/tools/read-file.d.ts +5 -0
  506. package/dist/tools/read-file.d.ts.map +1 -1
  507. package/dist/tools/read-file.js +5 -0
  508. package/dist/tools/read-file.js.map +1 -1
  509. package/dist/tools/registry.d.ts +5 -0
  510. package/dist/tools/registry.d.ts.map +1 -1
  511. package/dist/tools/registry.js +5 -0
  512. package/dist/tools/registry.js.map +1 -1
  513. package/dist/tools/run-command.d.ts +5 -0
  514. package/dist/tools/run-command.d.ts.map +1 -1
  515. package/dist/tools/run-command.js +5 -0
  516. package/dist/tools/run-command.js.map +1 -1
  517. package/dist/tools/run-tests.d.ts +6 -1
  518. package/dist/tools/run-tests.d.ts.map +1 -1
  519. package/dist/tools/run-tests.js +39 -0
  520. package/dist/tools/run-tests.js.map +1 -1
  521. package/dist/tools/web-browse.d.ts +5 -0
  522. package/dist/tools/web-browse.d.ts.map +1 -1
  523. package/dist/tools/web-browse.js +5 -0
  524. package/dist/tools/web-browse.js.map +1 -1
  525. package/dist/tools/web-fetch.d.ts +5 -0
  526. package/dist/tools/web-fetch.d.ts.map +1 -1
  527. package/dist/tools/web-fetch.js +5 -0
  528. package/dist/tools/web-fetch.js.map +1 -1
  529. package/dist/tools/web-search.d.ts +5 -0
  530. package/dist/tools/web-search.d.ts.map +1 -1
  531. package/dist/tools/web-search.js +5 -0
  532. package/dist/tools/web-search.js.map +1 -1
  533. package/dist/tools/write-file.d.ts +5 -0
  534. package/dist/tools/write-file.d.ts.map +1 -1
  535. package/dist/tools/write-file.js +43 -24
  536. package/dist/tools/write-file.js.map +1 -1
  537. package/dist/types/errors.d.ts +5 -0
  538. package/dist/types/errors.d.ts.map +1 -1
  539. package/dist/types/errors.js +5 -0
  540. package/dist/types/errors.js.map +1 -1
  541. package/dist/types/index.d.ts +35 -2
  542. package/dist/types/index.d.ts.map +1 -1
  543. package/dist/types/index.js +2 -0
  544. package/dist/types/index.js.map +1 -1
  545. package/dist/ui/chat.d.ts +2 -0
  546. package/dist/ui/chat.d.ts.map +1 -1
  547. package/dist/ui/chat.js +2 -0
  548. package/dist/ui/chat.js.map +1 -1
  549. package/dist/ui/public/app.js +701 -51
  550. package/dist/ui/public/index.html +4 -1
  551. package/dist/ui/public/markdown.js +108 -13
  552. package/dist/ui/public/styles.css +232 -4
  553. package/dist/ui/server-errors.d.ts +3 -1
  554. package/dist/ui/server-errors.d.ts.map +1 -1
  555. package/dist/ui/server-errors.js +3 -1
  556. package/dist/ui/server-errors.js.map +1 -1
  557. package/dist/ui/server.d.ts.map +1 -1
  558. package/dist/ui/server.js +62 -2
  559. package/dist/ui/server.js.map +1 -1
  560. package/dist/ui/task-runner.d.ts +2 -1
  561. package/dist/ui/task-runner.d.ts.map +1 -1
  562. package/dist/ui/task-runner.js +147 -14
  563. package/dist/ui/task-runner.js.map +1 -1
  564. package/dist/web/browse.d.ts.map +1 -1
  565. package/dist/web/browse.js +3 -1
  566. package/dist/web/browse.js.map +1 -1
  567. package/dist/web/fetch.d.ts.map +1 -1
  568. package/dist/web/fetch.js +3 -1
  569. package/dist/web/fetch.js.map +1 -1
  570. package/dist/web/sanitize.d.ts.map +1 -1
  571. package/dist/web/sanitize.js +2 -0
  572. package/dist/web/sanitize.js.map +1 -1
  573. package/dist/web/search.d.ts.map +1 -1
  574. package/dist/web/search.js +2 -0
  575. package/dist/web/search.js.map +1 -1
  576. package/install/install.ps1 +1 -1
  577. package/install/install.sh +2 -2
  578. package/package.json +5 -5
  579. package/scripts/bundle.js +2 -0
  580. package/scripts/copy-assets.js +2 -0
  581. package/scripts/link.sh +1 -0
  582. package/scripts/metrics.sh +2 -0
  583. package/scripts/postinstall.js +2 -0
@@ -3,7 +3,10 @@
3
3
  <head>
4
4
  <meta charset="utf-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1" />
6
- <title>Forge</title>
6
+ <meta name="theme-color" content="#000000" />
7
+ <meta name="description" content="Web site created using create-react-app" />
8
+ <meta name="author" content="Son Nguyen" />
9
+ <title>Forge - Dashboard UI</title>
7
10
  <link rel="preconnect" href="https://fonts.googleapis.com" />
8
11
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
9
12
  <link
@@ -16,6 +16,8 @@
16
16
  * blockquotes (>), horizontal rules (---), paragraphs.
17
17
  *
18
18
  * Kept in plain ES5-ish JS so the UI shell stays dependency-free.
19
+ *
20
+ * @author Son Nguyen <hoangson091104@gmail.com>
19
21
  */
20
22
  (function (root) {
21
23
  'use strict';
@@ -84,7 +86,7 @@
84
86
 
85
87
  const isBlockBoundary = (line) => {
86
88
  if (!line.trim()) return true;
87
- if (/^```+|^~~~+/.test(line)) return true;
89
+ if (/^\s*(?:```+|~~~+)/.test(line)) return true;
88
90
  if (/^#{1,6}\s/.test(line)) return true;
89
91
  if (BLOCKQUOTE_RE.test(line)) return true;
90
92
  if (/^\s*[-*+]\s+/.test(line)) return true;
@@ -93,10 +95,67 @@
93
95
  return false;
94
96
  };
95
97
 
98
+ // LLMs routinely emit `1. 1. 1.` for every item in a numbered list,
99
+ // trusting the renderer to auto-number. Our renderer strips the marker
100
+ // and emits `<ol>`, but if the items are separated by blank lines or
101
+ // sub-bullets, each run ends up as its own single-item `<ol>` — and the
102
+ // browser starts every one at 1. Pre-pass: per-indent counter that
103
+ // rewrites `1.` to sequential numbers whenever we're already past the
104
+ // first item at that indent. Mirrors src/cli/markdown.ts#renumberOrderedLists.
105
+ const renumberOrderedLists = (input) => {
106
+ const lines = input.split('\n');
107
+ const counters = new Map();
108
+ for (let i = 0; i < lines.length; i++) {
109
+ const line = lines[i];
110
+ if (/^\s*(?:#{1,6}\s|```+|~~~+)/.test(line)) {
111
+ counters.clear();
112
+ continue;
113
+ }
114
+ const m = /^(\s*)(\d+)\.\s(.*)$/.exec(line);
115
+ if (!m) continue;
116
+ const indent = m[1].length;
117
+ const num = parseInt(m[2], 10);
118
+ const body = m[3];
119
+ const prev = counters.get(indent) || 0;
120
+ if (num === 1 && prev >= 1) {
121
+ const next = prev + 1;
122
+ counters.set(indent, next);
123
+ lines[i] = m[1] + next + '. ' + body;
124
+ } else {
125
+ counters.set(indent, num);
126
+ }
127
+ }
128
+ return lines.join('\n');
129
+ };
130
+
131
+ // Smaller LLMs (and any model whose output gets re-flowed on its way to
132
+ // us) emit triple-backtick fences inline:
133
+ // ```javascript const numbers = [1,2,3]; numbers.forEach(...); ```
134
+ // The block parser's fence rule requires the opener to sit on its own
135
+ // line, so without preprocessing we fall through to the paragraph branch,
136
+ // and renderInline's `[^`\n]+` span then matches the body between two of
137
+ // the backticks — leaving a stray pair of backticks floating in the
138
+ // output. Rewriting inline fences onto their own lines (open / body /
139
+ // close) fixes both issues. Mirrors src/cli/markdown.ts#normaliseInlineFences.
140
+ const normaliseInlineFences = (input) => {
141
+ return input.replace(/```([\w-]*)[ \t]+([^\n]*?)[ \t]*```/g, (_m, lang, body) => {
142
+ const trimmed = String(body).replace(/\s+$/, '');
143
+ return '\n```' + lang + '\n' + trimmed + '\n```\n';
144
+ });
145
+ };
146
+
96
147
  /** Convert markdown input to a safe HTML fragment string. */
97
148
  const mdToHtml = (raw) => {
98
149
  if (raw == null || raw === '') return '';
99
- const escaped = esc(raw).replace(/\r\n?/g, '\n');
150
+ // Normalize inline fences BEFORE escaping — the regex matches literal
151
+ // backticks, not `&#96;`, and we want the rewritten newlines to survive
152
+ // into the line-based block parser. Renumber before splitting so the
153
+ // ordered-list loop below sees sequential numbers (and honors them via
154
+ // `<ol start="N">`).
155
+ const prepped = renumberOrderedLists(
156
+ normaliseInlineFences(String(raw).replace(/\r\n?/g, '\n')),
157
+ );
158
+ const escaped = esc(prepped);
100
159
  const lines = escaped.split('\n');
101
160
  const out = [];
102
161
  let i = 0;
@@ -105,17 +164,27 @@
105
164
  const line = lines[i];
106
165
 
107
166
  // Fenced code (```), optional language tag.
108
- const fence = /^(```+|~~~+)\s*([\w-]*)\s*$/.exec(line);
167
+ //
168
+ // LLMs routinely nest code blocks inside bullet / numbered lists so the
169
+ // fence arrives with 2–6 spaces of leading indent. Match liberally on
170
+ // whitespace prefix, and strip the same prefix from body lines so the
171
+ // code doesn't inherit the list indent as visible leading whitespace.
172
+ const fence = /^(\s*)(```+|~~~+)\s*([\w-]*)\s*$/.exec(line);
109
173
  if (fence) {
110
- const closer = fence[1].replace(/\s/g, '').charAt(0);
174
+ const openerIndent = fence[1].length;
175
+ const closer = fence[2].charAt(0);
176
+ const closerRe = new RegExp('^\\s*' + closer + '{3,}\\s*$');
111
177
  const buf = [];
112
178
  i++;
113
- while (i < lines.length && !new RegExp('^' + closer + '{3,}\\s*$').test(lines[i])) {
114
- buf.push(lines[i]);
179
+ while (i < lines.length && !closerRe.test(lines[i])) {
180
+ const raw = lines[i];
181
+ const leading = (raw.match(/^[ \t]*/) || [''])[0].length;
182
+ const strip = Math.min(openerIndent, leading);
183
+ buf.push(raw.slice(strip));
115
184
  i++;
116
185
  }
117
186
  if (i < lines.length) i++;
118
- const langAttr = fence[2] ? ' data-lang="' + esc(fence[2]) + '"' : '';
187
+ const langAttr = fence[3] ? ' data-lang="' + esc(fence[3]) + '"' : '';
119
188
  out.push(
120
189
  '<pre' + langAttr + '><code>' + buf.join('\n') + '</code></pre>',
121
190
  );
@@ -153,14 +222,40 @@
153
222
  continue;
154
223
  }
155
224
 
156
- // Ordered list
157
- if (/^\s*\d+\.\s+/.test(line)) {
225
+ // Ordered list. LLMs routinely separate items with blank lines —
226
+ // without the peek-past-blanks lookahead, each item became its own
227
+ // single-entry `<ol>` and every one rendered as "1." since browsers
228
+ // auto-number each `<ol>` from 1. Fix: consume blank lines between
229
+ // items as long as the next non-blank line is still a list item,
230
+ // and emit `start="N"` so the first number from source is honored.
231
+ const olHead = /^\s*(\d+)\.\s+/.exec(line);
232
+ if (olHead) {
233
+ const firstNum = parseInt(olHead[1], 10);
158
234
  const items = [];
159
- while (i < lines.length && /^\s*\d+\.\s+/.test(lines[i])) {
160
- items.push(lines[i].replace(/^\s*\d+\.\s+/, ''));
161
- i++;
235
+ while (i < lines.length) {
236
+ const cur = lines[i];
237
+ if (/^\s*\d+\.\s+/.test(cur)) {
238
+ items.push(cur.replace(/^\s*\d+\.\s+/, ''));
239
+ i++;
240
+ continue;
241
+ }
242
+ if (!cur.trim()) {
243
+ // Peek ahead past blank lines to see if more items follow.
244
+ let j = i + 1;
245
+ while (j < lines.length && !lines[j].trim()) j++;
246
+ if (j < lines.length && /^\s*\d+\.\s+/.test(lines[j])) {
247
+ i = j;
248
+ continue;
249
+ }
250
+ }
251
+ break;
162
252
  }
163
- out.push('<ol>' + items.map((it) => '<li>' + renderInline(it) + '</li>').join('') + '</ol>');
253
+ const startAttr = firstNum > 1 ? ` start="${firstNum}"` : '';
254
+ out.push(
255
+ '<ol' + startAttr + '>' +
256
+ items.map((it) => '<li>' + renderInline(it) + '</li>').join('') +
257
+ '</ol>',
258
+ );
164
259
  continue;
165
260
  }
166
261
 
@@ -1,4 +1,8 @@
1
- /* Forge dashboard — restrained palette, honest hierarchy, no gradient titles. */
1
+ /*
2
+ * Forge dashboard — restrained palette, honest hierarchy, no gradient titles.
3
+ *
4
+ * @author Son Nguyen <hoangson091104@gmail.com>
5
+ */
2
6
 
3
7
  :root {
4
8
  --bg: #0a0b0d;
@@ -421,6 +425,36 @@ html, body { overflow-x: hidden; }
421
425
  .hero-submit:hover { background: var(--accent-hi); }
422
426
  .hero-submit svg { width: 18px; height: 18px; }
423
427
 
428
+ .hero-project {
429
+ display: flex;
430
+ align-items: center;
431
+ gap: 8px;
432
+ max-width: 720px;
433
+ margin: 12px auto 0;
434
+ padding: 0 6px;
435
+ }
436
+ .hero-project-label {
437
+ font-size: 12px;
438
+ color: var(--dim);
439
+ flex: 0 0 auto;
440
+ }
441
+ .hero-cwd {
442
+ flex: 1 1 auto;
443
+ padding: 7px 11px;
444
+ background: var(--bg-1);
445
+ color: var(--fg);
446
+ border: 1px solid var(--border);
447
+ border-radius: 6px;
448
+ font: 12px/1.4 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
449
+ }
450
+ .hero-cwd:focus {
451
+ outline: none;
452
+ border-color: var(--accent);
453
+ box-shadow: 0 0 0 2px var(--accent-soft);
454
+ }
455
+ .hero-cwd::placeholder { color: var(--dim); }
456
+ .hero-project .btn { flex: 0 0 auto; padding: 6px 12px; font-size: 12px; }
457
+
424
458
  .hero-hint {
425
459
  color: var(--muted);
426
460
  font-size: 11.5px;
@@ -583,6 +617,13 @@ html, body { overflow-x: hidden; }
583
617
  .table tr:last-child td { border-bottom: none; }
584
618
  .table tbody tr { transition: background var(--tween); }
585
619
  .table tbody tr:hover { background: var(--surface-hi); cursor: default; }
620
+ .table tbody tr.row-clickable { cursor: pointer; }
621
+ .table tbody tr.row-clickable:hover {
622
+ background: var(--accent-soft);
623
+ }
624
+ .table tbody tr.row-clickable:active {
625
+ background: var(--surface-hi);
626
+ }
586
627
  .table th {
587
628
  color: var(--muted);
588
629
  font-weight: 600;
@@ -781,6 +822,22 @@ textarea {
781
822
  animation: fade-in 0.15s ease-out;
782
823
  white-space: pre-wrap;
783
824
  word-break: break-word;
825
+ display: flex;
826
+ align-items: flex-start;
827
+ gap: 10px;
828
+ }
829
+ .log-line .log-body {
830
+ flex: 1 1 auto;
831
+ min-width: 0;
832
+ }
833
+ .log-line .stream-head { margin-bottom: 4px; }
834
+ .log-line .log-ts {
835
+ flex: 0 0 auto;
836
+ color: var(--dim);
837
+ font-size: 10.5px;
838
+ font-variant-numeric: tabular-nums;
839
+ opacity: 0.75;
840
+ padding-top: 2px;
784
841
  }
785
842
  .log-line time {
786
843
  color: var(--dim);
@@ -791,6 +848,152 @@ textarea {
791
848
  .log-line.warning { color: var(--warn); }
792
849
  .log-line.error { color: var(--err); }
793
850
  .log-line.critical { color: var(--err); font-weight: 700; }
851
+ .log-line-stream {
852
+ border-left: 2px solid var(--accent);
853
+ padding-left: 10px;
854
+ color: var(--dim);
855
+ line-height: 1.45;
856
+ }
857
+ .log-line-stream .stream-text {
858
+ color: var(--fg);
859
+ white-space: normal;
860
+ word-break: break-word;
861
+ }
862
+ /* Live-streamed markdown inside a .stream-text span — same visual rules as
863
+ .log-md so the live reflow matches the final DONE render. Block-level
864
+ children (pre, ul, ol, h1-6) need proper spacing so partial renders
865
+ during streaming don't jump around as new tokens land. */
866
+ .log-line-stream .stream-text p { margin: 4px 0; }
867
+ .log-line-stream .stream-text pre {
868
+ background: rgba(0,0,0,0.3);
869
+ padding: 8px 10px;
870
+ border-radius: 4px;
871
+ overflow-x: auto;
872
+ font-size: 12px;
873
+ line-height: 1.45;
874
+ margin: 6px 0;
875
+ }
876
+ .log-line-stream .stream-text code {
877
+ background: rgba(0,0,0,0.35);
878
+ padding: 1px 4px;
879
+ border-radius: 3px;
880
+ font-size: 12px;
881
+ }
882
+ .log-line-stream .stream-text pre code { background: transparent; padding: 0; border: none; }
883
+ .log-line-stream .stream-text h1,
884
+ .log-line-stream .stream-text h2,
885
+ .log-line-stream .stream-text h3,
886
+ .log-line-stream .stream-text h4 { margin: 8px 0 4px; font-size: 13px; }
887
+ .log-line-stream .stream-text ul,
888
+ .log-line-stream .stream-text ol { margin: 4px 0; padding-left: 22px; }
889
+ .log-line-stream.log-line-done {
890
+ border-left-color: var(--border);
891
+ }
892
+ /* Live "working" indicator shown between STARTED and DONE, mirrors the
893
+ ora spinner the REPL/CLI emit. The braille glyph is swapped every 80ms
894
+ via JS; the CSS here just colors + positions. */
895
+ .log-line-working {
896
+ color: var(--dim);
897
+ }
898
+ .log-line-working .working-spinner {
899
+ color: var(--accent);
900
+ display: inline-block;
901
+ min-width: 1ch;
902
+ font-weight: 700;
903
+ }
904
+ .log-line-working .working-phase {
905
+ color: var(--fg);
906
+ }
907
+ /* Markdown emitted inside a log line — summary from DONE/FAILED. Block
908
+ markdown (code fences, lists, headings) gets its own indented card so
909
+ the label + body don't share a single line. */
910
+ .log-line .log-md {
911
+ margin-top: 6px;
912
+ padding: 8px 12px;
913
+ border-left: 2px solid var(--border);
914
+ background: rgba(255,255,255,0.02);
915
+ border-radius: 4px;
916
+ line-height: 1.5;
917
+ }
918
+ .log-line .log-md p { margin: 4px 0; }
919
+ .log-line .log-md pre {
920
+ background: rgba(0,0,0,0.3);
921
+ padding: 8px 10px;
922
+ border-radius: 4px;
923
+ overflow-x: auto;
924
+ font-size: 12px;
925
+ line-height: 1.45;
926
+ }
927
+ .log-line .log-md code {
928
+ background: rgba(0,0,0,0.35);
929
+ padding: 1px 4px;
930
+ border-radius: 3px;
931
+ font-size: 12px;
932
+ }
933
+ .log-line .log-md pre code { background: transparent; padding: 0; border: none; }
934
+ .log-line .log-md h1,
935
+ .log-line .log-md h2,
936
+ .log-line .log-md h3 { margin: 8px 0 4px; font-size: 13px; }
937
+ .log-line .log-md ul,
938
+ .log-line .log-md ol { margin: 4px 0; padding-left: 22px; }
939
+ .log-line .md-inline code {
940
+ background: rgba(0,0,0,0.35);
941
+ padding: 1px 4px;
942
+ border-radius: 3px;
943
+ font-size: 12px;
944
+ }
945
+
946
+ /* ---- Conversation follow-up input ---- */
947
+ .fu-input {
948
+ width: 100%;
949
+ resize: vertical;
950
+ min-height: 48px;
951
+ max-height: 260px;
952
+ padding: 10px 12px;
953
+ background: var(--bg-1);
954
+ color: var(--fg);
955
+ border: 1px solid var(--border);
956
+ border-radius: 8px;
957
+ font: 13.5px/1.45 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
958
+ }
959
+ .fu-input:focus {
960
+ outline: none;
961
+ border-color: var(--accent);
962
+ box-shadow: 0 0 0 2px var(--accent-soft);
963
+ }
964
+ .fu-input::placeholder {
965
+ color: var(--dim);
966
+ }
967
+ .fu-cwd {
968
+ flex: 1 1 auto;
969
+ padding: 6px 10px;
970
+ background: var(--bg-1);
971
+ color: var(--fg);
972
+ border: 1px solid var(--border);
973
+ border-radius: 6px;
974
+ font: 12px/1.4 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
975
+ }
976
+ .fu-cwd:focus {
977
+ outline: none;
978
+ border-color: var(--accent);
979
+ }
980
+ .fu-cwd::placeholder { color: var(--dim); }
981
+
982
+ /* ---- Directory picker modal ---- */
983
+ .dp-row {
984
+ display: flex;
985
+ align-items: center;
986
+ gap: 10px;
987
+ padding: 7px 12px;
988
+ cursor: pointer;
989
+ border-bottom: 1px solid var(--border);
990
+ font: 12.5px/1.4 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
991
+ color: var(--fg);
992
+ }
993
+ .dp-row:last-child { border-bottom: none; }
994
+ .dp-row:hover { background: var(--accent-soft); }
995
+ .dp-row .dp-icon { opacity: 0.7; flex: 0 0 auto; }
996
+ .dp-row .dp-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
794
997
 
795
998
  /* ---- Plan viewer ---- */
796
999
  .plan-viewer { display: flex; flex-direction: column; gap: 8px; padding: 16px 18px; }
@@ -996,6 +1199,18 @@ code {
996
1199
  font-size: 11.5px;
997
1200
  border: 1px solid var(--border);
998
1201
  }
1202
+ /* The global `code` rule above puts a 1px border + background on inline
1203
+ `<code>`. Inside a `<pre>` (fenced block) the `<code>` wraps multi-line
1204
+ text; because `<code>` is inline, each rendered line becomes its own
1205
+ line-box and each line-box gets its own top + bottom border — which
1206
+ shows up as thin horizontal lines between every code line. Strip the
1207
+ per-line chrome anywhere `<code>` lives inside a `<pre>`. */
1208
+ pre code {
1209
+ border: none !important;
1210
+ background: transparent !important;
1211
+ padding: 0 !important;
1212
+ border-radius: 0 !important;
1213
+ }
999
1214
 
1000
1215
  kbd {
1001
1216
  background: var(--bg-1);
@@ -1313,13 +1528,19 @@ kbd {
1313
1528
  background: var(--bg-1);
1314
1529
  border: 1px solid var(--border);
1315
1530
  border-radius: 10px;
1316
- padding: 10px 14px;
1531
+ padding: 8px 14px;
1317
1532
  max-width: min(780px, 74%);
1318
1533
  font-size: 13.5px;
1319
1534
  line-height: 1.5;
1320
1535
  color: var(--fg-1);
1321
- white-space: pre-wrap;
1322
1536
  word-break: break-word;
1537
+ /* NO `white-space: pre-wrap` here. The agent bubble receives
1538
+ pre-rendered HTML and the template literal that builds it has
1539
+ newlines + indentation between `<div class="chat-bubble-head">`,
1540
+ `${body}`, and `${files}` — `pre-wrap` rendered those as actual
1541
+ blank lines, producing huge empty gaps above and below the reply
1542
+ text. `pre-wrap` is only needed on the user bubble where the
1543
+ literal typed input might contain intentional newlines. */
1323
1544
  }
1324
1545
  .chat-msg-user .chat-bubble { border: none; white-space: pre-wrap; }
1325
1546
 
@@ -1336,6 +1557,13 @@ kbd {
1336
1557
  /* Markdown rendering in chat bubbles (both success and failure bodies) */
1337
1558
  .md p { margin: 0 0 8px; line-height: 1.55; }
1338
1559
  .md p:last-child { margin-bottom: 0; }
1560
+ /* Collapse top margin on the first block and bottom margin on the last
1561
+ block inside an .md container. The bubble already provides 10px vertical
1562
+ padding; without these resets the first heading/list added its own
1563
+ 10–12px top margin on top of that, making bot replies look padded by
1564
+ ~22px on the first line and ~18px after the last paragraph. */
1565
+ .md > *:first-child { margin-top: 0; }
1566
+ .md > *:last-child { margin-bottom: 0; }
1339
1567
  .md h1, .md h2, .md h3, .md h4, .md h5, .md h6 {
1340
1568
  margin: 12px 0 6px; font-weight: 700; line-height: 1.25; letter-spacing: -.01em;
1341
1569
  }
@@ -1356,7 +1584,7 @@ kbd {
1356
1584
  border-radius: 8px; padding: 10px 12px; margin: 8px 0;
1357
1585
  overflow-x: auto; font-size: .88em; line-height: 1.5;
1358
1586
  }
1359
- .md pre code { background: transparent; padding: 0; color: #e2e8f0; font-size: inherit; }
1587
+ .md pre code { background: transparent; padding: 0; color: #e2e8f0; font-size: inherit; border: none; }
1360
1588
  .md blockquote {
1361
1589
  border-left: 3px solid rgba(148, 163, 184, .4);
1362
1590
  padding: 2px 0 2px 10px; margin: 8px 0; color: var(--muted);
@@ -1,9 +1,11 @@
1
1
  /**
2
- * HTTP error normalisation for the UI server.
2
+ * HTTP error normalization for the UI server.
3
3
  *
4
4
  * Kept in its own tiny module so unit tests can exercise the mapping rules
5
5
  * without pulling in the entire server (which requires better-sqlite3,
6
6
  * WebSocket bindings, etc.).
7
+ *
8
+ * @author Son Nguyen <hoangson091104@gmail.com>
7
9
  */
8
10
  export interface HttpError {
9
11
  status: number;
@@ -1 +1 @@
1
- {"version":3,"file":"server-errors.d.ts","sourceRoot":"","sources":["../../src/ui/server-errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CACzB;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,SAAS,GAAI,GAAG,OAAO,KAAG,SAUtC,CAAC"}
1
+ {"version":3,"file":"server-errors.d.ts","sourceRoot":"","sources":["../../src/ui/server-errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CACzB;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,SAAS,GAAI,GAAG,OAAO,KAAG,SAUtC,CAAC"}
@@ -1,10 +1,12 @@
1
1
  "use strict";
2
2
  /**
3
- * HTTP error normalisation for the UI server.
3
+ * HTTP error normalization for the UI server.
4
4
  *
5
5
  * Kept in its own tiny module so unit tests can exercise the mapping rules
6
6
  * without pulling in the entire server (which requires better-sqlite3,
7
7
  * WebSocket bindings, etc.).
8
+ *
9
+ * @author Son Nguyen <hoangson091104@gmail.com>
8
10
  */
9
11
  Object.defineProperty(exports, "__esModule", { value: true });
10
12
  exports.errorBody = void 0;
@@ -1 +1 @@
1
- {"version":3,"file":"server-errors.js","sourceRoot":"","sources":["../../src/ui/server-errors.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;;AAOH;;;;;;;;GAQG;AACI,MAAM,SAAS,GAAG,CAAC,CAAU,EAAa,EAAE;IACjD,MAAM,GAAG,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IAC5C,MAAM,MAAM,GACV,OAAQ,CAA8B,CAAC,UAAU,KAAK,QAAQ;QAC5D,CAAC,CAAE,CAA4B,CAAC,UAAU;QAC1C,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC;YACzB,CAAC,CAAC,GAAG;YACL,CAAC,CAAC,GAAG,CAAC;IACZ,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC;AAC5C,CAAC,CAAC;AAVW,QAAA,SAAS,aAUpB"}
1
+ {"version":3,"file":"server-errors.js","sourceRoot":"","sources":["../../src/ui/server-errors.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAOH;;;;;;;;GAQG;AACI,MAAM,SAAS,GAAG,CAAC,CAAU,EAAa,EAAE;IACjD,MAAM,GAAG,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IAC5C,MAAM,MAAM,GACV,OAAQ,CAA8B,CAAC,UAAU,KAAK,QAAQ;QAC5D,CAAC,CAAE,CAA4B,CAAC,UAAU;QAC1C,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC;YACzB,CAAC,CAAC,GAAG;YACL,CAAC,CAAC,GAAG,CAAC;IACZ,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC;AAC5C,CAAC,CAAC;AAVW,QAAA,SAAS,aAUpB"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/ui/server.ts"],"names":[],"mappings":"AAqnBA,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,aAAa,GACxB,OAAM,eAAoB,KACzB,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CA4MrD,CAAC"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/ui/server.ts"],"names":[],"mappings":"AAgrBA,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,aAAa,GACxB,OAAM,eAAoB,KACzB,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CA4MrD,CAAC"}
package/dist/ui/server.js CHANGED
@@ -40,9 +40,12 @@ exports.startUiServer = void 0;
40
40
  * runs in-process so every CLI capability is reachable without shelling
41
41
  * out; this keeps UI-driven tasks under the same permission and sandbox
42
42
  * rules as CLI-driven tasks.
43
+ *
44
+ * @author Son Nguyen <hoangson091104@gmail.com>
43
45
  */
44
46
  const http = __importStar(require("http"));
45
47
  const fs = __importStar(require("fs"));
48
+ const os = __importStar(require("os"));
46
49
  const path = __importStar(require("path"));
47
50
  const url_1 = require("url");
48
51
  const ws_1 = require("ws");
@@ -168,6 +171,58 @@ const router = async (req, res, publicDir) => {
168
171
  if (p === '/api/projects') {
169
172
  return sendJson(res, 200, (0, index_db_1.listProjects)());
170
173
  }
174
+ // Directory browser for the task-view / run-form dir picker. Returns the
175
+ // resolved absolute path plus its immediate subdirectories. Confined to
176
+ // the user's home directory + common dev roots; anything outside is
177
+ // refused so the UI can't be used to enumerate system directories.
178
+ if (p === '/api/dir' && req.method === 'GET') {
179
+ try {
180
+ const homeDir = os.homedir();
181
+ const raw = u.searchParams.get('path') ?? homeDir;
182
+ // Expand a bare tilde or `~/...` the same way the task runner does.
183
+ let target = raw;
184
+ if (target === '~')
185
+ target = homeDir;
186
+ else if (target.startsWith('~/') || target.startsWith('~' + path.sep)) {
187
+ target = path.join(homeDir, target.slice(2));
188
+ }
189
+ const abs = path.resolve(target);
190
+ // Containment: only allow paths under $HOME. Users who genuinely need
191
+ // a non-home workspace can still paste an absolute path into the
192
+ // input itself — the picker just doesn't expose it.
193
+ const homeReal = fs.realpathSync(homeDir);
194
+ const absReal = fs.existsSync(abs) ? fs.realpathSync(abs) : abs;
195
+ const rel = path.relative(homeReal, absReal);
196
+ if (rel.startsWith('..') || path.isAbsolute(rel)) {
197
+ return sendJson(res, 403, { error: 'path outside $HOME', path: absReal });
198
+ }
199
+ let entries = [];
200
+ try {
201
+ entries = fs
202
+ .readdirSync(absReal, { withFileTypes: true })
203
+ .filter((d) => !d.name.startsWith('.'))
204
+ .map((d) => ({ name: d.name, isDir: d.isDirectory() }))
205
+ .filter((e) => e.isDir)
206
+ .sort((a, b) => a.name.localeCompare(b.name))
207
+ .slice(0, 500);
208
+ }
209
+ catch {
210
+ /* unreadable dir — return empty list, frontend shows "no entries" */
211
+ }
212
+ const parent = path.dirname(absReal);
213
+ const parentAllowed = !path.relative(homeReal, parent).startsWith('..');
214
+ return sendJson(res, 200, {
215
+ path: absReal,
216
+ parent: parentAllowed && parent !== absReal ? parent : null,
217
+ home: homeReal,
218
+ entries,
219
+ });
220
+ }
221
+ catch (e) {
222
+ const { status, body } = (0, server_errors_1.errorBody)(e);
223
+ return sendJson(res, status, body);
224
+ }
225
+ }
171
226
  if (p === '/api/config' && req.method === 'GET') {
172
227
  return sendJson(res, 200, (0, loader_1.loadGlobalConfig)());
173
228
  }
@@ -211,6 +266,11 @@ const router = async (req, res, publicDir) => {
211
266
  autoApprove: body.autoApprove,
212
267
  flags: body.flags,
213
268
  title: body.title,
269
+ // Composed multi-turn context from the UI's chat follow-up path.
270
+ // The orchestrator / conversation fast-path uses this so follow-up
271
+ // questions like "what did we just talk about?" resolve against
272
+ // actual prior turns rather than model hallucination.
273
+ description: body.description,
214
274
  });
215
275
  return sendJson(res, 202, reply);
216
276
  }
@@ -224,7 +284,7 @@ const router = async (req, res, publicDir) => {
224
284
  if (p === '/api/tasks/active' && req.method === 'GET') {
225
285
  return sendJson(res, 200, { active: (0, task_runner_1.listActive)(), pending: (0, task_runner_1.listPendingPrompts)() });
226
286
  }
227
- const cancelMatch = /^\/api\/tasks\/([a-f0-9]+)\/cancel$/.exec(p);
287
+ const cancelMatch = /^\/api\/tasks\/([a-z0-9_]+)\/cancel$/.exec(p);
228
288
  if (cancelMatch && req.method === 'POST') {
229
289
  const ok = (0, task_runner_1.cancelTask)(cancelMatch[1]);
230
290
  return sendJson(res, ok ? 200 : 404, { cancelled: ok });
@@ -651,7 +711,7 @@ const startUiServer = (opts = {}) => {
651
711
  const watchers = new Map();
652
712
  wss.on('connection', (socket, req) => {
653
713
  const u = new url_1.URL(req.url ?? '/', `http://${req.headers.host ?? 'localhost'}`);
654
- const taskMatch = /^\/ws\/tasks\/([a-f0-9]+)$/.exec(u.pathname);
714
+ const taskMatch = /^\/ws\/tasks\/([a-z0-9_]+)$/.exec(u.pathname);
655
715
  if (taskMatch) {
656
716
  const ok = (0, task_runner_1.subscribe)(taskMatch[1], socket);
657
717
  if (!ok) {