apex-code 0.0.1-alpha.8 → 0.0.4

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 (634) hide show
  1. package/CHANGELOG.md +231 -0
  2. package/README.md +9 -8
  3. package/dist/cli/args.d.ts +26 -1
  4. package/dist/cli/args.d.ts.map +1 -1
  5. package/dist/cli/args.js +72 -10
  6. package/dist/cli/args.js.map +1 -1
  7. package/dist/cli/file-processor.d.ts.map +1 -1
  8. package/dist/cli/file-processor.js +2 -1
  9. package/dist/cli/file-processor.js.map +1 -1
  10. package/dist/cli/mcp-command.d.ts +9 -0
  11. package/dist/cli/mcp-command.d.ts.map +1 -0
  12. package/dist/cli/mcp-command.js +53 -0
  13. package/dist/cli/mcp-command.js.map +1 -0
  14. package/dist/cli/project-trust.d.ts.map +1 -1
  15. package/dist/cli/project-trust.js +3 -1
  16. package/dist/cli/project-trust.js.map +1 -1
  17. package/dist/cli/startup-ui.d.ts.map +1 -1
  18. package/dist/cli/startup-ui.js +2 -1
  19. package/dist/cli/startup-ui.js.map +1 -1
  20. package/dist/cli.d.ts.map +1 -1
  21. package/dist/cli.js +94 -5
  22. package/dist/cli.js.map +1 -1
  23. package/dist/config.d.ts +3 -2
  24. package/dist/config.d.ts.map +1 -1
  25. package/dist/config.js +45 -18
  26. package/dist/config.js.map +1 -1
  27. package/dist/core/agent-session-services.d.ts +3 -0
  28. package/dist/core/agent-session-services.d.ts.map +1 -1
  29. package/dist/core/agent-session-services.js +1 -0
  30. package/dist/core/agent-session-services.js.map +1 -1
  31. package/dist/core/agent-session.d.ts +183 -15
  32. package/dist/core/agent-session.d.ts.map +1 -1
  33. package/dist/core/agent-session.js +728 -117
  34. package/dist/core/agent-session.js.map +1 -1
  35. package/dist/core/auth-storage.d.ts.map +1 -1
  36. package/dist/core/auth-storage.js +6 -7
  37. package/dist/core/auth-storage.js.map +1 -1
  38. package/dist/core/bash-executor.d.ts.map +1 -1
  39. package/dist/core/bash-executor.js +7 -0
  40. package/dist/core/bash-executor.js.map +1 -1
  41. package/dist/core/checkpoints/git-checkpoints.d.ts +39 -0
  42. package/dist/core/checkpoints/git-checkpoints.d.ts.map +1 -0
  43. package/dist/core/checkpoints/git-checkpoints.js +251 -0
  44. package/dist/core/checkpoints/git-checkpoints.js.map +1 -0
  45. package/dist/core/checkpoints/session-checkpoints.d.ts +23 -0
  46. package/dist/core/checkpoints/session-checkpoints.d.ts.map +1 -0
  47. package/dist/core/checkpoints/session-checkpoints.js +36 -0
  48. package/dist/core/checkpoints/session-checkpoints.js.map +1 -0
  49. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  50. package/dist/core/compaction/branch-summarization.js +7 -3
  51. package/dist/core/compaction/branch-summarization.js.map +1 -1
  52. package/dist/core/compaction/compaction.d.ts +9 -3
  53. package/dist/core/compaction/compaction.d.ts.map +1 -1
  54. package/dist/core/compaction/compaction.js +59 -36
  55. package/dist/core/compaction/compaction.js.map +1 -1
  56. package/dist/core/defaults.d.ts +1 -0
  57. package/dist/core/defaults.d.ts.map +1 -1
  58. package/dist/core/defaults.js +9 -0
  59. package/dist/core/defaults.js.map +1 -1
  60. package/dist/core/delegation/runtime.d.ts +6 -5
  61. package/dist/core/delegation/runtime.d.ts.map +1 -1
  62. package/dist/core/delegation/runtime.js +4 -3
  63. package/dist/core/delegation/runtime.js.map +1 -1
  64. package/dist/core/durable-state/sqlite.d.ts.map +1 -1
  65. package/dist/core/durable-state/sqlite.js +26 -2
  66. package/dist/core/durable-state/sqlite.js.map +1 -1
  67. package/dist/core/exec.d.ts.map +1 -1
  68. package/dist/core/exec.js +5 -2
  69. package/dist/core/exec.js.map +1 -1
  70. package/dist/core/extensions/index.d.ts +2 -2
  71. package/dist/core/extensions/index.d.ts.map +1 -1
  72. package/dist/core/extensions/index.js +1 -1
  73. package/dist/core/extensions/index.js.map +1 -1
  74. package/dist/core/extensions/loader.d.ts.map +1 -1
  75. package/dist/core/extensions/loader.js +123 -50
  76. package/dist/core/extensions/loader.js.map +1 -1
  77. package/dist/core/extensions/runner.d.ts +5 -0
  78. package/dist/core/extensions/runner.d.ts.map +1 -1
  79. package/dist/core/extensions/runner.js +45 -1
  80. package/dist/core/extensions/runner.js.map +1 -1
  81. package/dist/core/extensions/source-runtime.d.ts +14 -0
  82. package/dist/core/extensions/source-runtime.d.ts.map +1 -0
  83. package/dist/core/extensions/source-runtime.js +56 -0
  84. package/dist/core/extensions/source-runtime.js.map +1 -0
  85. package/dist/core/extensions/types.d.ts +60 -11
  86. package/dist/core/extensions/types.d.ts.map +1 -1
  87. package/dist/core/extensions/types.js +3 -0
  88. package/dist/core/extensions/types.js.map +1 -1
  89. package/dist/core/footer-data-provider.d.ts +1 -1
  90. package/dist/core/footer-data-provider.d.ts.map +1 -1
  91. package/dist/core/footer-data-provider.js +1 -1
  92. package/dist/core/footer-data-provider.js.map +1 -1
  93. package/dist/core/formatter-lifecycle.d.ts +69 -0
  94. package/dist/core/formatter-lifecycle.d.ts.map +1 -0
  95. package/dist/core/formatter-lifecycle.js +360 -0
  96. package/dist/core/formatter-lifecycle.js.map +1 -0
  97. package/dist/core/hooks/command-handler.d.ts +19 -0
  98. package/dist/core/hooks/command-handler.d.ts.map +1 -0
  99. package/dist/core/hooks/command-handler.js +112 -0
  100. package/dist/core/hooks/command-handler.js.map +1 -0
  101. package/dist/core/hooks/http-handler.d.ts +10 -0
  102. package/dist/core/hooks/http-handler.d.ts.map +1 -0
  103. package/dist/core/hooks/http-handler.js +36 -0
  104. package/dist/core/hooks/http-handler.js.map +1 -0
  105. package/dist/core/hooks/loader.d.ts +29 -0
  106. package/dist/core/hooks/loader.d.ts.map +1 -0
  107. package/dist/core/hooks/loader.js +139 -0
  108. package/dist/core/hooks/loader.js.map +1 -0
  109. package/dist/core/hooks/runtime.d.ts +13 -0
  110. package/dist/core/hooks/runtime.d.ts.map +1 -0
  111. package/dist/core/hooks/runtime.js +63 -0
  112. package/dist/core/hooks/runtime.js.map +1 -0
  113. package/dist/core/hooks/types.d.ts +83 -0
  114. package/dist/core/hooks/types.d.ts.map +1 -0
  115. package/dist/core/hooks/types.js +24 -0
  116. package/dist/core/hooks/types.js.map +1 -0
  117. package/dist/core/keybindings.d.ts +20 -19
  118. package/dist/core/keybindings.d.ts.map +1 -1
  119. package/dist/core/keybindings.js +26 -5
  120. package/dist/core/keybindings.js.map +1 -1
  121. package/dist/core/mcp/config.d.ts +16 -0
  122. package/dist/core/mcp/config.d.ts.map +1 -0
  123. package/dist/core/mcp/config.js +166 -0
  124. package/dist/core/mcp/config.js.map +1 -0
  125. package/dist/core/mcp/connector.d.ts +35 -0
  126. package/dist/core/mcp/connector.d.ts.map +1 -0
  127. package/dist/core/mcp/connector.js +105 -0
  128. package/dist/core/mcp/connector.js.map +1 -0
  129. package/dist/core/mcp/contract.d.ts +19 -0
  130. package/dist/core/mcp/contract.d.ts.map +1 -0
  131. package/dist/core/mcp/contract.js +89 -0
  132. package/dist/core/mcp/contract.js.map +1 -0
  133. package/dist/core/mcp/mcp-tool.d.ts +32 -0
  134. package/dist/core/mcp/mcp-tool.d.ts.map +1 -0
  135. package/dist/core/mcp/mcp-tool.js +171 -0
  136. package/dist/core/mcp/mcp-tool.js.map +1 -0
  137. package/dist/core/mcp/metadata-cache.d.ts +29 -0
  138. package/dist/core/mcp/metadata-cache.d.ts.map +1 -0
  139. package/dist/core/mcp/metadata-cache.js +99 -0
  140. package/dist/core/mcp/metadata-cache.js.map +1 -0
  141. package/dist/core/mcp/oauth/authorize.d.ts +21 -0
  142. package/dist/core/mcp/oauth/authorize.d.ts.map +1 -0
  143. package/dist/core/mcp/oauth/authorize.js +32 -0
  144. package/dist/core/mcp/oauth/authorize.js.map +1 -0
  145. package/dist/core/mcp/oauth/discover.d.ts +27 -0
  146. package/dist/core/mcp/oauth/discover.d.ts.map +1 -0
  147. package/dist/core/mcp/oauth/discover.js +116 -0
  148. package/dist/core/mcp/oauth/discover.js.map +1 -0
  149. package/dist/core/mcp/oauth/flow.d.ts +31 -0
  150. package/dist/core/mcp/oauth/flow.d.ts.map +1 -0
  151. package/dist/core/mcp/oauth/flow.js +175 -0
  152. package/dist/core/mcp/oauth/flow.js.map +1 -0
  153. package/dist/core/mcp/oauth/mcp-token.d.ts +51 -0
  154. package/dist/core/mcp/oauth/mcp-token.d.ts.map +1 -0
  155. package/dist/core/mcp/oauth/mcp-token.js +129 -0
  156. package/dist/core/mcp/oauth/mcp-token.js.map +1 -0
  157. package/dist/core/mcp/oauth/pkce.d.ts +12 -0
  158. package/dist/core/mcp/oauth/pkce.d.ts.map +1 -0
  159. package/dist/core/mcp/oauth/pkce.js +11 -0
  160. package/dist/core/mcp/oauth/pkce.js.map +1 -0
  161. package/dist/core/mcp/oauth/register.d.ts +16 -0
  162. package/dist/core/mcp/oauth/register.d.ts.map +1 -0
  163. package/dist/core/mcp/oauth/register.js +42 -0
  164. package/dist/core/mcp/oauth/register.js.map +1 -0
  165. package/dist/core/mcp/oauth/token-client.d.ts +33 -0
  166. package/dist/core/mcp/oauth/token-client.d.ts.map +1 -0
  167. package/dist/core/mcp/oauth/token-client.js +65 -0
  168. package/dist/core/mcp/oauth/token-client.js.map +1 -0
  169. package/dist/core/mcp/runtime.d.ts +20 -0
  170. package/dist/core/mcp/runtime.d.ts.map +1 -0
  171. package/dist/core/mcp/runtime.js +37 -0
  172. package/dist/core/mcp/runtime.js.map +1 -0
  173. package/dist/core/mcp/schema.d.ts +22 -0
  174. package/dist/core/mcp/schema.d.ts.map +1 -0
  175. package/dist/core/mcp/schema.js +20 -0
  176. package/dist/core/mcp/schema.js.map +1 -0
  177. package/dist/core/mcp/server-manager.d.ts +43 -0
  178. package/dist/core/mcp/server-manager.d.ts.map +1 -0
  179. package/dist/core/mcp/server-manager.js +142 -0
  180. package/dist/core/mcp/server-manager.js.map +1 -0
  181. package/dist/core/mcp/types.d.ts +100 -0
  182. package/dist/core/mcp/types.d.ts.map +1 -0
  183. package/dist/core/mcp/types.js +8 -0
  184. package/dist/core/mcp/types.js.map +1 -0
  185. package/dist/core/model-config.d.ts +5 -0
  186. package/dist/core/model-config.d.ts.map +1 -1
  187. package/dist/core/model-config.js +3 -1
  188. package/dist/core/model-config.js.map +1 -1
  189. package/dist/core/model-resolver.d.ts +1 -0
  190. package/dist/core/model-resolver.d.ts.map +1 -1
  191. package/dist/core/model-resolver.js +14 -8
  192. package/dist/core/model-resolver.js.map +1 -1
  193. package/dist/core/models-store.d.ts.map +1 -1
  194. package/dist/core/models-store.js +2 -1
  195. package/dist/core/models-store.js.map +1 -1
  196. package/dist/core/package-manager.d.ts.map +1 -1
  197. package/dist/core/package-manager.js +22 -14
  198. package/dist/core/package-manager.js.map +1 -1
  199. package/dist/core/permissions/gate.d.ts.map +1 -1
  200. package/dist/core/permissions/gate.js +45 -4
  201. package/dist/core/permissions/gate.js.map +1 -1
  202. package/dist/core/permissions/operations.d.ts +20 -0
  203. package/dist/core/permissions/operations.d.ts.map +1 -0
  204. package/dist/core/permissions/operations.js +9 -0
  205. package/dist/core/permissions/operations.js.map +1 -0
  206. package/dist/core/permissions/policy-command.d.ts +42 -0
  207. package/dist/core/permissions/policy-command.d.ts.map +1 -0
  208. package/dist/core/permissions/policy-command.js +44 -0
  209. package/dist/core/permissions/policy-command.js.map +1 -0
  210. package/dist/core/permissions/responder.d.ts +49 -2
  211. package/dist/core/permissions/responder.d.ts.map +1 -1
  212. package/dist/core/permissions/responder.js +20 -8
  213. package/dist/core/permissions/responder.js.map +1 -1
  214. package/dist/core/permissions/rules.d.ts.map +1 -1
  215. package/dist/core/permissions/rules.js +11 -1
  216. package/dist/core/permissions/rules.js.map +1 -1
  217. package/dist/core/permissions/store.d.ts +18 -0
  218. package/dist/core/permissions/store.d.ts.map +1 -1
  219. package/dist/core/permissions/store.js +89 -8
  220. package/dist/core/permissions/store.js.map +1 -1
  221. package/dist/core/pi-manifest.d.ts.map +1 -1
  222. package/dist/core/pi-manifest.js +2 -1
  223. package/dist/core/pi-manifest.js.map +1 -1
  224. package/dist/core/policy-executor.d.ts +47 -0
  225. package/dist/core/policy-executor.d.ts.map +1 -0
  226. package/dist/core/policy-executor.js +228 -0
  227. package/dist/core/policy-executor.js.map +1 -0
  228. package/dist/core/policy-loader.d.ts +72 -0
  229. package/dist/core/policy-loader.d.ts.map +1 -0
  230. package/dist/core/policy-loader.js +195 -0
  231. package/dist/core/policy-loader.js.map +1 -0
  232. package/dist/core/project-trust.d.ts +1 -1
  233. package/dist/core/project-trust.d.ts.map +1 -1
  234. package/dist/core/project-trust.js.map +1 -1
  235. package/dist/core/remote-catalog-provider.d.ts.map +1 -1
  236. package/dist/core/remote-catalog-provider.js +2 -1
  237. package/dist/core/remote-catalog-provider.js.map +1 -1
  238. package/dist/core/resource-loader.d.ts.map +1 -1
  239. package/dist/core/resource-loader.js +3 -2
  240. package/dist/core/resource-loader.js.map +1 -1
  241. package/dist/core/sandbox/bwrap-arguments.d.ts +41 -0
  242. package/dist/core/sandbox/bwrap-arguments.d.ts.map +1 -0
  243. package/dist/core/sandbox/bwrap-arguments.js +136 -0
  244. package/dist/core/sandbox/bwrap-arguments.js.map +1 -0
  245. package/dist/core/sandbox/child-entry.d.ts.map +1 -1
  246. package/dist/core/sandbox/child-entry.js +3 -1
  247. package/dist/core/sandbox/child-entry.js.map +1 -1
  248. package/dist/core/sandbox/cli-launch.d.ts +84 -4
  249. package/dist/core/sandbox/cli-launch.d.ts.map +1 -1
  250. package/dist/core/sandbox/cli-launch.js +115 -16
  251. package/dist/core/sandbox/cli-launch.js.map +1 -1
  252. package/dist/core/sandbox/cli-supervisor.d.ts +2 -0
  253. package/dist/core/sandbox/cli-supervisor.d.ts.map +1 -1
  254. package/dist/core/sandbox/cli-supervisor.js +50 -2
  255. package/dist/core/sandbox/cli-supervisor.js.map +1 -1
  256. package/dist/core/sandbox/full-access.d.ts +28 -0
  257. package/dist/core/sandbox/full-access.d.ts.map +1 -0
  258. package/dist/core/sandbox/full-access.js +63 -0
  259. package/dist/core/sandbox/full-access.js.map +1 -0
  260. package/dist/core/sandbox/git-identity.d.ts +57 -0
  261. package/dist/core/sandbox/git-identity.d.ts.map +1 -0
  262. package/dist/core/sandbox/git-identity.js +78 -0
  263. package/dist/core/sandbox/git-identity.js.map +1 -0
  264. package/dist/core/sandbox/host-approval.d.ts +42 -0
  265. package/dist/core/sandbox/host-approval.d.ts.map +1 -0
  266. package/dist/core/sandbox/host-approval.js +99 -0
  267. package/dist/core/sandbox/host-approval.js.map +1 -0
  268. package/dist/core/sandbox/linux-backend.d.ts +14 -0
  269. package/dist/core/sandbox/linux-backend.d.ts.map +1 -1
  270. package/dist/core/sandbox/linux-backend.js +158 -80
  271. package/dist/core/sandbox/linux-backend.js.map +1 -1
  272. package/dist/core/sandbox/macos-backend.d.ts +5 -0
  273. package/dist/core/sandbox/macos-backend.d.ts.map +1 -1
  274. package/dist/core/sandbox/macos-backend.js +164 -5
  275. package/dist/core/sandbox/macos-backend.js.map +1 -1
  276. package/dist/core/sandbox/network-proxy.d.ts +19 -0
  277. package/dist/core/sandbox/network-proxy.d.ts.map +1 -1
  278. package/dist/core/sandbox/network-proxy.js +93 -19
  279. package/dist/core/sandbox/network-proxy.js.map +1 -1
  280. package/dist/core/sandbox/policy.d.ts +8 -0
  281. package/dist/core/sandbox/policy.d.ts.map +1 -1
  282. package/dist/core/sandbox/policy.js +29 -12
  283. package/dist/core/sandbox/policy.js.map +1 -1
  284. package/dist/core/sandbox/profiles.d.ts +25 -0
  285. package/dist/core/sandbox/profiles.d.ts.map +1 -0
  286. package/dist/core/sandbox/profiles.js +23 -0
  287. package/dist/core/sandbox/profiles.js.map +1 -0
  288. package/dist/core/sandbox/rpc/command-client.d.ts +28 -0
  289. package/dist/core/sandbox/rpc/command-client.d.ts.map +1 -0
  290. package/dist/core/sandbox/rpc/command-client.js +86 -0
  291. package/dist/core/sandbox/rpc/command-client.js.map +1 -0
  292. package/dist/core/sandbox/rpc/command-proxy.d.ts +48 -0
  293. package/dist/core/sandbox/rpc/command-proxy.d.ts.map +1 -0
  294. package/dist/core/sandbox/rpc/command-proxy.js +120 -0
  295. package/dist/core/sandbox/rpc/command-proxy.js.map +1 -0
  296. package/dist/core/sandbox/rpc/credential-proxy.d.ts.map +1 -1
  297. package/dist/core/sandbox/rpc/credential-proxy.js +2 -96
  298. package/dist/core/sandbox/rpc/credential-proxy.js.map +1 -1
  299. package/dist/core/sandbox/rpc/framing.d.ts +35 -0
  300. package/dist/core/sandbox/rpc/framing.d.ts.map +1 -0
  301. package/dist/core/sandbox/rpc/framing.js +114 -0
  302. package/dist/core/sandbox/rpc/framing.js.map +1 -0
  303. package/dist/core/sandbox/rpc/git-credential-helper.d.ts +47 -0
  304. package/dist/core/sandbox/rpc/git-credential-helper.d.ts.map +1 -0
  305. package/dist/core/sandbox/rpc/git-credential-helper.js +222 -0
  306. package/dist/core/sandbox/rpc/git-credential-helper.js.map +1 -0
  307. package/dist/core/sandbox/rpc/git-credential-proxy.d.ts +66 -0
  308. package/dist/core/sandbox/rpc/git-credential-proxy.d.ts.map +1 -0
  309. package/dist/core/sandbox/rpc/git-credential-proxy.js +209 -0
  310. package/dist/core/sandbox/rpc/git-credential-proxy.js.map +1 -0
  311. package/dist/core/sandbox/supervisor-temp.d.ts +18 -0
  312. package/dist/core/sandbox/supervisor-temp.d.ts.map +1 -0
  313. package/dist/core/sandbox/supervisor-temp.js +21 -0
  314. package/dist/core/sandbox/supervisor-temp.js.map +1 -0
  315. package/dist/core/sandbox/supervisor.d.ts +12 -1
  316. package/dist/core/sandbox/supervisor.d.ts.map +1 -1
  317. package/dist/core/sandbox/supervisor.js +15 -1
  318. package/dist/core/sandbox/supervisor.js.map +1 -1
  319. package/dist/core/sandbox/terminal-handoff.d.ts +68 -0
  320. package/dist/core/sandbox/terminal-handoff.d.ts.map +1 -0
  321. package/dist/core/sandbox/terminal-handoff.js +221 -0
  322. package/dist/core/sandbox/terminal-handoff.js.map +1 -0
  323. package/dist/core/sandbox/terminal-size.d.ts +13 -0
  324. package/dist/core/sandbox/terminal-size.d.ts.map +1 -1
  325. package/dist/core/sandbox/terminal-size.js +23 -2
  326. package/dist/core/sandbox/terminal-size.js.map +1 -1
  327. package/dist/core/sdk.d.ts +24 -2
  328. package/dist/core/sdk.d.ts.map +1 -1
  329. package/dist/core/sdk.js +63 -4
  330. package/dist/core/sdk.js.map +1 -1
  331. package/dist/core/session-export.d.ts +4 -0
  332. package/dist/core/session-export.d.ts.map +1 -0
  333. package/dist/core/session-export.js +32 -0
  334. package/dist/core/session-export.js.map +1 -0
  335. package/dist/core/session-manager.d.ts +13 -1
  336. package/dist/core/session-manager.d.ts.map +1 -1
  337. package/dist/core/session-manager.js +34 -6
  338. package/dist/core/session-manager.js.map +1 -1
  339. package/dist/core/settings-diagnostics.d.ts +9 -0
  340. package/dist/core/settings-diagnostics.d.ts.map +1 -0
  341. package/dist/core/settings-diagnostics.js +21 -0
  342. package/dist/core/settings-diagnostics.js.map +1 -0
  343. package/dist/core/settings-manager.d.ts +172 -1
  344. package/dist/core/settings-manager.d.ts.map +1 -1
  345. package/dist/core/settings-manager.js +160 -11
  346. package/dist/core/settings-manager.js.map +1 -1
  347. package/dist/core/skills.d.ts.map +1 -1
  348. package/dist/core/skills.js +51 -33
  349. package/dist/core/skills.js.map +1 -1
  350. package/dist/core/slash-commands.d.ts.map +1 -1
  351. package/dist/core/slash-commands.js +4 -1
  352. package/dist/core/slash-commands.js.map +1 -1
  353. package/dist/core/system-prompt.d.ts.map +1 -1
  354. package/dist/core/system-prompt.js +8 -2
  355. package/dist/core/system-prompt.js.map +1 -1
  356. package/dist/core/tools/background-shell.d.ts +39 -0
  357. package/dist/core/tools/background-shell.d.ts.map +1 -0
  358. package/dist/core/tools/background-shell.js +81 -0
  359. package/dist/core/tools/background-shell.js.map +1 -0
  360. package/dist/core/tools/bash-command-segments.d.ts.map +1 -1
  361. package/dist/core/tools/bash-command-segments.js +2 -0
  362. package/dist/core/tools/bash-command-segments.js.map +1 -1
  363. package/dist/core/tools/bash.d.ts +44 -16
  364. package/dist/core/tools/bash.d.ts.map +1 -1
  365. package/dist/core/tools/bash.js +264 -32
  366. package/dist/core/tools/bash.js.map +1 -1
  367. package/dist/core/tools/contract-snapshot.d.ts +58 -0
  368. package/dist/core/tools/contract-snapshot.d.ts.map +1 -0
  369. package/dist/core/tools/contract-snapshot.js +51 -0
  370. package/dist/core/tools/contract-snapshot.js.map +1 -0
  371. package/dist/core/tools/contract.d.ts +53 -5
  372. package/dist/core/tools/contract.d.ts.map +1 -1
  373. package/dist/core/tools/contract.js +22 -2
  374. package/dist/core/tools/contract.js.map +1 -1
  375. package/dist/core/tools/delegate.d.ts +6 -4
  376. package/dist/core/tools/delegate.d.ts.map +1 -1
  377. package/dist/core/tools/delegate.js +21 -11
  378. package/dist/core/tools/delegate.js.map +1 -1
  379. package/dist/core/tools/edit-diff.d.ts +48 -5
  380. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  381. package/dist/core/tools/edit-diff.js +217 -8
  382. package/dist/core/tools/edit-diff.js.map +1 -1
  383. package/dist/core/tools/edit.d.ts +8 -0
  384. package/dist/core/tools/edit.d.ts.map +1 -1
  385. package/dist/core/tools/edit.js +72 -10
  386. package/dist/core/tools/edit.js.map +1 -1
  387. package/dist/core/tools/find.d.ts.map +1 -1
  388. package/dist/core/tools/find.js +5 -2
  389. package/dist/core/tools/find.js.map +1 -1
  390. package/dist/core/tools/grep.d.ts.map +1 -1
  391. package/dist/core/tools/grep.js +5 -2
  392. package/dist/core/tools/grep.js.map +1 -1
  393. package/dist/core/tools/index.d.ts +14 -2
  394. package/dist/core/tools/index.d.ts.map +1 -1
  395. package/dist/core/tools/index.js +12 -0
  396. package/dist/core/tools/index.js.map +1 -1
  397. package/dist/core/tools/ls.d.ts.map +1 -1
  398. package/dist/core/tools/ls.js +5 -2
  399. package/dist/core/tools/ls.js.map +1 -1
  400. package/dist/core/tools/lsp.d.ts +19 -1
  401. package/dist/core/tools/lsp.d.ts.map +1 -1
  402. package/dist/core/tools/lsp.js +163 -10
  403. package/dist/core/tools/lsp.js.map +1 -1
  404. package/dist/core/tools/path-permission.d.ts +3 -0
  405. package/dist/core/tools/path-permission.d.ts.map +1 -1
  406. package/dist/core/tools/path-permission.js +16 -4
  407. package/dist/core/tools/path-permission.js.map +1 -1
  408. package/dist/core/tools/path-utils.d.ts +27 -2
  409. package/dist/core/tools/path-utils.d.ts.map +1 -1
  410. package/dist/core/tools/path-utils.js +221 -4
  411. package/dist/core/tools/path-utils.js.map +1 -1
  412. package/dist/core/tools/powershell.d.ts +16 -0
  413. package/dist/core/tools/powershell.d.ts.map +1 -0
  414. package/dist/core/tools/powershell.js +39 -0
  415. package/dist/core/tools/powershell.js.map +1 -0
  416. package/dist/core/tools/read.d.ts.map +1 -1
  417. package/dist/core/tools/read.js +20 -11
  418. package/dist/core/tools/read.js.map +1 -1
  419. package/dist/core/tools/test.d.ts +54 -9
  420. package/dist/core/tools/test.d.ts.map +1 -1
  421. package/dist/core/tools/test.js +239 -19
  422. package/dist/core/tools/test.js.map +1 -1
  423. package/dist/core/tools/write.d.ts +7 -0
  424. package/dist/core/tools/write.d.ts.map +1 -1
  425. package/dist/core/tools/write.js +64 -9
  426. package/dist/core/tools/write.js.map +1 -1
  427. package/dist/core/trust-manager.d.ts.map +1 -1
  428. package/dist/core/trust-manager.js +2 -1
  429. package/dist/core/trust-manager.js.map +1 -1
  430. package/dist/core/verification-lifecycle.d.ts +77 -0
  431. package/dist/core/verification-lifecycle.d.ts.map +1 -0
  432. package/dist/core/verification-lifecycle.js +146 -0
  433. package/dist/core/verification-lifecycle.js.map +1 -0
  434. package/dist/core/workspace/artifacts.d.ts +45 -0
  435. package/dist/core/workspace/artifacts.d.ts.map +1 -0
  436. package/dist/core/workspace/artifacts.js +165 -0
  437. package/dist/core/workspace/artifacts.js.map +1 -0
  438. package/dist/core/workspace/comparison.d.ts +27 -0
  439. package/dist/core/workspace/comparison.d.ts.map +1 -0
  440. package/dist/core/workspace/comparison.js +94 -0
  441. package/dist/core/workspace/comparison.js.map +1 -0
  442. package/dist/core/workspace/git-observer.d.ts +48 -0
  443. package/dist/core/workspace/git-observer.d.ts.map +1 -0
  444. package/dist/core/workspace/git-observer.js +346 -0
  445. package/dist/core/workspace/git-observer.js.map +1 -0
  446. package/dist/core/workspace/projection.d.ts +3 -0
  447. package/dist/core/workspace/projection.d.ts.map +1 -0
  448. package/dist/core/workspace/projection.js +56 -0
  449. package/dist/core/workspace/projection.js.map +1 -0
  450. package/dist/core/workspace/state.d.ts +133 -0
  451. package/dist/core/workspace/state.d.ts.map +1 -0
  452. package/dist/core/workspace/state.js +96 -0
  453. package/dist/core/workspace/state.js.map +1 -0
  454. package/dist/extensions/llama/client.d.ts +6 -0
  455. package/dist/extensions/llama/client.d.ts.map +1 -1
  456. package/dist/extensions/llama/client.js +7 -0
  457. package/dist/extensions/llama/client.js.map +1 -1
  458. package/dist/extensions/llama/index.d.ts.map +1 -1
  459. package/dist/extensions/llama/index.js +2 -0
  460. package/dist/extensions/llama/index.js.map +1 -1
  461. package/dist/extensions/llama/provider.d.ts +3 -1
  462. package/dist/extensions/llama/provider.d.ts.map +1 -1
  463. package/dist/extensions/llama/provider.js +29 -4
  464. package/dist/extensions/llama/provider.js.map +1 -1
  465. package/dist/index.d.ts +8 -5
  466. package/dist/index.d.ts.map +1 -1
  467. package/dist/index.js +7 -4
  468. package/dist/index.js.map +1 -1
  469. package/dist/main.d.ts +6 -0
  470. package/dist/main.d.ts.map +1 -1
  471. package/dist/main.js +58 -23
  472. package/dist/main.js.map +1 -1
  473. package/dist/migrations.d.ts.map +1 -1
  474. package/dist/migrations.js +4 -3
  475. package/dist/migrations.js.map +1 -1
  476. package/dist/modes/acp/server.d.ts +55 -0
  477. package/dist/modes/acp/server.d.ts.map +1 -0
  478. package/dist/modes/acp/server.js +244 -0
  479. package/dist/modes/acp/server.js.map +1 -0
  480. package/dist/modes/acp/translate.d.ts +37 -0
  481. package/dist/modes/acp/translate.d.ts.map +1 -0
  482. package/dist/modes/acp/translate.js +50 -0
  483. package/dist/modes/acp/translate.js.map +1 -0
  484. package/dist/modes/index.d.ts +1 -0
  485. package/dist/modes/index.d.ts.map +1 -1
  486. package/dist/modes/index.js +1 -0
  487. package/dist/modes/index.js.map +1 -1
  488. package/dist/modes/interactive/components/assistant-message.d.ts +29 -0
  489. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  490. package/dist/modes/interactive/components/assistant-message.js +182 -23
  491. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  492. package/dist/modes/interactive/components/bash-execution.d.ts +7 -0
  493. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  494. package/dist/modes/interactive/components/bash-execution.js +20 -0
  495. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  496. package/dist/modes/interactive/components/custom-editor.d.ts +9 -4
  497. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  498. package/dist/modes/interactive/components/custom-editor.js +20 -9
  499. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  500. package/dist/modes/interactive/components/extension-selector.d.ts +7 -1
  501. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  502. package/dist/modes/interactive/components/extension-selector.js +7 -3
  503. package/dist/modes/interactive/components/extension-selector.js.map +1 -1
  504. package/dist/modes/interactive/components/footer.d.ts +19 -0
  505. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  506. package/dist/modes/interactive/components/footer.js +70 -10
  507. package/dist/modes/interactive/components/footer.js.map +1 -1
  508. package/dist/modes/interactive/components/model-selector.d.ts +10 -3
  509. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  510. package/dist/modes/interactive/components/model-selector.js +56 -14
  511. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  512. package/dist/modes/interactive/components/permission-preview.d.ts +15 -0
  513. package/dist/modes/interactive/components/permission-preview.d.ts.map +1 -0
  514. package/dist/modes/interactive/components/permission-preview.js +33 -0
  515. package/dist/modes/interactive/components/permission-preview.js.map +1 -0
  516. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  517. package/dist/modes/interactive/components/session-selector.js +2 -2
  518. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  519. package/dist/modes/interactive/components/settings-selector.d.ts +9 -2
  520. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  521. package/dist/modes/interactive/components/settings-selector.js +128 -56
  522. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  523. package/dist/modes/interactive/components/settings-submenu.d.ts +72 -0
  524. package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -0
  525. package/dist/modes/interactive/components/settings-submenu.js +165 -0
  526. package/dist/modes/interactive/components/settings-submenu.js.map +1 -0
  527. package/dist/modes/interactive/components/thinking-selector.d.ts +15 -3
  528. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  529. package/dist/modes/interactive/components/thinking-selector.js +74 -17
  530. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  531. package/dist/modes/interactive/components/tool-execution.d.ts +23 -1
  532. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  533. package/dist/modes/interactive/components/tool-execution.js +64 -10
  534. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  535. package/dist/modes/interactive/external-editor.d.ts.map +1 -1
  536. package/dist/modes/interactive/external-editor.js +2 -1
  537. package/dist/modes/interactive/external-editor.js.map +1 -1
  538. package/dist/modes/interactive/interactive-mode.d.ts +45 -0
  539. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  540. package/dist/modes/interactive/interactive-mode.js +395 -43
  541. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  542. package/dist/modes/interactive/theme/theme.d.ts +12 -0
  543. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  544. package/dist/modes/interactive/theme/theme.js +20 -9
  545. package/dist/modes/interactive/theme/theme.js.map +1 -1
  546. package/dist/modes/json-event.d.ts +16 -13
  547. package/dist/modes/json-event.d.ts.map +1 -1
  548. package/dist/modes/json-event.js +20 -6
  549. package/dist/modes/json-event.js.map +1 -1
  550. package/dist/modes/print-mode.d.ts.map +1 -1
  551. package/dist/modes/print-mode.js +27 -12
  552. package/dist/modes/print-mode.js.map +1 -1
  553. package/dist/modes/rpc/rpc-client.d.ts +7 -0
  554. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  555. package/dist/modes/rpc/rpc-client.js +7 -0
  556. package/dist/modes/rpc/rpc-client.js.map +1 -1
  557. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  558. package/dist/modes/rpc/rpc-mode.js +3 -0
  559. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  560. package/dist/modes/rpc/rpc-types.d.ts +12 -0
  561. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  562. package/dist/modes/rpc/rpc-types.js.map +1 -1
  563. package/dist/package-manager-cli.d.ts +1 -0
  564. package/dist/package-manager-cli.d.ts.map +1 -1
  565. package/dist/package-manager-cli.js +196 -10
  566. package/dist/package-manager-cli.js.map +1 -1
  567. package/dist/utils/frontmatter.d.ts.map +1 -1
  568. package/dist/utils/frontmatter.js +2 -1
  569. package/dist/utils/frontmatter.js.map +1 -1
  570. package/dist/utils/management-http.d.ts +5 -3
  571. package/dist/utils/management-http.d.ts.map +1 -1
  572. package/dist/utils/management-http.js +14 -10
  573. package/dist/utils/management-http.js.map +1 -1
  574. package/dist/utils/shell.d.ts +3 -0
  575. package/dist/utils/shell.d.ts.map +1 -1
  576. package/dist/utils/shell.js +23 -9
  577. package/dist/utils/shell.js.map +1 -1
  578. package/dist/utils/syntax-highlight.d.ts +1 -0
  579. package/dist/utils/syntax-highlight.d.ts.map +1 -1
  580. package/dist/utils/syntax-highlight.js +60 -1
  581. package/dist/utils/syntax-highlight.js.map +1 -1
  582. package/dist/utils/text.d.ts +8 -0
  583. package/dist/utils/text.d.ts.map +1 -0
  584. package/dist/utils/text.js +9 -0
  585. package/dist/utils/text.js.map +1 -0
  586. package/dist/utils/version-check.d.ts.map +1 -1
  587. package/dist/utils/version-check.js +6 -4
  588. package/dist/utils/version-check.js.map +1 -1
  589. package/docs/compaction.md +19 -0
  590. package/docs/custom-provider.md +12 -9
  591. package/docs/environment-variables.md +1 -1
  592. package/docs/extensions.md +35 -7
  593. package/docs/json.md +7 -2
  594. package/docs/keybindings.md +9 -9
  595. package/docs/llama-cpp.md +2 -0
  596. package/docs/models.md +8 -2
  597. package/docs/packages.md +2 -2
  598. package/docs/quickstart.md +1 -1
  599. package/docs/rpc.md +32 -3
  600. package/docs/sdk.md +32 -2
  601. package/docs/settings.md +23 -7
  602. package/docs/skills.md +4 -3
  603. package/docs/terminal-setup.md +23 -7
  604. package/docs/usage.md +10 -5
  605. package/docs/windows.md +24 -2
  606. package/examples/extensions/border-status-editor.ts +1 -1
  607. package/examples/extensions/built-in-tool-renderer.ts +8 -4
  608. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  609. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  610. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  611. package/examples/extensions/git-checkpoint.ts +24 -36
  612. package/examples/extensions/gondolin/package-lock.json +2 -2
  613. package/examples/extensions/gondolin/package.json +1 -1
  614. package/examples/extensions/minimal-mode.ts +2 -2
  615. package/examples/extensions/notify.ts +3 -1
  616. package/examples/extensions/permission-gate.ts +1 -1
  617. package/examples/extensions/plan-mode/index.ts +1 -1
  618. package/examples/extensions/rpc-demo.ts +1 -1
  619. package/examples/extensions/sandbox/package-lock.json +2 -2
  620. package/examples/extensions/sandbox/package.json +1 -1
  621. package/examples/extensions/subagent/README.md +1 -1
  622. package/examples/extensions/subagent/index.ts +6 -1
  623. package/examples/extensions/titlebar-spinner.ts +1 -1
  624. package/examples/extensions/with-deps/package-lock.json +2 -2
  625. package/examples/extensions/with-deps/package.json +1 -1
  626. package/examples/rpc-extension-ui.ts +1 -1
  627. package/examples/sdk/06-extensions.ts +1 -1
  628. package/examples/sdk/README.md +1 -1
  629. package/npm-shrinkwrap.json +439 -405
  630. package/package.json +17 -17
  631. package/dist/server/create-harness.d.ts +0 -26
  632. package/dist/server/create-harness.d.ts.map +0 -1
  633. package/dist/server/create-harness.js +0 -107
  634. package/dist/server/create-harness.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"startup-ui.js","sourceRoot":"","sources":["../../src/cli/startup-ui.ts"],"names":[],"mappings":"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","sourcesContent":["import { ProcessTerminal, setKeybindings, type TUI, TuiMainScreen } from \"@earendil-works/pi-tui\";\nimport { existsSync } from \"fs\";\nimport { APP_NAME, CONFIG_DIR_NAME, ENV_AGENT_DIR, getAgentDir, getSettingsPath, PACKAGE_NAME } from \"../config.ts\";\nimport { areExperimentalFeaturesEnabled } from \"../core/experimental.ts\";\nimport { KeybindingsManager } from \"../core/keybindings.ts\";\nimport { DefaultPackageManager, type ResolvedResource } from \"../core/package-manager.ts\";\nimport { SettingsManager } from \"../core/settings-manager.ts\";\nimport { ExtensionInputComponent } from \"../modes/interactive/components/extension-input.ts\";\nimport { ExtensionSelectorComponent } from \"../modes/interactive/components/extension-selector.ts\";\nimport {\n\tFirstTimeSetupComponent,\n\ttype FirstTimeSetupResult,\n} from \"../modes/interactive/components/first-time-setup.ts\";\nimport {\n\tdetectTerminalBackgroundFromEnv,\n\tdetectTerminalThemeForAuto,\n\tinitTheme,\n\tloadThemeFromPath,\n\tparseAutoThemeSetting,\n\tresolveThemeSetting,\n\tsetRegisteredThemes,\n\tsetTheme,\n\ttype Theme,\n} from \"../modes/interactive/theme/theme.ts\";\n\nconst OFFICIAL_PACKAGE_NAME = \"apex-code\";\nconst OFFICIAL_APP_NAME = \"apex-code\";\nconst OFFICIAL_CONFIG_DIR_NAME = \".apex-code\";\n\ninterface DistributionMetadata {\n\tpackageName: string;\n\tappName: string;\n\tconfigDirName: string;\n}\n\nfunction isOfficialDistribution({ packageName, appName, configDirName }: DistributionMetadata): boolean {\n\treturn (\n\t\tpackageName === OFFICIAL_PACKAGE_NAME &&\n\t\tappName === OFFICIAL_APP_NAME &&\n\t\tconfigDirName === OFFICIAL_CONFIG_DIR_NAME\n\t);\n}\n\nfunction loadThemes(resources: ResolvedResource[]): Theme[] {\n\tconst themes: Theme[] = [];\n\tconst seen = new Set<string>();\n\tfor (const resource of resources) {\n\t\tif (!resource.enabled) continue;\n\t\ttry {\n\t\t\tconst loadedTheme = loadThemeFromPath(resource.path);\n\t\t\tif (loadedTheme.name) {\n\t\t\t\tif (seen.has(loadedTheme.name)) continue;\n\t\t\t\tseen.add(loadedTheme.name);\n\t\t\t}\n\t\t\tthemes.push(loadedTheme);\n\t\t} catch {\n\t\t\t// Startup prompts should not fail because a theme is broken. The normal\n\t\t\t// resource loader reports theme diagnostics later in startup.\n\t\t}\n\t}\n\treturn themes;\n}\n\nasync function loadStartupThemes(settingsManager: SettingsManager): Promise<Theme[]> {\n\tconst globalSettingsManager = SettingsManager.inMemory(settingsManager.getGlobalSettings(), {\n\t\tprojectTrusted: false,\n\t});\n\tconst packageManager = new DefaultPackageManager({\n\t\tcwd: process.cwd(),\n\t\tagentDir: getAgentDir(),\n\t\tsettingsManager: globalSettingsManager,\n\t});\n\tconst resolvedPaths = await packageManager.resolve(async () => \"skip\");\n\treturn loadThemes(resolvedPaths.themes);\n}\n\nexport async function createStartupTui(settingsManager: SettingsManager): Promise<TUI> {\n\tsetRegisteredThemes(await loadStartupThemes(settingsManager));\n\tconst terminalTheme = detectTerminalBackgroundFromEnv().theme;\n\tinitTheme(resolveThemeSetting(settingsManager.getThemeSetting(), terminalTheme) ?? terminalTheme);\n\tsetKeybindings(KeybindingsManager.create());\n\tconst ui: TUI = new TuiMainScreen(new ProcessTerminal(), settingsManager.getShowHardwareCursor(), getAgentDir());\n\tui.setClearOnShrink(settingsManager.getClearOnShrink());\n\treturn ui;\n}\n\nexport function startStartupTui(ui: TUI, settingsManager: SettingsManager): void {\n\tui.start();\n\tvoid applyDetectedStartupTheme(ui, settingsManager);\n}\n\nasync function applyDetectedStartupTheme(ui: TUI, settingsManager: SettingsManager): Promise<void> {\n\tconst themeSetting = settingsManager.getThemeSetting();\n\tif (themeSetting && !parseAutoThemeSetting(themeSetting)) return;\n\n\tconst terminalTheme = await detectTerminalThemeForAuto({ ui, timeoutMs: 100 });\n\tsetTheme(resolveThemeSetting(themeSetting, terminalTheme) ?? terminalTheme);\n\tui.invalidate();\n\tui.requestRender();\n}\n\nasync function clearStartupTui(ui: TUI): Promise<void> {\n\tui.clear();\n\tui.requestRender();\n\tawait new Promise((resolve) => setTimeout(resolve, 25));\n}\n\n/**\n * First-time setup runs when all of these hold:\n * - this is the official Pi distribution (not a fork/rebrand)\n * - experimental features are enabled (APEX_CODE_EXPERIMENTAL=1)\n * - the default agent directory is used (no custom agent dir override)\n * - setup was not completed before (settings.json does not exist)\n */\nexport function shouldRunFirstTimeSetup(settingsPath: string = getSettingsPath()): boolean {\n\tif (\n\t\t!isOfficialDistribution({\n\t\t\tpackageName: PACKAGE_NAME,\n\t\t\tappName: APP_NAME,\n\t\t\tconfigDirName: CONFIG_DIR_NAME,\n\t\t})\n\t) {\n\t\treturn false;\n\t}\n\tif (!areExperimentalFeaturesEnabled()) {\n\t\treturn false;\n\t}\n\tif (process.env[ENV_AGENT_DIR]) {\n\t\treturn false;\n\t}\n\treturn !existsSync(settingsPath);\n}\n\nexport async function showStartupSelector<T>(\n\tsettingsManager: SettingsManager,\n\ttitle: string,\n\toptions: Array<{ label: string; value: T }>,\n): Promise<T | undefined> {\n\tconst ui = await createStartupTui(settingsManager);\n\treturn new Promise((resolve) => {\n\t\tlet settled = false;\n\t\tconst finish = async (result: T | undefined) => {\n\t\t\tif (settled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsettled = true;\n\t\t\tawait clearStartupTui(ui);\n\t\t\tui.stop();\n\t\t\tresolve(result);\n\t\t};\n\n\t\tconst selector = new ExtensionSelectorComponent(\n\t\t\ttitle,\n\t\t\toptions.map((option) => option.label),\n\t\t\t(option) => void finish(options.find((entry) => entry.label === option)?.value),\n\t\t\t() => void finish(undefined),\n\t\t\t{ tui: ui },\n\t\t);\n\t\tui.addChild(selector);\n\t\tui.setFocus(selector);\n\t\tstartStartupTui(ui, settingsManager);\n\t});\n}\n\n/** Show the first-time setup dialog and persist the result */\nexport async function showFirstTimeSetup(settingsManager: SettingsManager): Promise<void> {\n\tconst ui = await createStartupTui(settingsManager);\n\treturn new Promise((resolve) => {\n\t\tlet settled = false;\n\t\tconst finish = async (result: FirstTimeSetupResult | undefined) => {\n\t\t\tif (settled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsettled = true;\n\t\t\tif (result) {\n\t\t\t\tsettingsManager.setTheme(result.theme);\n\t\t\t\tawait settingsManager.flush();\n\t\t\t}\n\t\t\tawait clearStartupTui(ui);\n\t\t\tui.stop();\n\t\t\tresolve();\n\t\t};\n\n\t\tconst showSetup = async () => {\n\t\t\tui.start();\n\t\t\tconst detectedTheme = await detectTerminalThemeForAuto({ ui, timeoutMs: 100 });\n\t\t\tsetTheme(detectedTheme);\n\t\t\tconst component = new FirstTimeSetupComponent({\n\t\t\t\tdetectedTheme,\n\t\t\t\tonThemePreview: (themeName) => {\n\t\t\t\t\tsetTheme(themeName);\n\t\t\t\t\tui.requestRender();\n\t\t\t\t},\n\t\t\t\tonSubmit: (result) => void finish(result),\n\t\t\t\tonCancel: () => void finish(undefined),\n\t\t\t});\n\t\t\tui.addChild(component);\n\t\t\tui.setFocus(component);\n\t\t\tui.requestRender();\n\t\t};\n\n\t\tvoid showSetup();\n\t});\n}\n\nexport async function showStartupInput(\n\tsettingsManager: SettingsManager,\n\ttitle: string,\n\tplaceholder?: string,\n): Promise<string | undefined> {\n\tconst ui = await createStartupTui(settingsManager);\n\treturn new Promise((resolve) => {\n\t\tlet settled = false;\n\t\tconst finish = async (result: string | undefined) => {\n\t\t\tif (settled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsettled = true;\n\t\t\tinput.dispose();\n\t\t\tawait clearStartupTui(ui);\n\t\t\tui.stop();\n\t\t\tresolve(result);\n\t\t};\n\n\t\tconst input = new ExtensionInputComponent(\n\t\t\ttitle,\n\t\t\tplaceholder,\n\t\t\t(value) => void finish(value),\n\t\t\t() => void finish(undefined),\n\t\t\t{\n\t\t\t\ttui: ui,\n\t\t\t},\n\t\t);\n\t\tui.addChild(input);\n\t\tui.setFocus(input);\n\t\tstartStartupTui(ui, settingsManager);\n\t});\n}\n"]}
1
+ {"version":3,"file":"startup-ui.js","sourceRoot":"","sources":["../../src/cli/startup-ui.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tProcessTerminal,\n\tsetCapabilityOverrides,\n\tsetKeybindings,\n\ttype TUI,\n\tTuiMainScreen,\n} from \"@earendil-works/pi-tui\";\nimport { existsSync } from \"fs\";\nimport { APP_NAME, CONFIG_DIR_NAME, ENV_AGENT_DIR, getAgentDir, getSettingsPath, PACKAGE_NAME } from \"../config.ts\";\nimport { areExperimentalFeaturesEnabled } from \"../core/experimental.ts\";\nimport { KeybindingsManager } from \"../core/keybindings.ts\";\nimport { DefaultPackageManager, type ResolvedResource } from \"../core/package-manager.ts\";\nimport { SettingsManager } from \"../core/settings-manager.ts\";\nimport { ExtensionInputComponent } from \"../modes/interactive/components/extension-input.ts\";\nimport { ExtensionSelectorComponent } from \"../modes/interactive/components/extension-selector.ts\";\nimport {\n\tFirstTimeSetupComponent,\n\ttype FirstTimeSetupResult,\n} from \"../modes/interactive/components/first-time-setup.ts\";\nimport {\n\tdetectTerminalBackgroundFromEnv,\n\tdetectTerminalThemeForAuto,\n\tinitTheme,\n\tloadThemeFromPath,\n\tparseAutoThemeSetting,\n\tresolveThemeSetting,\n\tsetRegisteredThemes,\n\tsetTheme,\n\ttype Theme,\n} from \"../modes/interactive/theme/theme.ts\";\n\nconst OFFICIAL_PACKAGE_NAME = \"apex-code\";\nconst OFFICIAL_APP_NAME = \"apex-code\";\nconst OFFICIAL_CONFIG_DIR_NAME = \".apex-code\";\n\ninterface DistributionMetadata {\n\tpackageName: string;\n\tappName: string;\n\tconfigDirName: string;\n}\n\nfunction isOfficialDistribution({ packageName, appName, configDirName }: DistributionMetadata): boolean {\n\treturn (\n\t\tpackageName === OFFICIAL_PACKAGE_NAME &&\n\t\tappName === OFFICIAL_APP_NAME &&\n\t\tconfigDirName === OFFICIAL_CONFIG_DIR_NAME\n\t);\n}\n\nfunction loadThemes(resources: ResolvedResource[]): Theme[] {\n\tconst themes: Theme[] = [];\n\tconst seen = new Set<string>();\n\tfor (const resource of resources) {\n\t\tif (!resource.enabled) continue;\n\t\ttry {\n\t\t\tconst loadedTheme = loadThemeFromPath(resource.path);\n\t\t\tif (loadedTheme.name) {\n\t\t\t\tif (seen.has(loadedTheme.name)) continue;\n\t\t\t\tseen.add(loadedTheme.name);\n\t\t\t}\n\t\t\tthemes.push(loadedTheme);\n\t\t} catch {\n\t\t\t// Startup prompts should not fail because a theme is broken. The normal\n\t\t\t// resource loader reports theme diagnostics later in startup.\n\t\t}\n\t}\n\treturn themes;\n}\n\nasync function loadStartupThemes(settingsManager: SettingsManager): Promise<Theme[]> {\n\tconst globalSettingsManager = SettingsManager.inMemory(settingsManager.getGlobalSettings(), {\n\t\tprojectTrusted: false,\n\t});\n\tconst packageManager = new DefaultPackageManager({\n\t\tcwd: process.cwd(),\n\t\tagentDir: getAgentDir(),\n\t\tsettingsManager: globalSettingsManager,\n\t});\n\tconst resolvedPaths = await packageManager.resolve(async () => \"skip\");\n\treturn loadThemes(resolvedPaths.themes);\n}\n\nexport async function createStartupTui(settingsManager: SettingsManager): Promise<TUI> {\n\tsetCapabilityOverrides(settingsManager.getTerminalCapabilityOverrides());\n\tsetRegisteredThemes(await loadStartupThemes(settingsManager));\n\tconst terminalTheme = detectTerminalBackgroundFromEnv().theme;\n\tinitTheme(resolveThemeSetting(settingsManager.getThemeSetting(), terminalTheme) ?? terminalTheme);\n\tsetKeybindings(KeybindingsManager.create());\n\tconst ui: TUI = new TuiMainScreen(new ProcessTerminal(), settingsManager.getShowHardwareCursor(), getAgentDir());\n\tui.setClearOnShrink(settingsManager.getClearOnShrink());\n\treturn ui;\n}\n\nexport function startStartupTui(ui: TUI, settingsManager: SettingsManager): void {\n\tui.start();\n\tvoid applyDetectedStartupTheme(ui, settingsManager);\n}\n\nasync function applyDetectedStartupTheme(ui: TUI, settingsManager: SettingsManager): Promise<void> {\n\tconst themeSetting = settingsManager.getThemeSetting();\n\tif (themeSetting && !parseAutoThemeSetting(themeSetting)) return;\n\n\tconst terminalTheme = await detectTerminalThemeForAuto({ ui, timeoutMs: 100 });\n\tsetTheme(resolveThemeSetting(themeSetting, terminalTheme) ?? terminalTheme);\n\tui.invalidate();\n\tui.requestRender();\n}\n\nasync function clearStartupTui(ui: TUI): Promise<void> {\n\tui.clear();\n\tui.requestRender();\n\tawait new Promise((resolve) => setTimeout(resolve, 25));\n}\n\n/**\n * First-time setup runs when all of these hold:\n * - this is the official Pi distribution (not a fork/rebrand)\n * - experimental features are enabled (APEX_CODE_EXPERIMENTAL=1)\n * - the default agent directory is used (no custom agent dir override)\n * - setup was not completed before (settings.json does not exist)\n */\nexport function shouldRunFirstTimeSetup(settingsPath: string = getSettingsPath()): boolean {\n\tif (\n\t\t!isOfficialDistribution({\n\t\t\tpackageName: PACKAGE_NAME,\n\t\t\tappName: APP_NAME,\n\t\t\tconfigDirName: CONFIG_DIR_NAME,\n\t\t})\n\t) {\n\t\treturn false;\n\t}\n\tif (!areExperimentalFeaturesEnabled()) {\n\t\treturn false;\n\t}\n\tif (process.env[ENV_AGENT_DIR]) {\n\t\treturn false;\n\t}\n\treturn !existsSync(settingsPath);\n}\n\nexport async function showStartupSelector<T>(\n\tsettingsManager: SettingsManager,\n\ttitle: string,\n\toptions: Array<{ label: string; value: T }>,\n): Promise<T | undefined> {\n\tconst ui = await createStartupTui(settingsManager);\n\treturn new Promise((resolve) => {\n\t\tlet settled = false;\n\t\tconst finish = async (result: T | undefined) => {\n\t\t\tif (settled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsettled = true;\n\t\t\tawait clearStartupTui(ui);\n\t\t\tui.stop();\n\t\t\tresolve(result);\n\t\t};\n\n\t\tconst selector = new ExtensionSelectorComponent(\n\t\t\ttitle,\n\t\t\toptions.map((option) => option.label),\n\t\t\t(option) => void finish(options.find((entry) => entry.label === option)?.value),\n\t\t\t() => void finish(undefined),\n\t\t\t{ tui: ui },\n\t\t);\n\t\tui.addChild(selector);\n\t\tui.setFocus(selector);\n\t\tstartStartupTui(ui, settingsManager);\n\t});\n}\n\n/** Show the first-time setup dialog and persist the result */\nexport async function showFirstTimeSetup(settingsManager: SettingsManager): Promise<void> {\n\tconst ui = await createStartupTui(settingsManager);\n\treturn new Promise((resolve) => {\n\t\tlet settled = false;\n\t\tconst finish = async (result: FirstTimeSetupResult | undefined) => {\n\t\t\tif (settled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsettled = true;\n\t\t\tif (result) {\n\t\t\t\tsettingsManager.setTheme(result.theme);\n\t\t\t\tawait settingsManager.flush();\n\t\t\t}\n\t\t\tawait clearStartupTui(ui);\n\t\t\tui.stop();\n\t\t\tresolve();\n\t\t};\n\n\t\tconst showSetup = async () => {\n\t\t\tui.start();\n\t\t\tconst detectedTheme = await detectTerminalThemeForAuto({ ui, timeoutMs: 100 });\n\t\t\tsetTheme(detectedTheme);\n\t\t\tconst component = new FirstTimeSetupComponent({\n\t\t\t\tdetectedTheme,\n\t\t\t\tonThemePreview: (themeName) => {\n\t\t\t\t\tsetTheme(themeName);\n\t\t\t\t\tui.requestRender();\n\t\t\t\t},\n\t\t\t\tonSubmit: (result) => void finish(result),\n\t\t\t\tonCancel: () => void finish(undefined),\n\t\t\t});\n\t\t\tui.addChild(component);\n\t\t\tui.setFocus(component);\n\t\t\tui.requestRender();\n\t\t};\n\n\t\tvoid showSetup();\n\t});\n}\n\nexport async function showStartupInput(\n\tsettingsManager: SettingsManager,\n\ttitle: string,\n\tplaceholder?: string,\n): Promise<string | undefined> {\n\tconst ui = await createStartupTui(settingsManager);\n\treturn new Promise((resolve) => {\n\t\tlet settled = false;\n\t\tconst finish = async (result: string | undefined) => {\n\t\t\tif (settled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsettled = true;\n\t\t\tinput.dispose();\n\t\t\tawait clearStartupTui(ui);\n\t\t\tui.stop();\n\t\t\tresolve(result);\n\t\t};\n\n\t\tconst input = new ExtensionInputComponent(\n\t\t\ttitle,\n\t\t\tplaceholder,\n\t\t\t(value) => void finish(value),\n\t\t\t() => void finish(undefined),\n\t\t\t{\n\t\t\t\ttui: ui,\n\t\t\t},\n\t\t);\n\t\tui.addChild(input);\n\t\tui.setFocus(input);\n\t\tstartStartupTui(ui, settingsManager);\n\t});\n}\n"]}
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"","sourcesContent":["#!/usr/bin/env node\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n/** The public CLI either supervises a sandbox child or starts an ordinary runtime. */\nimport { fileURLToPath } from \"node:url\";\nimport { APP_NAME, getAgentDir, getPackageDir } from \"./config.ts\";\nimport { setApexEnvironment } from \"./core/environment.ts\";\nimport { configureHttpDispatcher } from \"./core/http-dispatcher.ts\";\nimport {\n\trequiresSandboxedChild,\n\tresolveHostSkillPaths,\n\tresolveSupervisorAllowedHosts,\n} from \"./core/sandbox/cli-launch.ts\";\nimport { launchSandboxedCli } from \"./core/sandbox/cli-supervisor.ts\";\nimport { prepareHostToolBinaries } from \"./utils/tools-manager.ts\";\n\nasync function run(): Promise<void> {\n\tconst args = process.argv.slice(2);\n\t// Validate session IDs before entering the sandbox. Invalid metadata must fail fast\n\t// without starting a child process or touching network/sandbox setup.\n\tconst sessionIdIndex = args.indexOf(\"--session-id\");\n\tconst sessionId = sessionIdIndex >= 0 ? args[sessionIdIndex + 1] : undefined;\n\tif (sessionId !== undefined && !/^[A-Za-z0-9](?:[A-Za-z0-9._-]*[A-Za-z0-9])?$/.test(sessionId)) {\n\t\tconsole.error(\n\t\t\t\"Error: Session id must be non-empty, contain only alphanumeric characters, '-', '_', and '.', and start and end with an alphanumeric character\",\n\t\t);\n\t\tprocess.exitCode = 1;\n\t\treturn;\n\t}\n\tif (requiresSandboxedChild(args)) {\n\t\tconst allowedHosts = resolveSupervisorAllowedHosts(process.cwd(), getAgentDir());\n\t\tconst authPath = join(getAgentDir(), \"auth.json\");\n\t\t// Resolve fd and rg out here, where the host home and the network are both still\n\t\t// reachable. The child's own PATH still names host directories the sandbox has\n\t\t// replaced, so without this projection it finds nothing and cannot download either.\n\t\t// Silent because this runs ahead of every mode, including --print and --mode rpc,\n\t\t// whose stdout carries machine-readable output; the child still reports a genuinely\n\t\t// missing tool through its own startup path.\n\t\tconst toolBinaries = await prepareHostToolBinaries(true);\n\t\t// Resolved here, where the host home is still reachable -- exactly like the\n\t\t// tool binaries above and unlike anything sourced from project files, which\n\t\t// ADR 0016 forbids as supervisor input before trust is established.\n\t\tconst { paths: skillPaths, refusals: skillPathRefusals } = resolveHostSkillPaths(\n\t\t\tgetAgentDir(),\n\t\t\tprocess.env.HOME || homedir(),\n\t\t);\n\t\tfor (const refusal of skillPathRefusals) {\n\t\t\tprocess.stderr.write(`Warning: not mounting skill directory ${refusal.path}: ${refusal.reason}\\n`);\n\t\t}\n\n\t\tprocess.exitCode = await launchSandboxedCli({\n\t\t\tcommand: process.execPath,\n\t\t\targs: [\n\t\t\t\tfileURLToPath(\n\t\t\t\t\tnew URL(`./core/sandbox/child-entry${import.meta.url.endsWith(\".ts\") ? \".ts\" : \".js\"}`, import.meta.url),\n\t\t\t\t),\n\t\t\t\t...args,\n\t\t\t],\n\t\t\tenvironment: process.env,\n\t\t\tworkspace: process.cwd(),\n\t\t\tallowedHosts,\n\t\t\tauthPath,\n\t\t\treadOnlyPaths: [getPackageDir(), dirname(getPackageDir())],\n\t\t\ttoolBinaries,\n\t\t\tskillPaths,\n\t\t});\n\t\treturn;\n\t}\n\n\tprocess.title = APP_NAME;\n\tsetApexEnvironment(\"APEX_CODE_CODING_AGENT\", \"true\");\n\tprocess.env.AI_AGENT = \"apex-code\";\n\tprocess.emitWarning = (() => {}) as typeof process.emitWarning;\n\tconfigureHttpDispatcher();\n\tconst { main } = await import(\"./main.ts\");\n\tawait main(args);\n}\n\nawait run();\n"]}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"","sourcesContent":["#!/usr/bin/env node\nimport { existsSync, readFileSync, realpathSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join, sep } from \"node:path\";\n/** The public CLI either supervises a sandbox child or starts an ordinary runtime. */\nimport { fileURLToPath } from \"node:url\";\nimport { parseCliCommand } from \"./cli/args.ts\";\nimport { APP_NAME, getAgentDir, getPackageDir } from \"./config.ts\";\nimport { setApexEnvironment } from \"./core/environment.ts\";\nimport { configureHttpDispatcher } from \"./core/http-dispatcher.ts\";\nimport {\n\trequiresSandboxedChild,\n\tresolveHostSkillPaths,\n\tresolveSupervisorAllowedHosts,\n} from \"./core/sandbox/cli-launch.ts\";\nimport { launchSandboxedCli } from \"./core/sandbox/cli-supervisor.ts\";\nimport { confirmFullAccess, writeFullAccessBanner } from \"./core/sandbox/full-access.ts\";\nimport { resolveSandboxProfile } from \"./core/sandbox/profiles.ts\";\nimport { prepareHostToolBinaries } from \"./utils/tools-manager.ts\";\n\nfunction resolveRuntimeReadOnlyPaths(): readonly string[] {\n\tconst packageDir = getPackageDir();\n\tconst checkoutRoot = dirname(dirname(packageDir));\n\tconst checkoutPackagesDirectory = join(checkoutRoot, \"packages\");\n\tconst checkoutDependenciesDirectory = join(checkoutRoot, \"node_modules\");\n\n\t// The source checkout hoists dependencies to the repository root. Package-local\n\t// node_modules entries are often symlinks into that directory, so projecting only\n\t// the package directory leaves Node unable to resolve imports after /home is hidden.\n\t// Project the workspace packages that the runtime dependency graph actually names,\n\t// rather than the whole `packages` parent, so unrelated workspace siblings remain\n\t// hidden. Do not apply this to installed layouts: exposing a package manager's\n\t// entire global node_modules parent would weaken the exact sibling projection.\n\tif (\n\t\texistsSync(checkoutPackagesDirectory) &&\n\t\texistsSync(checkoutDependenciesDirectory) &&\n\t\tpackageDir.startsWith(`${checkoutPackagesDirectory}${sep}`)\n\t) {\n\t\tconst packagePaths = new Set<string>([packageDir]);\n\t\tconst packagesToInspect = [packageDir];\n\t\twhile (packagesToInspect.length > 0) {\n\t\t\tconst currentPackage = packagesToInspect.pop()!;\n\t\t\tlet manifest: {\n\t\t\t\tdependencies?: Record<string, string>;\n\t\t\t\toptionalDependencies?: Record<string, string>;\n\t\t\t};\n\t\t\ttry {\n\t\t\t\tmanifest = JSON.parse(readFileSync(join(currentPackage, \"package.json\"), \"utf8\")) as typeof manifest;\n\t\t\t} catch {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tfor (const dependencyName of Object.keys({\n\t\t\t\t...manifest.dependencies,\n\t\t\t\t...manifest.optionalDependencies,\n\t\t\t})) {\n\t\t\t\tconst dependencyPath = join(checkoutDependenciesDirectory, dependencyName);\n\t\t\t\ttry {\n\t\t\t\t\tconst realDependencyPath = realpathSync(dependencyPath);\n\t\t\t\t\tif (\n\t\t\t\t\t\trealDependencyPath.startsWith(`${checkoutPackagesDirectory}${sep}`) &&\n\t\t\t\t\t\t!packagePaths.has(realDependencyPath)\n\t\t\t\t\t) {\n\t\t\t\t\t\tpackagePaths.add(realDependencyPath);\n\t\t\t\t\t\tpackagesToInspect.push(realDependencyPath);\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// A missing optional dependency does not make the CLI unlaunchable.\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn [...packagePaths, checkoutDependenciesDirectory];\n\t}\n\treturn [packageDir, dirname(packageDir)];\n}\n\nasync function run(): Promise<void> {\n\tconst args = process.argv.slice(2);\n\tconst command = parseCliCommand(args);\n\tconst parsed = command.args;\n\t// Validate session IDs before entering the sandbox. Invalid metadata must fail fast\n\t// without starting a child process or touching network/sandbox setup.\n\tconst sessionIdIndex = args.indexOf(\"--session-id\");\n\tconst sessionId = sessionIdIndex >= 0 ? args[sessionIdIndex + 1] : undefined;\n\tif (sessionId !== undefined && !/^[A-Za-z0-9](?:[A-Za-z0-9._-]*[A-Za-z0-9])?$/.test(sessionId)) {\n\t\tconsole.error(\n\t\t\t\"Error: Session id must be non-empty, contain only alphanumeric characters, '-', '_', and '.', and start and end with an alphanumeric character\",\n\t\t);\n\t\tprocess.exitCode = 1;\n\t\treturn;\n\t}\n\t// Parsed straight from argv, before any settings loader runs. ADR 0016 keeps every\n\t// supervisor policy input out of project files, and \"run with no boundary\" is the one\n\t// input where that matters most.\n\tconst { addDir, sandbox: sandboxMode, permissionProfile, diagnostics: sandboxDiagnostics } = parsed;\n\tfor (const diagnostic of sandboxDiagnostics) {\n\t\tif (diagnostic.type === \"error\" && /--add-dir|--sandbox|--permission-profile/.test(diagnostic.message)) {\n\t\t\tconsole.error(`Error: ${diagnostic.message}`);\n\t\t\tprocess.exitCode = 1;\n\t\t\treturn;\n\t\t}\n\t}\n\n\tif (sandboxMode === \"danger-full-access\" && requiresSandboxedChild(command)) {\n\t\twriteFullAccessBanner(process.stderr);\n\t\tif (!(await confirmFullAccess({}))) {\n\t\t\tprocess.stderr.write(\"Aborted; the session was not started.\\n\");\n\t\t\tprocess.exitCode = 1;\n\t\t\treturn;\n\t\t}\n\t}\n\n\tif (requiresSandboxedChild(command) && sandboxMode !== \"danger-full-access\") {\n\t\t// The profile is resolved from global settings only and merged as additional\n\t\t// permission, never as replacement: a profile widens what a session may reach and\n\t\t// write, and cannot narrow or disable the boundary itself.\n\t\tconst profile = resolveSandboxProfile(permissionProfile, process.cwd(), getAgentDir());\n\t\tif (permissionProfile && !profile) {\n\t\t\tconsole.error(`Error: no sandbox profile named \"${permissionProfile}\" in global settings.`);\n\t\t\tprocess.exitCode = 1;\n\t\t\treturn;\n\t\t}\n\t\tconst configuredHosts = resolveSupervisorAllowedHosts(process.cwd(), getAgentDir());\n\t\t// undefined means the strict deny-all posture, which a profile must not silently\n\t\t// turn into an allowlist by being concatenated onto nothing.\n\t\tconst allowedHosts =\n\t\t\tconfiguredHosts === undefined && !profile\n\t\t\t\t? undefined\n\t\t\t\t: [...(configuredHosts ?? []), ...(profile?.allowedHosts ?? [])];\n\t\tconst authPath = join(getAgentDir(), \"auth.json\");\n\t\t// Resolve fd and rg out here, where the host home and the network are both still\n\t\t// reachable. The child's own PATH still names host directories the sandbox has\n\t\t// replaced, so without this projection it finds nothing and cannot download either.\n\t\t// Silent because this runs ahead of every mode, including --print and --mode rpc,\n\t\t// whose stdout carries machine-readable output; the child still reports a genuinely\n\t\t// missing tool through its own startup path.\n\t\tconst toolBinaries = await prepareHostToolBinaries(true);\n\t\t// Resolved here, where the host home is still reachable -- exactly like the\n\t\t// tool binaries above and unlike anything sourced from project files, which\n\t\t// ADR 0016 forbids as supervisor input before trust is established.\n\t\tconst { paths: skillPaths, refusals: skillPathRefusals } = resolveHostSkillPaths(\n\t\t\tgetAgentDir(),\n\t\t\tprocess.env.HOME || homedir(),\n\t\t);\n\t\tfor (const refusal of skillPathRefusals) {\n\t\t\tprocess.stderr.write(`Warning: not mounting skill directory ${refusal.path}: ${refusal.reason}\\n`);\n\t\t}\n\n\t\tprocess.exitCode = await launchSandboxedCli({\n\t\t\tcommand: process.execPath,\n\t\t\targs: [\n\t\t\t\tfileURLToPath(\n\t\t\t\t\tnew URL(`./core/sandbox/child-entry${import.meta.url.endsWith(\".ts\") ? \".ts\" : \".js\"}`, import.meta.url),\n\t\t\t\t),\n\t\t\t\t...args,\n\t\t\t],\n\t\t\tenvironment: process.env,\n\t\t\tworkspace: process.cwd(),\n\t\t\tagentDir: getAgentDir(),\n\t\t\tallowedHosts,\n\t\t\tauthPath,\n\t\t\tadditionalWritableRoots: [...(addDir ?? []), ...(profile?.additionalWritableRoots ?? [])],\n\t\t\treadOnlyPaths: resolveRuntimeReadOnlyPaths(),\n\t\t\ttoolBinaries,\n\t\t\tskillPaths,\n\t\t});\n\t\treturn;\n\t}\n\n\tprocess.title = APP_NAME;\n\tsetApexEnvironment(\"APEX_CODE_CODING_AGENT\", \"true\");\n\tprocess.env.AI_AGENT = \"apex-code\";\n\tprocess.emitWarning = (() => {}) as typeof process.emitWarning;\n\tconfigureHttpDispatcher();\n\tconst { main } = await import(\"./main.ts\");\n\tawait main(args, { parsedCommand: command });\n}\n\nawait run();\n"]}
package/dist/cli.js CHANGED
@@ -1,16 +1,70 @@
1
1
  #!/usr/bin/env node
2
+ import { existsSync, readFileSync, realpathSync } from "node:fs";
2
3
  import { homedir } from "node:os";
3
- import { dirname, join } from "node:path";
4
+ import { dirname, join, sep } from "node:path";
4
5
  /** The public CLI either supervises a sandbox child or starts an ordinary runtime. */
5
6
  import { fileURLToPath } from "node:url";
7
+ import { parseCliCommand } from "./cli/args.js";
6
8
  import { APP_NAME, getAgentDir, getPackageDir } from "./config.js";
7
9
  import { setApexEnvironment } from "./core/environment.js";
8
10
  import { configureHttpDispatcher } from "./core/http-dispatcher.js";
9
11
  import { requiresSandboxedChild, resolveHostSkillPaths, resolveSupervisorAllowedHosts, } from "./core/sandbox/cli-launch.js";
10
12
  import { launchSandboxedCli } from "./core/sandbox/cli-supervisor.js";
13
+ import { confirmFullAccess, writeFullAccessBanner } from "./core/sandbox/full-access.js";
14
+ import { resolveSandboxProfile } from "./core/sandbox/profiles.js";
11
15
  import { prepareHostToolBinaries } from "./utils/tools-manager.js";
16
+ function resolveRuntimeReadOnlyPaths() {
17
+ const packageDir = getPackageDir();
18
+ const checkoutRoot = dirname(dirname(packageDir));
19
+ const checkoutPackagesDirectory = join(checkoutRoot, "packages");
20
+ const checkoutDependenciesDirectory = join(checkoutRoot, "node_modules");
21
+ // The source checkout hoists dependencies to the repository root. Package-local
22
+ // node_modules entries are often symlinks into that directory, so projecting only
23
+ // the package directory leaves Node unable to resolve imports after /home is hidden.
24
+ // Project the workspace packages that the runtime dependency graph actually names,
25
+ // rather than the whole `packages` parent, so unrelated workspace siblings remain
26
+ // hidden. Do not apply this to installed layouts: exposing a package manager's
27
+ // entire global node_modules parent would weaken the exact sibling projection.
28
+ if (existsSync(checkoutPackagesDirectory) &&
29
+ existsSync(checkoutDependenciesDirectory) &&
30
+ packageDir.startsWith(`${checkoutPackagesDirectory}${sep}`)) {
31
+ const packagePaths = new Set([packageDir]);
32
+ const packagesToInspect = [packageDir];
33
+ while (packagesToInspect.length > 0) {
34
+ const currentPackage = packagesToInspect.pop();
35
+ let manifest;
36
+ try {
37
+ manifest = JSON.parse(readFileSync(join(currentPackage, "package.json"), "utf8"));
38
+ }
39
+ catch {
40
+ continue;
41
+ }
42
+ for (const dependencyName of Object.keys({
43
+ ...manifest.dependencies,
44
+ ...manifest.optionalDependencies,
45
+ })) {
46
+ const dependencyPath = join(checkoutDependenciesDirectory, dependencyName);
47
+ try {
48
+ const realDependencyPath = realpathSync(dependencyPath);
49
+ if (realDependencyPath.startsWith(`${checkoutPackagesDirectory}${sep}`) &&
50
+ !packagePaths.has(realDependencyPath)) {
51
+ packagePaths.add(realDependencyPath);
52
+ packagesToInspect.push(realDependencyPath);
53
+ }
54
+ }
55
+ catch {
56
+ // A missing optional dependency does not make the CLI unlaunchable.
57
+ }
58
+ }
59
+ }
60
+ return [...packagePaths, checkoutDependenciesDirectory];
61
+ }
62
+ return [packageDir, dirname(packageDir)];
63
+ }
12
64
  async function run() {
13
65
  const args = process.argv.slice(2);
66
+ const command = parseCliCommand(args);
67
+ const parsed = command.args;
14
68
  // Validate session IDs before entering the sandbox. Invalid metadata must fail fast
15
69
  // without starting a child process or touching network/sandbox setup.
16
70
  const sessionIdIndex = args.indexOf("--session-id");
@@ -20,8 +74,41 @@ async function run() {
20
74
  process.exitCode = 1;
21
75
  return;
22
76
  }
23
- if (requiresSandboxedChild(args)) {
24
- const allowedHosts = resolveSupervisorAllowedHosts(process.cwd(), getAgentDir());
77
+ // Parsed straight from argv, before any settings loader runs. ADR 0016 keeps every
78
+ // supervisor policy input out of project files, and "run with no boundary" is the one
79
+ // input where that matters most.
80
+ const { addDir, sandbox: sandboxMode, permissionProfile, diagnostics: sandboxDiagnostics } = parsed;
81
+ for (const diagnostic of sandboxDiagnostics) {
82
+ if (diagnostic.type === "error" && /--add-dir|--sandbox|--permission-profile/.test(diagnostic.message)) {
83
+ console.error(`Error: ${diagnostic.message}`);
84
+ process.exitCode = 1;
85
+ return;
86
+ }
87
+ }
88
+ if (sandboxMode === "danger-full-access" && requiresSandboxedChild(command)) {
89
+ writeFullAccessBanner(process.stderr);
90
+ if (!(await confirmFullAccess({}))) {
91
+ process.stderr.write("Aborted; the session was not started.\n");
92
+ process.exitCode = 1;
93
+ return;
94
+ }
95
+ }
96
+ if (requiresSandboxedChild(command) && sandboxMode !== "danger-full-access") {
97
+ // The profile is resolved from global settings only and merged as additional
98
+ // permission, never as replacement: a profile widens what a session may reach and
99
+ // write, and cannot narrow or disable the boundary itself.
100
+ const profile = resolveSandboxProfile(permissionProfile, process.cwd(), getAgentDir());
101
+ if (permissionProfile && !profile) {
102
+ console.error(`Error: no sandbox profile named "${permissionProfile}" in global settings.`);
103
+ process.exitCode = 1;
104
+ return;
105
+ }
106
+ const configuredHosts = resolveSupervisorAllowedHosts(process.cwd(), getAgentDir());
107
+ // undefined means the strict deny-all posture, which a profile must not silently
108
+ // turn into an allowlist by being concatenated onto nothing.
109
+ const allowedHosts = configuredHosts === undefined && !profile
110
+ ? undefined
111
+ : [...(configuredHosts ?? []), ...(profile?.allowedHosts ?? [])];
25
112
  const authPath = join(getAgentDir(), "auth.json");
26
113
  // Resolve fd and rg out here, where the host home and the network are both still
27
114
  // reachable. The child's own PATH still names host directories the sandbox has
@@ -45,9 +132,11 @@ async function run() {
45
132
  ],
46
133
  environment: process.env,
47
134
  workspace: process.cwd(),
135
+ agentDir: getAgentDir(),
48
136
  allowedHosts,
49
137
  authPath,
50
- readOnlyPaths: [getPackageDir(), dirname(getPackageDir())],
138
+ additionalWritableRoots: [...(addDir ?? []), ...(profile?.additionalWritableRoots ?? [])],
139
+ readOnlyPaths: resolveRuntimeReadOnlyPaths(),
51
140
  toolBinaries,
52
141
  skillPaths,
53
142
  });
@@ -59,7 +148,7 @@ async function run() {
59
148
  process.emitWarning = (() => { });
60
149
  configureHttpDispatcher();
61
150
  const { main } = await import("./main.js");
62
- await main(args);
151
+ await main(args, { parsedCommand: command });
63
152
  }
64
153
  await run();
65
154
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n/** The public CLI either supervises a sandbox child or starts an ordinary runtime. */\nimport { fileURLToPath } from \"node:url\";\nimport { APP_NAME, getAgentDir, getPackageDir } from \"./config.ts\";\nimport { setApexEnvironment } from \"./core/environment.ts\";\nimport { configureHttpDispatcher } from \"./core/http-dispatcher.ts\";\nimport {\n\trequiresSandboxedChild,\n\tresolveHostSkillPaths,\n\tresolveSupervisorAllowedHosts,\n} from \"./core/sandbox/cli-launch.ts\";\nimport { launchSandboxedCli } from \"./core/sandbox/cli-supervisor.ts\";\nimport { prepareHostToolBinaries } from \"./utils/tools-manager.ts\";\n\nasync function run(): Promise<void> {\n\tconst args = process.argv.slice(2);\n\t// Validate session IDs before entering the sandbox. Invalid metadata must fail fast\n\t// without starting a child process or touching network/sandbox setup.\n\tconst sessionIdIndex = args.indexOf(\"--session-id\");\n\tconst sessionId = sessionIdIndex >= 0 ? args[sessionIdIndex + 1] : undefined;\n\tif (sessionId !== undefined && !/^[A-Za-z0-9](?:[A-Za-z0-9._-]*[A-Za-z0-9])?$/.test(sessionId)) {\n\t\tconsole.error(\n\t\t\t\"Error: Session id must be non-empty, contain only alphanumeric characters, '-', '_', and '.', and start and end with an alphanumeric character\",\n\t\t);\n\t\tprocess.exitCode = 1;\n\t\treturn;\n\t}\n\tif (requiresSandboxedChild(args)) {\n\t\tconst allowedHosts = resolveSupervisorAllowedHosts(process.cwd(), getAgentDir());\n\t\tconst authPath = join(getAgentDir(), \"auth.json\");\n\t\t// Resolve fd and rg out here, where the host home and the network are both still\n\t\t// reachable. The child's own PATH still names host directories the sandbox has\n\t\t// replaced, so without this projection it finds nothing and cannot download either.\n\t\t// Silent because this runs ahead of every mode, including --print and --mode rpc,\n\t\t// whose stdout carries machine-readable output; the child still reports a genuinely\n\t\t// missing tool through its own startup path.\n\t\tconst toolBinaries = await prepareHostToolBinaries(true);\n\t\t// Resolved here, where the host home is still reachable -- exactly like the\n\t\t// tool binaries above and unlike anything sourced from project files, which\n\t\t// ADR 0016 forbids as supervisor input before trust is established.\n\t\tconst { paths: skillPaths, refusals: skillPathRefusals } = resolveHostSkillPaths(\n\t\t\tgetAgentDir(),\n\t\t\tprocess.env.HOME || homedir(),\n\t\t);\n\t\tfor (const refusal of skillPathRefusals) {\n\t\t\tprocess.stderr.write(`Warning: not mounting skill directory ${refusal.path}: ${refusal.reason}\\n`);\n\t\t}\n\n\t\tprocess.exitCode = await launchSandboxedCli({\n\t\t\tcommand: process.execPath,\n\t\t\targs: [\n\t\t\t\tfileURLToPath(\n\t\t\t\t\tnew URL(`./core/sandbox/child-entry${import.meta.url.endsWith(\".ts\") ? \".ts\" : \".js\"}`, import.meta.url),\n\t\t\t\t),\n\t\t\t\t...args,\n\t\t\t],\n\t\t\tenvironment: process.env,\n\t\t\tworkspace: process.cwd(),\n\t\t\tallowedHosts,\n\t\t\tauthPath,\n\t\t\treadOnlyPaths: [getPackageDir(), dirname(getPackageDir())],\n\t\t\ttoolBinaries,\n\t\t\tskillPaths,\n\t\t});\n\t\treturn;\n\t}\n\n\tprocess.title = APP_NAME;\n\tsetApexEnvironment(\"APEX_CODE_CODING_AGENT\", \"true\");\n\tprocess.env.AI_AGENT = \"apex-code\";\n\tprocess.emitWarning = (() => {}) as typeof process.emitWarning;\n\tconfigureHttpDispatcher();\n\tconst { main } = await import(\"./main.ts\");\n\tawait main(args);\n}\n\nawait run();\n"]}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\nimport { existsSync, readFileSync, realpathSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join, sep } from \"node:path\";\n/** The public CLI either supervises a sandbox child or starts an ordinary runtime. */\nimport { fileURLToPath } from \"node:url\";\nimport { parseCliCommand } from \"./cli/args.ts\";\nimport { APP_NAME, getAgentDir, getPackageDir } from \"./config.ts\";\nimport { setApexEnvironment } from \"./core/environment.ts\";\nimport { configureHttpDispatcher } from \"./core/http-dispatcher.ts\";\nimport {\n\trequiresSandboxedChild,\n\tresolveHostSkillPaths,\n\tresolveSupervisorAllowedHosts,\n} from \"./core/sandbox/cli-launch.ts\";\nimport { launchSandboxedCli } from \"./core/sandbox/cli-supervisor.ts\";\nimport { confirmFullAccess, writeFullAccessBanner } from \"./core/sandbox/full-access.ts\";\nimport { resolveSandboxProfile } from \"./core/sandbox/profiles.ts\";\nimport { prepareHostToolBinaries } from \"./utils/tools-manager.ts\";\n\nfunction resolveRuntimeReadOnlyPaths(): readonly string[] {\n\tconst packageDir = getPackageDir();\n\tconst checkoutRoot = dirname(dirname(packageDir));\n\tconst checkoutPackagesDirectory = join(checkoutRoot, \"packages\");\n\tconst checkoutDependenciesDirectory = join(checkoutRoot, \"node_modules\");\n\n\t// The source checkout hoists dependencies to the repository root. Package-local\n\t// node_modules entries are often symlinks into that directory, so projecting only\n\t// the package directory leaves Node unable to resolve imports after /home is hidden.\n\t// Project the workspace packages that the runtime dependency graph actually names,\n\t// rather than the whole `packages` parent, so unrelated workspace siblings remain\n\t// hidden. Do not apply this to installed layouts: exposing a package manager's\n\t// entire global node_modules parent would weaken the exact sibling projection.\n\tif (\n\t\texistsSync(checkoutPackagesDirectory) &&\n\t\texistsSync(checkoutDependenciesDirectory) &&\n\t\tpackageDir.startsWith(`${checkoutPackagesDirectory}${sep}`)\n\t) {\n\t\tconst packagePaths = new Set<string>([packageDir]);\n\t\tconst packagesToInspect = [packageDir];\n\t\twhile (packagesToInspect.length > 0) {\n\t\t\tconst currentPackage = packagesToInspect.pop()!;\n\t\t\tlet manifest: {\n\t\t\t\tdependencies?: Record<string, string>;\n\t\t\t\toptionalDependencies?: Record<string, string>;\n\t\t\t};\n\t\t\ttry {\n\t\t\t\tmanifest = JSON.parse(readFileSync(join(currentPackage, \"package.json\"), \"utf8\")) as typeof manifest;\n\t\t\t} catch {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tfor (const dependencyName of Object.keys({\n\t\t\t\t...manifest.dependencies,\n\t\t\t\t...manifest.optionalDependencies,\n\t\t\t})) {\n\t\t\t\tconst dependencyPath = join(checkoutDependenciesDirectory, dependencyName);\n\t\t\t\ttry {\n\t\t\t\t\tconst realDependencyPath = realpathSync(dependencyPath);\n\t\t\t\t\tif (\n\t\t\t\t\t\trealDependencyPath.startsWith(`${checkoutPackagesDirectory}${sep}`) &&\n\t\t\t\t\t\t!packagePaths.has(realDependencyPath)\n\t\t\t\t\t) {\n\t\t\t\t\t\tpackagePaths.add(realDependencyPath);\n\t\t\t\t\t\tpackagesToInspect.push(realDependencyPath);\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// A missing optional dependency does not make the CLI unlaunchable.\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn [...packagePaths, checkoutDependenciesDirectory];\n\t}\n\treturn [packageDir, dirname(packageDir)];\n}\n\nasync function run(): Promise<void> {\n\tconst args = process.argv.slice(2);\n\tconst command = parseCliCommand(args);\n\tconst parsed = command.args;\n\t// Validate session IDs before entering the sandbox. Invalid metadata must fail fast\n\t// without starting a child process or touching network/sandbox setup.\n\tconst sessionIdIndex = args.indexOf(\"--session-id\");\n\tconst sessionId = sessionIdIndex >= 0 ? args[sessionIdIndex + 1] : undefined;\n\tif (sessionId !== undefined && !/^[A-Za-z0-9](?:[A-Za-z0-9._-]*[A-Za-z0-9])?$/.test(sessionId)) {\n\t\tconsole.error(\n\t\t\t\"Error: Session id must be non-empty, contain only alphanumeric characters, '-', '_', and '.', and start and end with an alphanumeric character\",\n\t\t);\n\t\tprocess.exitCode = 1;\n\t\treturn;\n\t}\n\t// Parsed straight from argv, before any settings loader runs. ADR 0016 keeps every\n\t// supervisor policy input out of project files, and \"run with no boundary\" is the one\n\t// input where that matters most.\n\tconst { addDir, sandbox: sandboxMode, permissionProfile, diagnostics: sandboxDiagnostics } = parsed;\n\tfor (const diagnostic of sandboxDiagnostics) {\n\t\tif (diagnostic.type === \"error\" && /--add-dir|--sandbox|--permission-profile/.test(diagnostic.message)) {\n\t\t\tconsole.error(`Error: ${diagnostic.message}`);\n\t\t\tprocess.exitCode = 1;\n\t\t\treturn;\n\t\t}\n\t}\n\n\tif (sandboxMode === \"danger-full-access\" && requiresSandboxedChild(command)) {\n\t\twriteFullAccessBanner(process.stderr);\n\t\tif (!(await confirmFullAccess({}))) {\n\t\t\tprocess.stderr.write(\"Aborted; the session was not started.\\n\");\n\t\t\tprocess.exitCode = 1;\n\t\t\treturn;\n\t\t}\n\t}\n\n\tif (requiresSandboxedChild(command) && sandboxMode !== \"danger-full-access\") {\n\t\t// The profile is resolved from global settings only and merged as additional\n\t\t// permission, never as replacement: a profile widens what a session may reach and\n\t\t// write, and cannot narrow or disable the boundary itself.\n\t\tconst profile = resolveSandboxProfile(permissionProfile, process.cwd(), getAgentDir());\n\t\tif (permissionProfile && !profile) {\n\t\t\tconsole.error(`Error: no sandbox profile named \"${permissionProfile}\" in global settings.`);\n\t\t\tprocess.exitCode = 1;\n\t\t\treturn;\n\t\t}\n\t\tconst configuredHosts = resolveSupervisorAllowedHosts(process.cwd(), getAgentDir());\n\t\t// undefined means the strict deny-all posture, which a profile must not silently\n\t\t// turn into an allowlist by being concatenated onto nothing.\n\t\tconst allowedHosts =\n\t\t\tconfiguredHosts === undefined && !profile\n\t\t\t\t? undefined\n\t\t\t\t: [...(configuredHosts ?? []), ...(profile?.allowedHosts ?? [])];\n\t\tconst authPath = join(getAgentDir(), \"auth.json\");\n\t\t// Resolve fd and rg out here, where the host home and the network are both still\n\t\t// reachable. The child's own PATH still names host directories the sandbox has\n\t\t// replaced, so without this projection it finds nothing and cannot download either.\n\t\t// Silent because this runs ahead of every mode, including --print and --mode rpc,\n\t\t// whose stdout carries machine-readable output; the child still reports a genuinely\n\t\t// missing tool through its own startup path.\n\t\tconst toolBinaries = await prepareHostToolBinaries(true);\n\t\t// Resolved here, where the host home is still reachable -- exactly like the\n\t\t// tool binaries above and unlike anything sourced from project files, which\n\t\t// ADR 0016 forbids as supervisor input before trust is established.\n\t\tconst { paths: skillPaths, refusals: skillPathRefusals } = resolveHostSkillPaths(\n\t\t\tgetAgentDir(),\n\t\t\tprocess.env.HOME || homedir(),\n\t\t);\n\t\tfor (const refusal of skillPathRefusals) {\n\t\t\tprocess.stderr.write(`Warning: not mounting skill directory ${refusal.path}: ${refusal.reason}\\n`);\n\t\t}\n\n\t\tprocess.exitCode = await launchSandboxedCli({\n\t\t\tcommand: process.execPath,\n\t\t\targs: [\n\t\t\t\tfileURLToPath(\n\t\t\t\t\tnew URL(`./core/sandbox/child-entry${import.meta.url.endsWith(\".ts\") ? \".ts\" : \".js\"}`, import.meta.url),\n\t\t\t\t),\n\t\t\t\t...args,\n\t\t\t],\n\t\t\tenvironment: process.env,\n\t\t\tworkspace: process.cwd(),\n\t\t\tagentDir: getAgentDir(),\n\t\t\tallowedHosts,\n\t\t\tauthPath,\n\t\t\tadditionalWritableRoots: [...(addDir ?? []), ...(profile?.additionalWritableRoots ?? [])],\n\t\t\treadOnlyPaths: resolveRuntimeReadOnlyPaths(),\n\t\t\ttoolBinaries,\n\t\t\tskillPaths,\n\t\t});\n\t\treturn;\n\t}\n\n\tprocess.title = APP_NAME;\n\tsetApexEnvironment(\"APEX_CODE_CODING_AGENT\", \"true\");\n\tprocess.env.AI_AGENT = \"apex-code\";\n\tprocess.emitWarning = (() => {}) as typeof process.emitWarning;\n\tconfigureHttpDispatcher();\n\tconst { main } = await import(\"./main.ts\");\n\tawait main(args, { parsedCommand: command });\n}\n\nawait run();\n"]}
package/dist/config.d.ts CHANGED
@@ -25,9 +25,10 @@ export declare function getUpdateInstruction(packageName: string): string;
25
25
  /**
26
26
  * Get the base directory for resolving package assets (themes, package.json, README.md, CHANGELOG.md).
27
27
  * - For Bun binary: returns the directory containing the executable
28
- * - For Node.js (dist/): returns __dirname (the dist/ directory)
29
- * - For tsx (src/): returns parent directory (the package root)
28
+ * - For Node.js and tsx: returns the package root containing package.json
29
+ * - Ignores Bun binary metadata copied into dist/ when the package root is available
30
30
  */
31
+ export declare function findNodePackageDir(startDir: string): string;
31
32
  export declare function getPackageDir(): string;
32
33
  /**
33
34
  * Get path to built-in themes directory (shipped with package)
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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","sourcesContent":["import { accessSync, constants, existsSync, readFileSync, realpathSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { basename, dirname, join, resolve, sep, win32 } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { getApexEnvironment } from \"./core/environment.ts\";\nimport { spawnProcessSync } from \"./utils/child-process.ts\";\nimport { normalizePath } from \"./utils/paths.ts\";\n\n// =============================================================================\n// Package Detection\n// =============================================================================\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Detect if we're running as a Bun compiled binary.\n * Bun binaries have import.meta.url containing \"$bunfs\", \"~BUN\", or \"%7EBUN\" (Bun's virtual filesystem path)\n */\nexport const isBunBinary =\n\timport.meta.url.includes(\"$bunfs\") || import.meta.url.includes(\"~BUN\") || import.meta.url.includes(\"%7EBUN\");\n\n/** Detect if Bun is the runtime (compiled binary or bun run) */\nexport const isBunRuntime = !!process.versions.bun;\n\n// =============================================================================\n// Install Method Detection\n// =============================================================================\n\nexport type InstallMethod = \"bun-binary\" | \"npm\" | \"pnpm\" | \"yarn\" | \"bun\" | \"unknown\";\n\ninterface SelfUpdateCommandStep {\n\tcommand: string;\n\targs: string[];\n\tdisplay: string;\n}\n\nexport interface SelfUpdateCommand extends SelfUpdateCommandStep {\n\tsteps?: SelfUpdateCommandStep[];\n}\n\nexport type SelfUpdatePackageTarget = string | { packageName: string; installSpec?: string };\n\nfunction normalizeSelfUpdatePackageTarget(target: SelfUpdatePackageTarget): {\n\tpackageName: string;\n\tinstallSpec: string;\n} {\n\tif (typeof target === \"string\") {\n\t\treturn { packageName: target, installSpec: target };\n\t}\n\treturn { packageName: target.packageName, installSpec: target.installSpec ?? target.packageName };\n}\n\nfunction makeSelfUpdateCommand(\n\tinstallStep: SelfUpdateCommandStep,\n\tuninstallStep?: SelfUpdateCommandStep,\n): SelfUpdateCommand {\n\tif (!uninstallStep) return installStep;\n\treturn {\n\t\t...installStep,\n\t\tdisplay: `${uninstallStep.display} && ${installStep.display}`,\n\t\tsteps: [uninstallStep, installStep],\n\t};\n}\n\nfunction makeSelfUpdateCommandStep(command: string, args: string[]): SelfUpdateCommandStep {\n\treturn {\n\t\tcommand,\n\t\targs,\n\t\tdisplay: [command, ...args].map((arg) => (/\\s/.test(arg) ? `\"${arg}\"` : arg)).join(\" \"),\n\t};\n}\n\nexport function detectInstallMethod(): InstallMethod {\n\tif (isBunBinary) {\n\t\treturn \"bun-binary\";\n\t}\n\n\tconst resolvedPath = `${__dirname}\\0${process.execPath || \"\"}`.toLowerCase().replace(/\\\\/g, \"/\");\n\n\tif (resolvedPath.includes(\"/pnpm/\") || resolvedPath.includes(\"/.pnpm/\")) {\n\t\treturn \"pnpm\";\n\t}\n\tif (resolvedPath.includes(\"/yarn/\") || resolvedPath.includes(\"/.yarn/\")) {\n\t\treturn \"yarn\";\n\t}\n\tif (isBunRuntime || resolvedPath.includes(\"/install/global/node_modules/\")) {\n\t\treturn \"bun\";\n\t}\n\tif (resolvedPath.includes(\"/npm/\") || resolvedPath.includes(\"/node_modules/\")) {\n\t\treturn \"npm\";\n\t}\n\n\treturn \"unknown\";\n}\n\nfunction getInferredNpmInstall(): { root: string; prefix: string } | undefined {\n\tconst packageDir = getPackageDir();\n\tconst path = process.platform === \"win32\" || packageDir.includes(\"\\\\\") ? win32 : { basename, dirname };\n\tconst parent = path.dirname(packageDir);\n\tlet root: string | undefined;\n\tif (path.basename(parent).startsWith(\"@\") && path.basename(path.dirname(parent)) === \"node_modules\") {\n\t\troot = path.dirname(parent);\n\t} else if (path.basename(parent) === \"node_modules\") {\n\t\troot = parent;\n\t}\n\tif (!root) return undefined;\n\tconst rootParent = path.dirname(root);\n\tif (path.basename(rootParent) === \"lib\") return { root, prefix: path.dirname(rootParent) };\n\t// Windows global npm prefixes use `<prefix>\\\\node_modules`, which is\n\t// indistinguishable from local project installs by path shape alone. Do not\n\t// infer unsupported Windows custom prefixes without `npm root -g` evidence.\n\treturn undefined;\n}\n\nfunction getSelfUpdateCommandForMethod(\n\tmethod: InstallMethod,\n\tinstalledPackageName: string,\n\tupdatePackageTarget: SelfUpdatePackageTarget = installedPackageName,\n\tnpmCommand?: string[],\n): SelfUpdateCommand | undefined {\n\tconst target = normalizeSelfUpdatePackageTarget(updatePackageTarget);\n\tswitch (method) {\n\t\tcase \"bun-binary\":\n\t\t\treturn undefined;\n\t\tcase \"pnpm\": {\n\t\t\tconst match = readCommandOutput(\"pnpm\", [\"root\", \"-g\"])\n\t\t\t\t? undefined\n\t\t\t\t: /^(.*[\\\\/]global[\\\\/][^\\\\/]+)[\\\\/]\\.pnpm[\\\\/]/.exec(getPackageDir());\n\t\t\tconst binDirArgs = match\n\t\t\t\t? [`--config.global-bin-dir=${process.env.PNPM_HOME || dirname(dirname(match[1]))}`]\n\t\t\t\t: [];\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"pnpm\", [\n\t\t\t\t\t\"install\",\n\t\t\t\t\t\"-g\",\n\t\t\t\t\t\"--ignore-scripts\",\n\t\t\t\t\t\"--config.minimumReleaseAge=0\",\n\t\t\t\t\t...binDirArgs,\n\t\t\t\t\ttarget.installSpec,\n\t\t\t\t]),\n\t\t\t\ttarget.packageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"pnpm\", [\"remove\", \"-g\", ...binDirArgs, installedPackageName]),\n\t\t\t);\n\t\t}\n\t\tcase \"yarn\":\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"yarn\", [\"global\", \"add\", \"--ignore-scripts\", target.installSpec]),\n\t\t\t\ttarget.packageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"yarn\", [\"global\", \"remove\", installedPackageName]),\n\t\t\t);\n\t\tcase \"bun\":\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"bun\", [\n\t\t\t\t\t\"install\",\n\t\t\t\t\t\"-g\",\n\t\t\t\t\t\"--ignore-scripts\",\n\t\t\t\t\t\"--minimum-release-age=0\",\n\t\t\t\t\ttarget.installSpec,\n\t\t\t\t]),\n\t\t\t\ttarget.packageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"bun\", [\"uninstall\", \"-g\", installedPackageName]),\n\t\t\t);\n\t\tcase \"npm\": {\n\t\t\tconst [command = \"npm\", ...npmArgs] = npmCommand ?? [];\n\t\t\tconst inferred = npmCommand?.length ? undefined : getInferredNpmInstall();\n\t\t\tconst prefixArgs = [...npmArgs, ...(inferred ? [\"--prefix\", inferred.prefix] : [])];\n\t\t\tconst installStep = makeSelfUpdateCommandStep(command, [\n\t\t\t\t...prefixArgs,\n\t\t\t\t\"install\",\n\t\t\t\t\"-g\",\n\t\t\t\t\"--ignore-scripts\",\n\t\t\t\t\"--min-release-age=0\",\n\t\t\t\ttarget.installSpec,\n\t\t\t]);\n\t\t\tconst uninstallStep =\n\t\t\t\ttarget.packageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(command, [...prefixArgs, \"uninstall\", \"-g\", installedPackageName]);\n\t\t\treturn makeSelfUpdateCommand(installStep, uninstallStep);\n\t\t}\n\t\tcase \"unknown\":\n\t\t\treturn undefined;\n\t}\n}\n\nfunction readCommandOutput(\n\tcommand: string,\n\targs: string[],\n\toptions: { requireSuccess?: boolean } = {},\n): string | undefined {\n\tconst result = spawnProcessSync(command, args, {\n\t\tencoding: \"utf-8\",\n\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t});\n\tif (result.status === 0) return result.stdout.trim() || undefined;\n\tif (options.requireSuccess) {\n\t\tconst reason = result.error?.message || result.stderr.trim() || `exit code ${result.status ?? \"unknown\"}`;\n\t\tthrow new Error(`Failed to run ${[command, ...args].join(\" \")}: ${reason}`);\n\t}\n\treturn undefined;\n}\n\nfunction getGlobalPackageRoots(method: InstallMethod, _packageName: string, npmCommand?: string[]): string[] {\n\tswitch (method) {\n\t\tcase \"npm\": {\n\t\t\tconst configured = !!npmCommand?.length;\n\t\t\tconst [command = \"npm\", ...npmArgs] = npmCommand ?? [];\n\t\t\tif (configured && command === \"bun\") {\n\t\t\t\tconst bunBin = readCommandOutput(command, [...npmArgs, \"pm\", \"bin\", \"-g\"], {\n\t\t\t\t\trequireSuccess: true,\n\t\t\t\t});\n\t\t\t\tconst roots = [join(homedir(), \".bun\", \"install\", \"global\", \"node_modules\")];\n\t\t\t\tif (bunBin) {\n\t\t\t\t\troots.push(join(dirname(bunBin), \"install\", \"global\", \"node_modules\"));\n\t\t\t\t}\n\t\t\t\treturn roots;\n\t\t\t}\n\t\t\tconst root = readCommandOutput(command, [...npmArgs, \"root\", \"-g\"], {\n\t\t\t\trequireSuccess: configured,\n\t\t\t});\n\t\t\tconst inferred = configured ? undefined : getInferredNpmInstall();\n\t\t\treturn [root, inferred?.root].filter((x): x is string => !!x);\n\t\t}\n\t\tcase \"pnpm\": {\n\t\t\tconst root = readCommandOutput(\"pnpm\", [\"root\", \"-g\"]);\n\t\t\tif (root) return [root, dirname(root)];\n\t\t\tconst match = /^(.*[\\\\/]global[\\\\/][^\\\\/]+)[\\\\/]\\.pnpm[\\\\/]/.exec(getPackageDir());\n\t\t\treturn match ? [match[1]] : [];\n\t\t}\n\t\tcase \"yarn\": {\n\t\t\tconst dir = readCommandOutput(\"yarn\", [\"global\", \"dir\"]);\n\t\t\treturn dir ? [dir, join(dir, \"node_modules\")] : [];\n\t\t}\n\t\tcase \"bun\": {\n\t\t\tconst bunBin = readCommandOutput(\"bun\", [\"pm\", \"bin\", \"-g\"]);\n\t\t\tconst roots = [join(homedir(), \".bun\", \"install\", \"global\", \"node_modules\")];\n\t\t\tif (bunBin) {\n\t\t\t\troots.push(join(dirname(bunBin), \"install\", \"global\", \"node_modules\"));\n\t\t\t}\n\t\t\treturn roots;\n\t\t}\n\t\tcase \"bun-binary\":\n\t\tcase \"unknown\":\n\t\t\treturn [];\n\t}\n}\n\nfunction normalizeExistingPathForComparison(path: string, resolveSymlinks: boolean): string | undefined {\n\tconst resolvedPath = resolve(path);\n\tif (!existsSync(resolvedPath)) {\n\t\treturn undefined;\n\t}\n\tlet normalizedPath = resolvedPath;\n\tif (resolveSymlinks) {\n\t\ttry {\n\t\t\tnormalizedPath = realpathSync(resolvedPath);\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\tif (process.platform === \"win32\") {\n\t\tnormalizedPath = normalizedPath.toLowerCase();\n\t}\n\treturn normalizedPath;\n}\n\nfunction getPathComparisonCandidates(path: string): string[] {\n\treturn Array.from(\n\t\tnew Set(\n\t\t\t[normalizeExistingPathForComparison(path, false), normalizeExistingPathForComparison(path, true)].filter(\n\t\t\t\t(candidate): candidate is string => !!candidate,\n\t\t\t),\n\t\t),\n\t);\n}\n\nfunction getEntrypointPackageDir(): string | undefined {\n\tconst entrypoint = process.argv[1];\n\tif (!entrypoint) return undefined;\n\tlet dir = dirname(entrypoint);\n\twhile (dir !== dirname(dir)) {\n\t\tif (existsSync(join(dir, \"package.json\"))) {\n\t\t\treturn dir;\n\t\t}\n\t\tdir = dirname(dir);\n\t}\n\treturn undefined;\n}\n\nfunction isSelfUpdatePathWritable(): boolean {\n\tconst packageDir = getPackageDir();\n\ttry {\n\t\taccessSync(packageDir, constants.W_OK);\n\t\taccessSync(dirname(packageDir), constants.W_OK);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction isManagedByGlobalPackageManager(method: InstallMethod, packageName: string, npmCommand?: string[]): boolean {\n\tconst packageDirs = [getPackageDir(), getEntrypointPackageDir()].filter((dir): dir is string => !!dir);\n\tconst packageDirCandidates = packageDirs.flatMap((dir) => getPathComparisonCandidates(dir));\n\treturn getGlobalPackageRoots(method, packageName, npmCommand).some((root) => {\n\t\treturn getPathComparisonCandidates(root).some((normalizedRoot) => {\n\t\t\tconst rootPrefix = normalizedRoot.endsWith(sep) ? normalizedRoot : `${normalizedRoot}${sep}`;\n\t\t\treturn packageDirCandidates.some((packageDir) => packageDir.startsWith(rootPrefix));\n\t\t});\n\t});\n}\n\nexport function getSelfUpdateCommand(\n\tpackageName: string,\n\tnpmCommand?: string[],\n\tupdatePackageTarget: SelfUpdatePackageTarget = packageName,\n): SelfUpdateCommand | undefined {\n\tconst method = detectInstallMethod();\n\tconst command = getSelfUpdateCommandForMethod(method, packageName, updatePackageTarget, npmCommand);\n\tif (!command || !isManagedByGlobalPackageManager(method, packageName, npmCommand) || !isSelfUpdatePathWritable()) {\n\t\treturn undefined;\n\t}\n\treturn command;\n}\n\nexport function getSelfUpdateUnavailableInstruction(\n\tpackageName: string,\n\tnpmCommand?: string[],\n\tupdatePackageTarget: SelfUpdatePackageTarget = packageName,\n): string {\n\tconst method = detectInstallMethod();\n\tconst target = normalizeSelfUpdatePackageTarget(updatePackageTarget);\n\tif (method === \"bun-binary\") {\n\t\treturn `This standalone binary is not connected to an Apex Code update channel. Install the supported npm package instead: npm install --global apex-code@next`;\n\t}\n\tconst command = getSelfUpdateCommandForMethod(method, packageName, target, npmCommand);\n\tif (command) {\n\t\tif (isManagedByGlobalPackageManager(method, packageName, npmCommand) && !isSelfUpdatePathWritable()) {\n\t\t\treturn `This installation is managed by a global ${method} install, but the install path is not writable. Update it yourself with: ${command.display}`;\n\t\t}\n\t\treturn `This installation is not managed by a global ${method} install. Update it with the package manager, wrapper, or source checkout that provides it.`;\n\t}\n\treturn `Update ${target.installSpec} using the package manager, wrapper, or source checkout that provides this installation.`;\n}\n\nexport function getUpdateInstruction(packageName: string): string {\n\tconst method = detectInstallMethod();\n\tconst command = getSelfUpdateCommandForMethod(method, packageName);\n\tif (command) {\n\t\treturn `Run: ${command.display}`;\n\t}\n\treturn getSelfUpdateUnavailableInstruction(packageName);\n}\n\n// =============================================================================\n// Package Asset Paths (shipped with executable)\n// =============================================================================\n\n/**\n * Get the base directory for resolving package assets (themes, package.json, README.md, CHANGELOG.md).\n * - For Bun binary: returns the directory containing the executable\n * - For Node.js (dist/): returns __dirname (the dist/ directory)\n * - For tsx (src/): returns parent directory (the package root)\n */\nexport function getPackageDir(): string {\n\t// Allow override via environment variable (useful for Nix/Guix where store paths tokenize poorly)\n\tconst envDir = getApexEnvironment(\"APEX_CODE_PACKAGE_DIR\");\n\tif (envDir) {\n\t\treturn normalizePath(envDir);\n\t}\n\n\tif (isBunBinary) {\n\t\t// Bun binary: process.execPath points to the compiled executable\n\t\treturn dirname(process.execPath);\n\t}\n\t// Node.js: walk up from __dirname until we find package.json\n\tlet dir = __dirname;\n\twhile (dir !== dirname(dir)) {\n\t\tif (existsSync(join(dir, \"package.json\"))) {\n\t\t\treturn dir;\n\t\t}\n\t\tdir = dirname(dir);\n\t}\n\t// Fallback (shouldn't happen)\n\treturn __dirname;\n}\n\n/**\n * Get path to built-in themes directory (shipped with package)\n * - For Bun binary: theme/ next to executable\n * - For Node.js (dist/): dist/modes/interactive/theme/\n * - For tsx (src/): src/modes/interactive/theme/\n */\nexport function getThemesDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"theme\");\n\t}\n\t// Theme is in modes/interactive/theme/ relative to src/ or dist/\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"modes\", \"interactive\", \"theme\");\n}\n\n/**\n * Get path to HTML export template directory (shipped with package)\n * - For Bun binary: export-html/ next to executable\n * - For Node.js (dist/): dist/core/export-html/\n * - For tsx (src/): src/core/export-html/\n */\nexport function getExportTemplateDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"export-html\");\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"core\", \"export-html\");\n}\n\n/** Get path to package.json */\nexport function getPackageJsonPath(): string {\n\treturn join(getPackageDir(), \"package.json\");\n}\n\n/** Get path to README.md */\nexport function getReadmePath(): string {\n\treturn resolve(join(getPackageDir(), \"README.md\"));\n}\n\n/** Get path to docs directory */\nexport function getDocsPath(): string {\n\treturn resolve(join(getPackageDir(), \"docs\"));\n}\n\n/** Get path to examples directory */\nexport function getExamplesPath(): string {\n\treturn resolve(join(getPackageDir(), \"examples\"));\n}\n\n/** Get path to CHANGELOG.md */\nexport function getChangelogPath(): string {\n\treturn resolve(join(getPackageDir(), \"CHANGELOG.md\"));\n}\n\n/**\n * Get path to built-in interactive assets directory.\n * - For Bun binary: assets/ next to executable\n * - For Node.js (dist/): dist/modes/interactive/assets/\n * - For tsx (src/): src/modes/interactive/assets/\n */\nexport function getInteractiveAssetsDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"assets\");\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"modes\", \"interactive\", \"assets\");\n}\n\n/** Get path to a bundled interactive asset */\nexport function getBundledInteractiveAssetPath(name: string): string {\n\treturn join(getInteractiveAssetsDir(), name);\n}\n\n// =============================================================================\n// App Config (from package.json piConfig)\n// =============================================================================\n\ninterface PackageJson {\n\tname?: string;\n\tversion?: string;\n\tpiConfig?: {\n\t\tname?: string;\n\t\tconfigDir?: string;\n\t};\n}\n\nlet pkg: PackageJson = {};\ntry {\n\tpkg = JSON.parse(readFileSync(getPackageJsonPath(), \"utf-8\")) as PackageJson;\n} catch (e: unknown) {\n\tconst err = e as NodeJS.ErrnoException;\n\tif (err.code !== \"ENOENT\") throw e;\n}\n\nconst piConfigName: string | undefined = pkg.piConfig?.name;\nexport const PACKAGE_NAME: string = pkg.name || \"apex-code\";\nexport const APP_NAME: string = piConfigName || \"apex-code\";\nexport const APP_TITLE: string = piConfigName ? APP_NAME : \"π\";\nexport const CONFIG_DIR_NAME: string = pkg.piConfig?.configDir || \".apex-code\";\nexport const VERSION: string = pkg.version || \"0.0.0\";\n\nconst ENV_PREFIX = APP_NAME.toUpperCase().replaceAll(/[^A-Z0-9]+/g, \"_\");\nexport const ENV_AGENT_DIR = `${ENV_PREFIX}_CODING_AGENT_DIR`;\nexport const ENV_SESSION_DIR = `${ENV_PREFIX}_CODING_AGENT_SESSION_DIR`;\n\nexport function expandTildePath(path: string): string {\n\treturn normalizePath(path);\n}\n\n/** Get the share viewer URL for a gist ID */\nexport function getShareViewerUrl(gistId: string): string | undefined {\n\tconst configured = getApexEnvironment(\"APEX_CODE_SHARE_VIEWER_URL\")?.trim();\n\tif (!configured) return undefined;\n\tconst viewer = new URL(configured);\n\tif (viewer.protocol !== \"https:\" && viewer.protocol !== \"http:\") {\n\t\tthrow new Error(\"APEX_CODE_SHARE_VIEWER_URL must use http or https\");\n\t}\n\tviewer.hash = encodeURIComponent(gistId);\n\treturn viewer.href;\n}\n\n// =============================================================================\n// User Config Paths (~/.apex-code/agent/*)\n// =============================================================================\n\n/** Get the agent config directory (e.g., ~/.apex-code/agent/) */\nexport function getAgentDir(): string {\n\tconst envDir = process.env[ENV_AGENT_DIR];\n\tif (envDir) {\n\t\treturn expandTildePath(envDir);\n\t}\n\treturn join(homedir(), CONFIG_DIR_NAME, \"agent\");\n}\n\n/** Get path to user's custom themes directory */\nexport function getCustomThemesDir(): string {\n\treturn join(getAgentDir(), \"themes\");\n}\n\n/** Get path to models.json */\nexport function getModelsPath(): string {\n\treturn join(getAgentDir(), \"models.json\");\n}\n\n/** Get path to auth.json. Sandboxed children may receive an explicit read-only projection. */\nexport function getAuthPath(): string {\n\treturn process.env.APEX_CODE_AUTH_PATH ?? join(getAgentDir(), \"auth.json\");\n}\n\n/** Get path to settings.json */\nexport function getSettingsPath(): string {\n\treturn join(getAgentDir(), \"settings.json\");\n}\n\n/** Get path to tools directory */\nexport function getToolsDir(): string {\n\treturn join(getAgentDir(), \"tools\");\n}\n\n/** Get path to managed binaries directory (fd, rg) */\nexport function getBinDir(): string {\n\treturn join(getAgentDir(), \"bin\");\n}\n\n/** Get path to prompt templates directory */\nexport function getPromptsDir(): string {\n\treturn join(getAgentDir(), \"prompts\");\n}\n\n/** Get path to sessions directory */\nexport function getSessionsDir(): string {\n\treturn join(getAgentDir(), \"sessions\");\n}\n\n/** Get path to debug log file */\nexport function getDebugLogPath(): string {\n\treturn join(getAgentDir(), `${APP_NAME}-debug.log`);\n}\n"]}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAiBA;;;GAGG;AACH,eAAO,MAAM,WAAW,SACqF,CAAC;AAE9G,gEAAgE;AAChE,eAAO,MAAM,YAAY,SAAyB,CAAC;AAMnD,MAAM,MAAM,aAAa,GAAG,YAAY,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;AAEvF,UAAU,qBAAqB;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAkB,SAAQ,qBAAqB;IAC/D,KAAK,CAAC,EAAE,qBAAqB,EAAE,CAAC;CAChC;AAED,MAAM,MAAM,uBAAuB,GAAG,MAAM,GAAG;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAgC7F,wBAAgB,mBAAmB,IAAI,aAAa,CAqBnD;AAiPD,wBAAgB,oBAAoB,CACnC,WAAW,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,MAAM,EAAE,EACrB,mBAAmB,GAAE,uBAAqC,GACxD,iBAAiB,GAAG,SAAS,CAO/B;AAED,wBAAgB,mCAAmC,CAClD,WAAW,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,MAAM,EAAE,EACrB,mBAAmB,GAAE,uBAAqC,GACxD,MAAM,CAcR;AAED,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAOhE;AAMD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAe3D;AAED,wBAAgB,aAAa,IAAI,MAAM,CAYtC;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAQrC;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAO7C;AAED,+BAA+B;AAC/B,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,4BAA4B;AAC5B,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,iCAAiC;AACjC,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,qCAAqC;AACrC,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,+BAA+B;AAC/B,wBAAgB,gBAAgB,IAAI,MAAM,CAEzC;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,CAOhD;AAED,8CAA8C;AAC9C,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnE;AAwBD,eAAO,MAAM,YAAY,EAAE,MAAgC,CAAC;AAC5D,eAAO,MAAM,QAAQ,EAAE,MAAoC,CAAC;AAC5D,eAAO,MAAM,SAAS,EAAE,MAAsC,CAAC;AAC/D,eAAO,MAAM,eAAe,EAAE,MAAgD,CAAC;AAC/E,eAAO,MAAM,OAAO,EAAE,MAA+B,CAAC;AAGtD,eAAO,MAAM,aAAa,QAAmC,CAAC;AAC9D,eAAO,MAAM,eAAe,QAA2C,CAAC;AAExE,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpD;AAED,6CAA6C;AAC7C,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CASpE;AAMD,iEAAiE;AACjE,wBAAgB,WAAW,IAAI,MAAM,CAMpC;AAED,iDAAiD;AACjD,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C;AAED,8BAA8B;AAC9B,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,8FAA8F;AAC9F,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,gCAAgC;AAChC,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,kCAAkC;AAClC,wBAAgB,WAAW,IAAI,MAAM,CAEpC;AAED,sDAAsD;AACtD,wBAAgB,SAAS,IAAI,MAAM,CAElC;AAED,6CAA6C;AAC7C,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,qCAAqC;AACrC,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,iCAAiC;AACjC,wBAAgB,eAAe,IAAI,MAAM,CAExC","sourcesContent":["import { spawnSync } from \"node:child_process\";\nimport { accessSync, constants, existsSync, readFileSync, realpathSync } from \"fs\";\nimport { homedir } from \"os\";\nimport { basename, dirname, join, resolve, sep, win32 } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { getApexEnvironment } from \"./core/environment.ts\";\nimport { spawnProcessSync } from \"./utils/child-process.ts\";\nimport { normalizePath } from \"./utils/paths.ts\";\nimport { stripBom } from \"./utils/text.ts\";\n\n// =============================================================================\n// Package Detection\n// =============================================================================\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Detect if we're running as a Bun compiled binary.\n * Bun binaries have import.meta.url containing \"$bunfs\", \"~BUN\", or \"%7EBUN\" (Bun's virtual filesystem path)\n */\nexport const isBunBinary =\n\timport.meta.url.includes(\"$bunfs\") || import.meta.url.includes(\"~BUN\") || import.meta.url.includes(\"%7EBUN\");\n\n/** Detect if Bun is the runtime (compiled binary or bun run) */\nexport const isBunRuntime = !!process.versions.bun;\n\n// =============================================================================\n// Install Method Detection\n// =============================================================================\n\nexport type InstallMethod = \"bun-binary\" | \"npm\" | \"pnpm\" | \"yarn\" | \"bun\" | \"unknown\";\n\ninterface SelfUpdateCommandStep {\n\tcommand: string;\n\targs: string[];\n\tdisplay: string;\n}\n\nexport interface SelfUpdateCommand extends SelfUpdateCommandStep {\n\tsteps?: SelfUpdateCommandStep[];\n}\n\nexport type SelfUpdatePackageTarget = string | { packageName: string; installSpec?: string };\n\nfunction normalizeSelfUpdatePackageTarget(target: SelfUpdatePackageTarget): {\n\tpackageName: string;\n\tinstallSpec: string;\n} {\n\tif (typeof target === \"string\") {\n\t\treturn { packageName: target, installSpec: target };\n\t}\n\treturn { packageName: target.packageName, installSpec: target.installSpec ?? target.packageName };\n}\n\nfunction makeSelfUpdateCommand(\n\tinstallStep: SelfUpdateCommandStep,\n\tuninstallStep?: SelfUpdateCommandStep,\n): SelfUpdateCommand {\n\tif (!uninstallStep) return installStep;\n\treturn {\n\t\t...installStep,\n\t\tdisplay: `${uninstallStep.display} && ${installStep.display}`,\n\t\tsteps: [uninstallStep, installStep],\n\t};\n}\n\nfunction makeSelfUpdateCommandStep(command: string, args: string[]): SelfUpdateCommandStep {\n\treturn {\n\t\tcommand,\n\t\targs,\n\t\tdisplay: [command, ...args].map((arg) => (/\\s/.test(arg) ? `\"${arg}\"` : arg)).join(\" \"),\n\t};\n}\n\nexport function detectInstallMethod(): InstallMethod {\n\tif (isBunBinary) {\n\t\treturn \"bun-binary\";\n\t}\n\n\tconst resolvedPath = `${__dirname}\\0${process.execPath || \"\"}`.toLowerCase().replace(/\\\\/g, \"/\");\n\n\tif (resolvedPath.includes(\"/pnpm/\") || resolvedPath.includes(\"/.pnpm/\")) {\n\t\treturn \"pnpm\";\n\t}\n\tif (resolvedPath.includes(\"/yarn/\") || resolvedPath.includes(\"/.yarn/\")) {\n\t\treturn \"yarn\";\n\t}\n\tif (isBunRuntime || resolvedPath.includes(\"/install/global/node_modules/\")) {\n\t\treturn \"bun\";\n\t}\n\tif (resolvedPath.includes(\"/npm/\") || resolvedPath.includes(\"/node_modules/\")) {\n\t\treturn \"npm\";\n\t}\n\n\treturn \"unknown\";\n}\n\nfunction getInferredNpmInstall(): { root: string; prefix: string } | undefined {\n\tconst packageDir = getPackageDir();\n\tconst path = process.platform === \"win32\" || packageDir.includes(\"\\\\\") ? win32 : { basename, dirname };\n\tconst parent = path.dirname(packageDir);\n\tlet root: string | undefined;\n\tif (path.basename(parent).startsWith(\"@\") && path.basename(path.dirname(parent)) === \"node_modules\") {\n\t\troot = path.dirname(parent);\n\t} else if (path.basename(parent) === \"node_modules\") {\n\t\troot = parent;\n\t}\n\tif (!root) return undefined;\n\tconst rootParent = path.dirname(root);\n\tif (path.basename(rootParent) === \"lib\") return { root, prefix: path.dirname(rootParent) };\n\t// Windows global npm prefixes use `<prefix>\\\\node_modules`, which is\n\t// indistinguishable from local project installs by path shape alone. Do not\n\t// infer unsupported Windows custom prefixes without `npm root -g` evidence.\n\treturn undefined;\n}\n\nfunction getSelfUpdateCommandForMethod(\n\tmethod: InstallMethod,\n\tinstalledPackageName: string,\n\tupdatePackageTarget: SelfUpdatePackageTarget = installedPackageName,\n\tnpmCommand?: string[],\n): SelfUpdateCommand | undefined {\n\tconst target = normalizeSelfUpdatePackageTarget(updatePackageTarget);\n\tswitch (method) {\n\t\tcase \"bun-binary\":\n\t\t\treturn undefined;\n\t\tcase \"pnpm\": {\n\t\t\tconst match = readCommandOutput(\"pnpm\", [\"root\", \"-g\"])\n\t\t\t\t? undefined\n\t\t\t\t: /^(.*[\\\\/]global[\\\\/][^\\\\/]+)[\\\\/]\\.pnpm[\\\\/]/.exec(getPackageDir());\n\t\t\tconst binDirArgs = match\n\t\t\t\t? [`--config.global-bin-dir=${process.env.PNPM_HOME || dirname(dirname(match[1]))}`]\n\t\t\t\t: [];\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"pnpm\", [\n\t\t\t\t\t\"install\",\n\t\t\t\t\t\"-g\",\n\t\t\t\t\t\"--ignore-scripts\",\n\t\t\t\t\t\"--config.minimumReleaseAge=0\",\n\t\t\t\t\t...binDirArgs,\n\t\t\t\t\ttarget.installSpec,\n\t\t\t\t]),\n\t\t\t\ttarget.packageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"pnpm\", [\"remove\", \"-g\", ...binDirArgs, installedPackageName]),\n\t\t\t);\n\t\t}\n\t\tcase \"yarn\":\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"yarn\", [\"global\", \"add\", \"--ignore-scripts\", target.installSpec]),\n\t\t\t\ttarget.packageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"yarn\", [\"global\", \"remove\", installedPackageName]),\n\t\t\t);\n\t\tcase \"bun\":\n\t\t\treturn makeSelfUpdateCommand(\n\t\t\t\tmakeSelfUpdateCommandStep(\"bun\", [\n\t\t\t\t\t\"install\",\n\t\t\t\t\t\"-g\",\n\t\t\t\t\t\"--ignore-scripts\",\n\t\t\t\t\t\"--minimum-release-age=0\",\n\t\t\t\t\ttarget.installSpec,\n\t\t\t\t]),\n\t\t\t\ttarget.packageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(\"bun\", [\"uninstall\", \"-g\", installedPackageName]),\n\t\t\t);\n\t\tcase \"npm\": {\n\t\t\tconst [command = \"npm\", ...npmArgs] = npmCommand ?? [];\n\t\t\tconst inferred = npmCommand?.length ? undefined : getInferredNpmInstall();\n\t\t\tconst prefixArgs = [...npmArgs, ...(inferred ? [\"--prefix\", inferred.prefix] : [])];\n\t\t\tconst installStep = makeSelfUpdateCommandStep(command, [\n\t\t\t\t...prefixArgs,\n\t\t\t\t\"install\",\n\t\t\t\t\"-g\",\n\t\t\t\t\"--ignore-scripts\",\n\t\t\t\t\"--min-release-age=0\",\n\t\t\t\ttarget.installSpec,\n\t\t\t]);\n\t\t\tconst uninstallStep =\n\t\t\t\ttarget.packageName === installedPackageName\n\t\t\t\t\t? undefined\n\t\t\t\t\t: makeSelfUpdateCommandStep(command, [...prefixArgs, \"uninstall\", \"-g\", installedPackageName]);\n\t\t\treturn makeSelfUpdateCommand(installStep, uninstallStep);\n\t\t}\n\t\tcase \"unknown\":\n\t\t\treturn undefined;\n\t}\n}\n\n/**\n * Quote one argument for a cmd.exe command line: only arguments containing\n * whitespace need quotes, and embedded quotes are doubled, which is the\n * convention cmd.exe itself documents for `if` comparisons.\n */\nfunction quoteWindowsCommandLineArgument(arg: string): string {\n\treturn /\\s/.test(arg) ? `\"${arg.replaceAll('\"', '\"\"')}\"` : arg;\n}\n\nfunction readCommandOutput(\n\tcommand: string,\n\targs: string[],\n\toptions: { requireSuccess?: boolean } = {},\n): string | undefined {\n\t// crossSpawn's win32 argument escaping drops positional args when the\n\t// command resolves to a .cmd shim: the shim runs, sees no %1/%2, and exits\n\t// 0 with no output (observed on windows-latest), which starves the\n\t// managed-install check of the global root it needs. Route win32 through\n\t// cmd.exe explicitly, where the shim receives its arguments intact.\n\tconst result =\n\t\tprocess.platform === \"win32\"\n\t\t\t? spawnSync(\"cmd.exe\", [\"/d\", \"/s\", \"/c\", [command, ...args].map(quoteWindowsCommandLineArgument).join(\" \")], {\n\t\t\t\t\tencoding: \"utf-8\",\n\t\t\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t\t\t})\n\t\t\t: spawnProcessSync(command, args, {\n\t\t\t\t\tencoding: \"utf-8\",\n\t\t\t\t\tstdio: [\"ignore\", \"pipe\", \"pipe\"],\n\t\t\t\t});\n\tif (result.status === 0) return result.stdout.trim() || undefined;\n\tif (options.requireSuccess) {\n\t\tconst reason = result.error?.message || result.stderr.trim() || `exit code ${result.status ?? \"unknown\"}`;\n\t\tthrow new Error(`Failed to run ${[command, ...args].join(\" \")}: ${reason}`);\n\t}\n\treturn undefined;\n}\n\nfunction getGlobalPackageRoots(method: InstallMethod, _packageName: string, npmCommand?: string[]): string[] {\n\tswitch (method) {\n\t\tcase \"npm\": {\n\t\t\tconst configured = !!npmCommand?.length;\n\t\t\tconst [command = \"npm\", ...npmArgs] = npmCommand ?? [];\n\t\t\tif (configured && command === \"bun\") {\n\t\t\t\tconst bunBin = readCommandOutput(command, [...npmArgs, \"pm\", \"bin\", \"-g\"], {\n\t\t\t\t\trequireSuccess: true,\n\t\t\t\t});\n\t\t\t\tconst roots = [join(homedir(), \".bun\", \"install\", \"global\", \"node_modules\")];\n\t\t\t\tif (bunBin) {\n\t\t\t\t\troots.push(join(dirname(bunBin), \"install\", \"global\", \"node_modules\"));\n\t\t\t\t}\n\t\t\t\treturn roots;\n\t\t\t}\n\t\t\tconst root = readCommandOutput(command, [...npmArgs, \"root\", \"-g\"], {\n\t\t\t\trequireSuccess: configured,\n\t\t\t});\n\t\t\tconst inferred = configured ? undefined : getInferredNpmInstall();\n\t\t\treturn [root, inferred?.root].filter((x): x is string => !!x);\n\t\t}\n\t\tcase \"pnpm\": {\n\t\t\tconst root = readCommandOutput(\"pnpm\", [\"root\", \"-g\"]);\n\t\t\tif (root) return [root, dirname(root)];\n\t\t\tconst match = /^(.*[\\\\/]global[\\\\/][^\\\\/]+)[\\\\/]\\.pnpm[\\\\/]/.exec(getPackageDir());\n\t\t\treturn match ? [match[1]] : [];\n\t\t}\n\t\tcase \"yarn\": {\n\t\t\tconst dir = readCommandOutput(\"yarn\", [\"global\", \"dir\"]);\n\t\t\treturn dir ? [dir, join(dir, \"node_modules\")] : [];\n\t\t}\n\t\tcase \"bun\": {\n\t\t\tconst bunBin = readCommandOutput(\"bun\", [\"pm\", \"bin\", \"-g\"]);\n\t\t\tconst roots = [join(homedir(), \".bun\", \"install\", \"global\", \"node_modules\")];\n\t\t\tif (bunBin) {\n\t\t\t\troots.push(join(dirname(bunBin), \"install\", \"global\", \"node_modules\"));\n\t\t\t}\n\t\t\treturn roots;\n\t\t}\n\t\tcase \"bun-binary\":\n\t\tcase \"unknown\":\n\t\t\treturn [];\n\t}\n}\n\nfunction normalizeExistingPathForComparison(path: string, resolveSymlinks: boolean): string | undefined {\n\tconst resolvedPath = resolve(path);\n\tif (!existsSync(resolvedPath)) {\n\t\treturn undefined;\n\t}\n\tlet normalizedPath = resolvedPath;\n\tif (resolveSymlinks) {\n\t\ttry {\n\t\t\tnormalizedPath = realpathSync(resolvedPath);\n\t\t} catch {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\tif (process.platform === \"win32\") {\n\t\tnormalizedPath = normalizedPath.toLowerCase();\n\t}\n\treturn normalizedPath;\n}\n\nfunction getPathComparisonCandidates(path: string): string[] {\n\treturn Array.from(\n\t\tnew Set(\n\t\t\t[normalizeExistingPathForComparison(path, false), normalizeExistingPathForComparison(path, true)].filter(\n\t\t\t\t(candidate): candidate is string => !!candidate,\n\t\t\t),\n\t\t),\n\t);\n}\n\nfunction getEntrypointPackageDir(): string | undefined {\n\tconst entrypoint = process.argv[1];\n\tif (!entrypoint) return undefined;\n\tlet dir = dirname(entrypoint);\n\twhile (dir !== dirname(dir)) {\n\t\tif (existsSync(join(dir, \"package.json\"))) {\n\t\t\treturn dir;\n\t\t}\n\t\tdir = dirname(dir);\n\t}\n\treturn undefined;\n}\n\nfunction isSelfUpdatePathWritable(): boolean {\n\tconst packageDir = getPackageDir();\n\ttry {\n\t\taccessSync(packageDir, constants.W_OK);\n\t\taccessSync(dirname(packageDir), constants.W_OK);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nfunction isManagedByGlobalPackageManager(method: InstallMethod, packageName: string, npmCommand?: string[]): boolean {\n\tconst packageDirs = [getPackageDir(), getEntrypointPackageDir()].filter((dir): dir is string => !!dir);\n\tconst packageDirCandidates = packageDirs.flatMap((dir) => getPathComparisonCandidates(dir));\n\treturn getGlobalPackageRoots(method, packageName, npmCommand).some((root) => {\n\t\treturn getPathComparisonCandidates(root).some((normalizedRoot) => {\n\t\t\tconst rootPrefix = normalizedRoot.endsWith(sep) ? normalizedRoot : `${normalizedRoot}${sep}`;\n\t\t\treturn packageDirCandidates.some((packageDir) => packageDir.startsWith(rootPrefix));\n\t\t});\n\t});\n}\n\nexport function getSelfUpdateCommand(\n\tpackageName: string,\n\tnpmCommand?: string[],\n\tupdatePackageTarget: SelfUpdatePackageTarget = packageName,\n): SelfUpdateCommand | undefined {\n\tconst method = detectInstallMethod();\n\tconst command = getSelfUpdateCommandForMethod(method, packageName, updatePackageTarget, npmCommand);\n\tif (!command || !isManagedByGlobalPackageManager(method, packageName, npmCommand) || !isSelfUpdatePathWritable()) {\n\t\treturn undefined;\n\t}\n\treturn command;\n}\n\nexport function getSelfUpdateUnavailableInstruction(\n\tpackageName: string,\n\tnpmCommand?: string[],\n\tupdatePackageTarget: SelfUpdatePackageTarget = packageName,\n): string {\n\tconst method = detectInstallMethod();\n\tconst target = normalizeSelfUpdatePackageTarget(updatePackageTarget);\n\tif (method === \"bun-binary\") {\n\t\treturn `This standalone binary is not connected to an Apex Code update channel. Install the supported npm package instead: npm install --global apex-code`;\n\t}\n\tconst command = getSelfUpdateCommandForMethod(method, packageName, target, npmCommand);\n\tif (command) {\n\t\tif (isManagedByGlobalPackageManager(method, packageName, npmCommand) && !isSelfUpdatePathWritable()) {\n\t\t\treturn `This installation is managed by a global ${method} install, but the install path is not writable. Update it yourself with: ${command.display}`;\n\t\t}\n\t\treturn `This installation is not managed by a global ${method} install. Update it with the package manager, wrapper, or source checkout that provides it.`;\n\t}\n\treturn `Update ${target.installSpec} using the package manager, wrapper, or source checkout that provides this installation.`;\n}\n\nexport function getUpdateInstruction(packageName: string): string {\n\tconst method = detectInstallMethod();\n\tconst command = getSelfUpdateCommandForMethod(method, packageName);\n\tif (command) {\n\t\treturn `Run: ${command.display}`;\n\t}\n\treturn getSelfUpdateUnavailableInstruction(packageName);\n}\n\n// =============================================================================\n// Package Asset Paths (shipped with executable)\n// =============================================================================\n\n/**\n * Get the base directory for resolving package assets (themes, package.json, README.md, CHANGELOG.md).\n * - For Bun binary: returns the directory containing the executable\n * - For Node.js and tsx: returns the package root containing package.json\n * - Ignores Bun binary metadata copied into dist/ when the package root is available\n */\nexport function findNodePackageDir(startDir: string): string {\n\tlet dir = startDir;\n\twhile (dir !== dirname(dir)) {\n\t\tif (existsSync(join(dir, \"package.json\"))) {\n\t\t\tconst parent = dirname(dir);\n\t\t\t// build:binary places Bun's metadata inside dist/. Node still needs the\n\t\t\t// package root so its dist-relative asset paths do not become dist/dist/.\n\t\t\tif (basename(dir) === \"dist\" && existsSync(join(parent, \"package.json\"))) {\n\t\t\t\treturn parent;\n\t\t\t}\n\t\t\treturn dir;\n\t\t}\n\t\tdir = dirname(dir);\n\t}\n\treturn startDir;\n}\n\nexport function getPackageDir(): string {\n\t// Allow override via environment variable (useful for Nix/Guix where store paths tokenize poorly)\n\tconst envDir = getApexEnvironment(\"APEX_CODE_PACKAGE_DIR\");\n\tif (envDir) {\n\t\treturn normalizePath(envDir);\n\t}\n\n\tif (isBunBinary) {\n\t\t// Bun binary: process.execPath points to the compiled executable\n\t\treturn dirname(process.execPath);\n\t}\n\treturn findNodePackageDir(__dirname);\n}\n\n/**\n * Get path to built-in themes directory (shipped with package)\n * - For Bun binary: theme/ next to executable\n * - For Node.js (dist/): dist/modes/interactive/theme/\n * - For tsx (src/): src/modes/interactive/theme/\n */\nexport function getThemesDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"theme\");\n\t}\n\t// Theme is in modes/interactive/theme/ relative to src/ or dist/\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"modes\", \"interactive\", \"theme\");\n}\n\n/**\n * Get path to HTML export template directory (shipped with package)\n * - For Bun binary: export-html/ next to executable\n * - For Node.js (dist/): dist/core/export-html/\n * - For tsx (src/): src/core/export-html/\n */\nexport function getExportTemplateDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"export-html\");\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"core\", \"export-html\");\n}\n\n/** Get path to package.json */\nexport function getPackageJsonPath(): string {\n\treturn join(getPackageDir(), \"package.json\");\n}\n\n/** Get path to README.md */\nexport function getReadmePath(): string {\n\treturn resolve(join(getPackageDir(), \"README.md\"));\n}\n\n/** Get path to docs directory */\nexport function getDocsPath(): string {\n\treturn resolve(join(getPackageDir(), \"docs\"));\n}\n\n/** Get path to examples directory */\nexport function getExamplesPath(): string {\n\treturn resolve(join(getPackageDir(), \"examples\"));\n}\n\n/** Get path to CHANGELOG.md */\nexport function getChangelogPath(): string {\n\treturn resolve(join(getPackageDir(), \"CHANGELOG.md\"));\n}\n\n/**\n * Get path to built-in interactive assets directory.\n * - For Bun binary: assets/ next to executable\n * - For Node.js (dist/): dist/modes/interactive/assets/\n * - For tsx (src/): src/modes/interactive/assets/\n */\nexport function getInteractiveAssetsDir(): string {\n\tif (isBunBinary) {\n\t\treturn join(getPackageDir(), \"assets\");\n\t}\n\tconst packageDir = getPackageDir();\n\tconst srcOrDist = existsSync(join(packageDir, \"src\")) ? \"src\" : \"dist\";\n\treturn join(packageDir, srcOrDist, \"modes\", \"interactive\", \"assets\");\n}\n\n/** Get path to a bundled interactive asset */\nexport function getBundledInteractiveAssetPath(name: string): string {\n\treturn join(getInteractiveAssetsDir(), name);\n}\n\n// =============================================================================\n// App Config (from package.json piConfig)\n// =============================================================================\n\ninterface PackageJson {\n\tname?: string;\n\tversion?: string;\n\tpiConfig?: {\n\t\tname?: string;\n\t\tconfigDir?: string;\n\t};\n}\n\nlet pkg: PackageJson = {};\ntry {\n\tpkg = JSON.parse(stripBom(readFileSync(getPackageJsonPath(), \"utf-8\"))) as PackageJson;\n} catch (e: unknown) {\n\tconst err = e as NodeJS.ErrnoException;\n\tif (err.code !== \"ENOENT\") throw e;\n}\n\nconst piConfigName: string | undefined = pkg.piConfig?.name;\nexport const PACKAGE_NAME: string = pkg.name || \"apex-code\";\nexport const APP_NAME: string = piConfigName || \"apex-code\";\nexport const APP_TITLE: string = piConfigName ? APP_NAME : \"π\";\nexport const CONFIG_DIR_NAME: string = pkg.piConfig?.configDir || \".apex-code\";\nexport const VERSION: string = pkg.version || \"0.0.0\";\n\nconst ENV_PREFIX = APP_NAME.toUpperCase().replaceAll(/[^A-Z0-9]+/g, \"_\");\nexport const ENV_AGENT_DIR = `${ENV_PREFIX}_CODING_AGENT_DIR`;\nexport const ENV_SESSION_DIR = `${ENV_PREFIX}_CODING_AGENT_SESSION_DIR`;\n\nexport function expandTildePath(path: string): string {\n\treturn normalizePath(path);\n}\n\n/** Get the share viewer URL for a gist ID */\nexport function getShareViewerUrl(gistId: string): string | undefined {\n\tconst configured = getApexEnvironment(\"APEX_CODE_SHARE_VIEWER_URL\")?.trim();\n\tif (!configured) return undefined;\n\tconst viewer = new URL(configured);\n\tif (viewer.protocol !== \"https:\" && viewer.protocol !== \"http:\") {\n\t\tthrow new Error(\"APEX_CODE_SHARE_VIEWER_URL must use http or https\");\n\t}\n\tviewer.hash = encodeURIComponent(gistId);\n\treturn viewer.href;\n}\n\n// =============================================================================\n// User Config Paths (~/.apex-code/agent/*)\n// =============================================================================\n\n/** Get the agent config directory (e.g., ~/.apex-code/agent/) */\nexport function getAgentDir(): string {\n\tconst envDir = process.env[ENV_AGENT_DIR];\n\tif (envDir) {\n\t\treturn expandTildePath(envDir);\n\t}\n\treturn join(homedir(), CONFIG_DIR_NAME, \"agent\");\n}\n\n/** Get path to user's custom themes directory */\nexport function getCustomThemesDir(): string {\n\treturn join(getAgentDir(), \"themes\");\n}\n\n/** Get path to models.json */\nexport function getModelsPath(): string {\n\treturn join(getAgentDir(), \"models.json\");\n}\n\n/** Get path to auth.json. Sandboxed children may receive an explicit read-only projection. */\nexport function getAuthPath(): string {\n\treturn process.env.APEX_CODE_AUTH_PATH ?? join(getAgentDir(), \"auth.json\");\n}\n\n/** Get path to settings.json */\nexport function getSettingsPath(): string {\n\treturn join(getAgentDir(), \"settings.json\");\n}\n\n/** Get path to tools directory */\nexport function getToolsDir(): string {\n\treturn join(getAgentDir(), \"tools\");\n}\n\n/** Get path to managed binaries directory (fd, rg) */\nexport function getBinDir(): string {\n\treturn join(getAgentDir(), \"bin\");\n}\n\n/** Get path to prompt templates directory */\nexport function getPromptsDir(): string {\n\treturn join(getAgentDir(), \"prompts\");\n}\n\n/** Get path to sessions directory */\nexport function getSessionsDir(): string {\n\treturn join(getAgentDir(), \"sessions\");\n}\n\n/** Get path to debug log file */\nexport function getDebugLogPath(): string {\n\treturn join(getAgentDir(), `${APP_NAME}-debug.log`);\n}\n"]}
package/dist/config.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { spawnSync } from "node:child_process";
1
2
  import { accessSync, constants, existsSync, readFileSync, realpathSync } from "fs";
2
3
  import { homedir } from "os";
3
4
  import { basename, dirname, join, resolve, sep, win32 } from "path";
@@ -5,6 +6,7 @@ import { fileURLToPath } from "url";
5
6
  import { getApexEnvironment } from "./core/environment.js";
6
7
  import { spawnProcessSync } from "./utils/child-process.js";
7
8
  import { normalizePath } from "./utils/paths.js";
9
+ import { stripBom } from "./utils/text.js";
8
10
  // =============================================================================
9
11
  // Package Detection
10
12
  // =============================================================================
@@ -137,11 +139,29 @@ function getSelfUpdateCommandForMethod(method, installedPackageName, updatePacka
137
139
  return undefined;
138
140
  }
139
141
  }
142
+ /**
143
+ * Quote one argument for a cmd.exe command line: only arguments containing
144
+ * whitespace need quotes, and embedded quotes are doubled, which is the
145
+ * convention cmd.exe itself documents for `if` comparisons.
146
+ */
147
+ function quoteWindowsCommandLineArgument(arg) {
148
+ return /\s/.test(arg) ? `"${arg.replaceAll('"', '""')}"` : arg;
149
+ }
140
150
  function readCommandOutput(command, args, options = {}) {
141
- const result = spawnProcessSync(command, args, {
142
- encoding: "utf-8",
143
- stdio: ["ignore", "pipe", "pipe"],
144
- });
151
+ // crossSpawn's win32 argument escaping drops positional args when the
152
+ // command resolves to a .cmd shim: the shim runs, sees no %1/%2, and exits
153
+ // 0 with no output (observed on windows-latest), which starves the
154
+ // managed-install check of the global root it needs. Route win32 through
155
+ // cmd.exe explicitly, where the shim receives its arguments intact.
156
+ const result = process.platform === "win32"
157
+ ? spawnSync("cmd.exe", ["/d", "/s", "/c", [command, ...args].map(quoteWindowsCommandLineArgument).join(" ")], {
158
+ encoding: "utf-8",
159
+ stdio: ["ignore", "pipe", "pipe"],
160
+ })
161
+ : spawnProcessSync(command, args, {
162
+ encoding: "utf-8",
163
+ stdio: ["ignore", "pipe", "pipe"],
164
+ });
145
165
  if (result.status === 0)
146
166
  return result.stdout.trim() || undefined;
147
167
  if (options.requireSuccess) {
@@ -263,7 +283,7 @@ export function getSelfUpdateUnavailableInstruction(packageName, npmCommand, upd
263
283
  const method = detectInstallMethod();
264
284
  const target = normalizeSelfUpdatePackageTarget(updatePackageTarget);
265
285
  if (method === "bun-binary") {
266
- return `This standalone binary is not connected to an Apex Code update channel. Install the supported npm package instead: npm install --global apex-code@next`;
286
+ return `This standalone binary is not connected to an Apex Code update channel. Install the supported npm package instead: npm install --global apex-code`;
267
287
  }
268
288
  const command = getSelfUpdateCommandForMethod(method, packageName, target, npmCommand);
269
289
  if (command) {
@@ -288,9 +308,25 @@ export function getUpdateInstruction(packageName) {
288
308
  /**
289
309
  * Get the base directory for resolving package assets (themes, package.json, README.md, CHANGELOG.md).
290
310
  * - For Bun binary: returns the directory containing the executable
291
- * - For Node.js (dist/): returns __dirname (the dist/ directory)
292
- * - For tsx (src/): returns parent directory (the package root)
311
+ * - For Node.js and tsx: returns the package root containing package.json
312
+ * - Ignores Bun binary metadata copied into dist/ when the package root is available
293
313
  */
314
+ export function findNodePackageDir(startDir) {
315
+ let dir = startDir;
316
+ while (dir !== dirname(dir)) {
317
+ if (existsSync(join(dir, "package.json"))) {
318
+ const parent = dirname(dir);
319
+ // build:binary places Bun's metadata inside dist/. Node still needs the
320
+ // package root so its dist-relative asset paths do not become dist/dist/.
321
+ if (basename(dir) === "dist" && existsSync(join(parent, "package.json"))) {
322
+ return parent;
323
+ }
324
+ return dir;
325
+ }
326
+ dir = dirname(dir);
327
+ }
328
+ return startDir;
329
+ }
294
330
  export function getPackageDir() {
295
331
  // Allow override via environment variable (useful for Nix/Guix where store paths tokenize poorly)
296
332
  const envDir = getApexEnvironment("APEX_CODE_PACKAGE_DIR");
@@ -301,16 +337,7 @@ export function getPackageDir() {
301
337
  // Bun binary: process.execPath points to the compiled executable
302
338
  return dirname(process.execPath);
303
339
  }
304
- // Node.js: walk up from __dirname until we find package.json
305
- let dir = __dirname;
306
- while (dir !== dirname(dir)) {
307
- if (existsSync(join(dir, "package.json"))) {
308
- return dir;
309
- }
310
- dir = dirname(dir);
311
- }
312
- // Fallback (shouldn't happen)
313
- return __dirname;
340
+ return findNodePackageDir(__dirname);
314
341
  }
315
342
  /**
316
343
  * Get path to built-in themes directory (shipped with package)
@@ -381,7 +408,7 @@ export function getBundledInteractiveAssetPath(name) {
381
408
  }
382
409
  let pkg = {};
383
410
  try {
384
- pkg = JSON.parse(readFileSync(getPackageJsonPath(), "utf-8"));
411
+ pkg = JSON.parse(stripBom(readFileSync(getPackageJsonPath(), "utf-8")));
385
412
  }
386
413
  catch (e) {
387
414
  const err = e;