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
@@ -12,31 +12,40 @@
12
12
  *
13
13
  * Modes use this class and add their own I/O layer on top.
14
14
  */
15
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
15
+ import { readFileSync } from "node:fs";
16
16
  import { basename, dirname } from "node:path";
17
17
  import { contentText } from "@earendil-works/pi-ai";
18
- import { clampThinkingLevel, cleanupSessionResources, getSupportedThinkingLevels, isContextOverflow, isRecoverableLength, isRetryableAssistantError, modelsAreEqual, resetApiProviders, streamSimple, } from "@earendil-works/pi-ai/compat";
18
+ import { clampThinkingLevel, cleanupSessionResources, getSupportedThinkingLevels, isContextOverflow, isRecoverableLength, isRetryableAssistantError, modelsAreEqual, resetApiProviders, } from "@earendil-works/pi-ai/compat";
19
19
  import { getThemeByName, theme } from "../modes/interactive/theme/theme.js";
20
20
  import { stripFrontmatter } from "../utils/frontmatter.js";
21
- import { resolvePath } from "../utils/paths.js";
22
21
  import { sleep } from "../utils/sleep.js";
23
22
  import { normalizeToolResultImages } from "../utils/tool-result-images.js";
24
23
  import { formatNoApiKeyFoundMessage, formatNoModelSelectedMessage } from "./auth-guidance.js";
25
24
  import { executeBashWithOperations } from "./bash-executor.js";
26
25
  import { calculateContextTokens, collectEntriesForBranchSummary, compact, estimateContextTokens, estimateTokens, generateBranchSummary, prepareCompaction, shouldCompact, } from "./compaction/index.js";
27
- import { DEFAULT_THINKING_LEVEL } from "./defaults.js";
26
+ import { evictionBudget, installContextPipeline, isDefaultStreamFunction } from "./context/pipeline.js";
27
+ import { DEFAULT_THINKING_LEVEL, THINKING_LEVEL_OPTIONS } from "./defaults.js";
28
+ import { SessionEvidenceSink } from "./evidence.js";
28
29
  import { exportSessionToHtml } from "./export-html/index.js";
29
30
  import { createToolHtmlRenderer } from "./export-html/tool-renderer.js";
30
31
  import { ExtensionRunner, wrapRegisteredTools, } from "./extensions/index.js";
31
32
  import { emitSessionShutdownEvent } from "./extensions/runner.js";
32
33
  import { ModelRegistry } from "./model-registry.js";
34
+ import { evaluateToolCall } from "./permissions/gate.js";
35
+ import { createInteractiveResponder } from "./permissions/responder.js";
36
+ import { resolveEffectiveModeWithOrigin } from "./permissions/startup.js";
33
37
  import { expandPromptTemplate } from "./prompt-templates.js";
34
- import { CURRENT_SESSION_VERSION, getLatestCompactionEntry } from "./session-manager.js";
38
+ import { exportSessionToJsonl } from "./session-export.js";
39
+ import { getLatestCompactionEntry, TODO_CUSTOM_ENTRY_TYPE } from "./session-manager.js";
40
+ import { slugifySkillCommandName } from "./skills.js";
35
41
  import { createSyntheticSourceInfo } from "./source-info.js";
36
42
  import { buildSystemPrompt } from "./system-prompt.js";
37
43
  import { createLocalBashOperations } from "./tools/bash.js";
38
44
  import { createAllToolDefinitions } from "./tools/index.js";
45
+ import { createSkillSearchToolDefinition } from "./tools/skill-search.js";
46
+ import { createTodoWriteToolDefinition } from "./tools/todo-write.js";
39
47
  import { createToolDefinitionFromAgentTool } from "./tools/tool-definition-wrapper.js";
48
+ import { createToolSchemaToolDefinition } from "./tools/tool-schema.js";
40
49
  import { addUsageToTotals, createUsageTotals } from "./usage-totals.js";
41
50
  /**
42
51
  * Parse a skill block from message text.
@@ -71,8 +80,6 @@ function estimateMessagesTokens(messages) {
71
80
  // ============================================================================
72
81
  // Constants
73
82
  // ============================================================================
74
- /** Standard thinking levels */
75
- const THINKING_LEVELS = ["off", "minimal", "low", "medium", "high"];
76
83
  // ============================================================================
77
84
  // AgentSession Class
78
85
  // ============================================================================
@@ -118,6 +125,11 @@ export class AgentSession {
118
125
  _excludedToolNames;
119
126
  _baseToolsOverride;
120
127
  _sessionStartEvent;
128
+ _permissionGate;
129
+ _evidenceSink;
130
+ _diagnosticsOperations;
131
+ _lspOperations;
132
+ _webSearchOperations;
121
133
  _extensionUIContext;
122
134
  _extensionMode = "print";
123
135
  _extensionCommandContextActions;
@@ -131,6 +143,7 @@ export class AgentSession {
131
143
  _toolDefinitions = new Map();
132
144
  _toolPromptSnippets = new Map();
133
145
  _toolPromptGuidelines = new Map();
146
+ _loadedDeferredSchemas = new Set();
134
147
  // Base system prompt (without extension appends) - used to apply fresh appends each turn
135
148
  _baseSystemPrompt = "";
136
149
  _baseSystemPromptOptions;
@@ -150,11 +163,17 @@ export class AgentSession {
150
163
  this._excludedToolNames = config.excludedToolNames ? new Set(config.excludedToolNames) : undefined;
151
164
  this._baseToolsOverride = config.baseToolsOverride;
152
165
  this._sessionStartEvent = config.sessionStartEvent ?? { type: "session_start", reason: "startup" };
166
+ this._permissionGate = config.permissionGate;
167
+ this._evidenceSink = config.evidenceSink ?? new SessionEvidenceSink(this.sessionManager);
168
+ this._diagnosticsOperations = config.diagnosticsOperations;
169
+ this._lspOperations = config.lspOperations;
170
+ this._webSearchOperations = config.webSearchOperations;
153
171
  // Always subscribe to agent events for internal handling
154
172
  // (session persistence, extensions, auto-compaction, retry logic)
155
173
  this._unsubscribeAgent = this.agent.subscribe(this._handleAgentEvent);
156
174
  this._installAgentToolHooks();
157
175
  this._installAgentNextTurnRefresh();
176
+ this._installContextPipeline();
158
177
  this._buildRuntime({
159
178
  activeToolNames: this._initialActiveToolNames,
160
179
  includeAllExtensionTools: true,
@@ -193,7 +212,7 @@ export class AgentSession {
193
212
  throw new Error(formatNoApiKeyFoundMessage(model.provider));
194
213
  }
195
214
  async _getSummarizationRequestAuth(model) {
196
- if (this.agent.streamFunction === streamSimple) {
215
+ if (isDefaultStreamFunction(this.agent.streamFunction)) {
197
216
  return this._getRequiredRequestAuth(model);
198
217
  }
199
218
  try {
@@ -223,25 +242,63 @@ export class AgentSession {
223
242
  _installAgentToolHooks() {
224
243
  this.agent.beforeToolCall = async ({ toolCall, args }) => {
225
244
  const runner = this._extensionRunner;
226
- if (!runner.hasHandlers("tool_call")) {
227
- return undefined;
228
- }
229
- try {
230
- return await runner.emitToolCall({
231
- type: "tool_call",
232
- toolName: toolCall.name,
233
- toolCallId: toolCall.id,
234
- input: args,
235
- });
236
- }
237
- catch (err) {
238
- if (err instanceof Error) {
239
- throw err;
245
+ if (runner.hasHandlers("tool_call")) {
246
+ let extensionResult;
247
+ try {
248
+ extensionResult = await runner.emitToolCall({
249
+ type: "tool_call",
250
+ toolName: toolCall.name,
251
+ toolCallId: toolCall.id,
252
+ input: args,
253
+ });
254
+ }
255
+ catch (err) {
256
+ if (err instanceof Error) {
257
+ throw err;
258
+ }
259
+ throw new Error(`Extension failed, blocking execution: ${String(err)}`);
240
260
  }
241
- throw new Error(`Extension failed, blocking execution: ${String(err)}`);
261
+ // A blocking extension remains authoritative. A non-blocking result
262
+ // (including a mutation-only `{}`) must still pass the permission gate,
263
+ // which evaluates the extension's final input below.
264
+ if (extensionResult?.block === true)
265
+ return extensionResult;
266
+ }
267
+ // Permission gate (roadmap Phase 2a, ADR 0004). Off by default — see
268
+ // AgentSessionConfig.permissionGate. When present, every registered tool
269
+ // call passes through it (contracts.md invariant 2): this is the seam,
270
+ // not a per-tool opt-in.
271
+ if (this._permissionGate) {
272
+ const decision = await evaluateToolCall(toolCall.name, args, {
273
+ ...this._permissionGate,
274
+ getContract: (name) => this.getToolDefinition(name)?.contract,
275
+ getResponder: () => this._extensionMode === "tui" && this._extensionUIContext
276
+ ? createInteractiveResponder(this._extensionUIContext)
277
+ : undefined,
278
+ });
279
+ if (decision.block)
280
+ return { block: true, reason: decision.reason };
242
281
  }
282
+ return undefined;
243
283
  };
244
284
  this.agent.afterToolCall = async ({ toolCall, args, result, isError }) => {
285
+ const definition = this.getToolDefinition(toolCall.name);
286
+ if (this._evidenceSink && definition?.contract) {
287
+ try {
288
+ const records = definition.contract.evidence.capture(args, result);
289
+ if (!records.every((record) => definition.contract?.evidence.emits.has(record.kind))) {
290
+ throw new Error("Evidence capture emitted a kind not declared by its tool contract");
291
+ }
292
+ if (records.length > 0)
293
+ this._evidenceSink.record({ toolName: toolCall.name, records });
294
+ }
295
+ catch (error) {
296
+ this._evidenceSink.recordDiagnostic?.({
297
+ toolName: toolCall.name,
298
+ reason: error instanceof Error ? error.message : String(error),
299
+ });
300
+ }
301
+ }
245
302
  const runner = this._extensionRunner;
246
303
  const hookResult = runner.hasHandlers("tool_result")
247
304
  ? await runner.emitToolResult({
@@ -291,6 +348,46 @@ export class AgentSession {
291
348
  };
292
349
  };
293
350
  }
351
+ /**
352
+ * Installs the context pipeline settled in `docs/architecture/contracts.md` § 2:
353
+ * deferred-schema resolution → tool-result eviction → compaction. Compaction
354
+ * already runs reactively from `_checkCompaction`, after a response comes back
355
+ * over-threshold or overflowed; this method only adds the two stages that run
356
+ * *ahead of* every LLM request, so that reactive check is reached less often
357
+ * because the request it is reacting to is smaller. It does not call into
358
+ * compaction and does not need to.
359
+ *
360
+ * The wiring itself — where each stage attaches, and why they land in different
361
+ * seams (`transformContext` for eviction, `streamFunction` for schema
362
+ * projection) — lives in `./context/pipeline.ts`'s `installContextPipeline`,
363
+ * shared with the offline replay harness so there is one implementation, not
364
+ * two. This method only supplies this session's two dependencies: a contract
365
+ * lookup backed by `getToolDefinition`, and a budget thunk (never cached — see
366
+ * `_evictionBudget`, which reads live `this.model` / `this.settingsManager` on
367
+ * every call, so a model switch or settings edit mid-session takes effect on
368
+ * the very next request).
369
+ */
370
+ _installContextPipeline() {
371
+ installContextPipeline(this.agent, {
372
+ contractLookup: (name) => this.getToolDefinition(name)?.contract,
373
+ loadedSchemaNames: this._loadedDeferredSchemas,
374
+ evictionBudget: () => this._evictionBudget(),
375
+ });
376
+ }
377
+ /**
378
+ * Token budget for `evictToolResults`'s outbound pass, derived from the same
379
+ * quantities compaction already uses for its own threshold
380
+ * (`getCompactionSettings()`; see `shouldCompact` in
381
+ * `core/compaction/compaction.ts`). The formula itself is `./context/
382
+ * pipeline.ts`'s `evictionBudget` — see that function's comment for the "why
383
+ * half of headroom" reasoning; this method only supplies production's real
384
+ * `contextWindow` / `reserveTokens` inputs.
385
+ */
386
+ _evictionBudget() {
387
+ const contextWindow = this.model?.contextWindow ?? 0;
388
+ const { reserveTokens } = this.settingsManager.getCompactionSettings();
389
+ return evictionBudget(contextWindow, reserveTokens);
390
+ }
294
391
  // =========================================================================
295
392
  // Event Subscription
296
393
  // =========================================================================
@@ -307,6 +404,11 @@ export class AgentSession {
307
404
  followUp: [...this._followUpMessages],
308
405
  });
309
406
  }
407
+ async _emitSessionCompactFailed(event) {
408
+ if (this._extensionRunner.hasHandlers("session_compact_failed")) {
409
+ await this._extensionRunner.emit({ type: "session_compact_failed", ...event });
410
+ }
411
+ }
310
412
  _getIdleWaitPromise() {
311
413
  if (!this._idleWaitPromise) {
312
414
  this._idleWaitPromise = new Promise((resolve) => {
@@ -611,12 +713,16 @@ export class AgentSession {
611
713
  * Get all configured tools with name, description, parameter schema, prompt guidelines, and source metadata.
612
714
  */
613
715
  getAllTools() {
614
- return Array.from(this._toolDefinitions.values()).map(({ definition, sourceInfo }) => ({
716
+ const schemaToolActive = this.getActiveToolNames().includes("tool_schema");
717
+ return Array.from(this._toolDefinitions.values())
718
+ .filter(({ definition }) => definition.name !== "tool_schema" || schemaToolActive)
719
+ .map(({ definition, sourceInfo }) => ({
615
720
  name: definition.name,
616
721
  description: definition.description,
617
722
  parameters: definition.parameters,
618
723
  promptGuidelines: definition.promptGuidelines,
619
724
  sourceInfo,
725
+ unclassified: !("contract" in definition),
620
726
  }));
621
727
  }
622
728
  getToolDefinition(name) {
@@ -954,9 +1060,16 @@ export class AgentSession {
954
1060
  if (!text.startsWith("/skill:"))
955
1061
  return text;
956
1062
  const spaceIndex = text.indexOf(" ");
957
- const skillName = spaceIndex === -1 ? text.slice(7) : text.slice(7, spaceIndex);
1063
+ const commandToken = spaceIndex === -1 ? text.slice(7) : text.slice(7, spaceIndex);
958
1064
  const args = spaceIndex === -1 ? "" : text.slice(spaceIndex + 1).trim();
959
- const skill = this.resourceLoader.getSkills().skills.find((s) => s.name === skillName);
1065
+ // Matched against the slugged command token (SKILL.5), not the raw frontmatter
1066
+ // name -- identity for an already command-safe name, so an exactly-typed raw
1067
+ // name still matches too. A skill whose name contains a space or other
1068
+ // slash-command-breaking character (docs/skills.md's lenient loading allows
1069
+ // this) is only reachable through its slugged token.
1070
+ const skill = this.resourceLoader
1071
+ .getSkills()
1072
+ .skills.find((s) => slugifySkillCommandName(s.name) === commandToken);
960
1073
  if (!skill)
961
1074
  return text; // Unknown skill, pass through
962
1075
  try {
@@ -1078,7 +1191,7 @@ export class AgentSession {
1078
1191
  if (options?.deliverAs === "nextTurn") {
1079
1192
  this._pendingNextTurnMessages.push(appMessage);
1080
1193
  }
1081
- else if (this.isStreaming) {
1194
+ else if (this.isStreaming && options?.triggerTurn !== false) {
1082
1195
  if (options?.deliverAs === "followUp") {
1083
1196
  this.agent.followUp(appMessage);
1084
1197
  }
@@ -1102,6 +1215,7 @@ export class AgentSession {
1102
1215
  *
1103
1216
  * @param content User message content (string or content array)
1104
1217
  * @param options.deliverAs Delivery mode when streaming: "steer" or "followUp"
1218
+ * @param options.expandPromptTemplates Whether to dispatch extension commands and expand skill commands and prompt templates. Default: false.
1105
1219
  */
1106
1220
  async sendUserMessage(content, options) {
1107
1221
  // Normalize content to text string + optional images
@@ -1125,9 +1239,8 @@ export class AgentSession {
1125
1239
  if (images.length === 0)
1126
1240
  images = undefined;
1127
1241
  }
1128
- // Use prompt() with expandPromptTemplates: false to skip command handling and template expansion
1129
1242
  await this.prompt(text, {
1130
- expandPromptTemplates: false,
1243
+ expandPromptTemplates: options?.expandPromptTemplates ?? false,
1131
1244
  streamingBehavior: options?.deliverAs,
1132
1245
  images,
1133
1246
  source: "extension",
@@ -1189,21 +1302,53 @@ export class AgentSession {
1189
1302
  source,
1190
1303
  });
1191
1304
  }
1305
+ /** True when this session runs behind a permission gate at all. */
1306
+ get hasPermissionGate() {
1307
+ return this._permissionGate !== undefined;
1308
+ }
1309
+ /**
1310
+ * The mode in force right now, and which source won. `getMode` in the gate
1311
+ * config re-reads the store on every decision, so a mode written here applies
1312
+ * to the next tool call with no restart.
1313
+ */
1314
+ async getPermissionMode() {
1315
+ if (!this._permissionGate)
1316
+ return undefined;
1317
+ const snapshot = await this._permissionGate.store.snapshot();
1318
+ return resolveEffectiveModeWithOrigin(this._permissionGate.flagMode, snapshot.modesBySource);
1319
+ }
1320
+ /**
1321
+ * Persist a permission mode to user scope (`~/.apex-code/agent/permissions.json`).
1322
+ * Returns the resolution that is actually in force afterwards, which is *not*
1323
+ * necessarily `mode`: `flag`, `local`, and `project` all outrank `user`, so the
1324
+ * caller has to be able to tell the user their choice was recorded but shadowed.
1325
+ */
1326
+ async setPermissionMode(mode) {
1327
+ if (!this._permissionGate)
1328
+ return undefined;
1329
+ await this._permissionGate.store.apply({ type: "setMode", destination: "user", mode });
1330
+ return this.getPermissionMode();
1331
+ }
1192
1332
  /**
1193
1333
  * Set model directly.
1194
- * Validates that auth is configured, saves to session and settings.
1334
+ * Validates that auth is configured and saves to the session transcript.
1335
+ * Persists to global defaults only when options.persist is true.
1195
1336
  * @throws Error if no auth is configured for the model
1196
1337
  */
1197
- async setModel(model) {
1338
+ async setModel(model, options = {}) {
1198
1339
  if (!(await this._modelRuntime.checkAuth(model.provider))) {
1199
1340
  throw new Error(`No API key for ${model.provider}/${model.id}`);
1200
1341
  }
1201
1342
  const previousModel = this.model;
1202
- const thinkingLevel = this._getThinkingLevelForModelSwitch();
1343
+ const thinkingLevel = this._getThinkingLevelForModelSwitch(model);
1203
1344
  this.agent.state.model = model;
1204
1345
  this.sessionManager.appendModelChange(model.provider, model.id);
1205
- this.settingsManager.setDefaultModelAndProvider(model.provider, model.id);
1206
- // Re-clamp thinking level for new model's capabilities
1346
+ if (options.persist) {
1347
+ this.settingsManager.setDefaultModelAndProvider(model.provider, model.id);
1348
+ }
1349
+ // Apply thinking level for the new model.
1350
+ // Per-model thinking level overrides take priority over the global default.
1351
+ // Model persistence does not implicitly rewrite the global thinking default.
1207
1352
  this.setThinkingLevel(thinkingLevel);
1208
1353
  await this._emitModelSelect(model, previousModel, "set");
1209
1354
  }
@@ -1213,13 +1358,13 @@ export class AgentSession {
1213
1358
  * @param direction - "forward" (default) or "backward"
1214
1359
  * @returns The new model info, or undefined if only one model available
1215
1360
  */
1216
- async cycleModel(direction = "forward") {
1361
+ async cycleModel(direction = "forward", options = {}) {
1217
1362
  if (this._scopedModels.length > 0) {
1218
- return this._cycleScopedModel(direction);
1363
+ return this._cycleScopedModel(direction, options);
1219
1364
  }
1220
- return this._cycleAvailableModel(direction);
1365
+ return this._cycleAvailableModel(direction, options);
1221
1366
  }
1222
- async _cycleScopedModel(direction) {
1367
+ async _cycleScopedModel(direction, options) {
1223
1368
  const availableIds = new Set(this._modelRuntime.getAvailableSnapshot().map((model) => `${model.provider}\0${model.id}`));
1224
1369
  const scopedModels = this._scopedModels.filter((scoped) => availableIds.has(`${scoped.model.provider}\0${scoped.model.id}`));
1225
1370
  if (scopedModels.length <= 1)
@@ -1231,20 +1376,23 @@ export class AgentSession {
1231
1376
  const len = scopedModels.length;
1232
1377
  const nextIndex = direction === "forward" ? (currentIndex + 1) % len : (currentIndex - 1 + len) % len;
1233
1378
  const next = scopedModels[nextIndex];
1234
- const thinkingLevel = this._getThinkingLevelForModelSwitch(next.thinkingLevel);
1379
+ const thinkingLevel = this._getThinkingLevelForModelSwitch(next.model, next.thinkingLevel);
1235
1380
  // Apply model
1236
1381
  this.agent.state.model = next.model;
1237
1382
  this.sessionManager.appendModelChange(next.model.provider, next.model.id);
1238
- this.settingsManager.setDefaultModelAndProvider(next.model.provider, next.model.id);
1239
- // Apply thinking level.
1240
- // - Explicit scoped model thinking level overrides current session level
1241
- // - Undefined scoped model thinking level inherits the current session preference
1383
+ if (options.persist) {
1384
+ this.settingsManager.setDefaultModelAndProvider(next.model.provider, next.model.id);
1385
+ }
1386
+ // Apply thinking level for the new model.
1387
+ // - Explicit scoped model thinking level overrides defaults
1388
+ // - Per-model thinking level overrides take priority over the global default
1242
1389
  // setThinkingLevel clamps to model capabilities.
1390
+ // Model persistence does not implicitly rewrite the global thinking default.
1243
1391
  this.setThinkingLevel(thinkingLevel);
1244
1392
  await this._emitModelSelect(next.model, currentModel, "cycle");
1245
1393
  return { model: next.model, thinkingLevel: this.thinkingLevel, isScoped: true };
1246
1394
  }
1247
- async _cycleAvailableModel(direction) {
1395
+ async _cycleAvailableModel(direction, options) {
1248
1396
  const availableModels = this._modelRuntime.getAvailableSnapshot();
1249
1397
  if (availableModels.length <= 1)
1250
1398
  return undefined;
@@ -1255,11 +1403,14 @@ export class AgentSession {
1255
1403
  const len = availableModels.length;
1256
1404
  const nextIndex = direction === "forward" ? (currentIndex + 1) % len : (currentIndex - 1 + len) % len;
1257
1405
  const nextModel = availableModels[nextIndex];
1258
- const thinkingLevel = this._getThinkingLevelForModelSwitch();
1406
+ const thinkingLevel = this._getThinkingLevelForModelSwitch(nextModel);
1259
1407
  this.agent.state.model = nextModel;
1260
1408
  this.sessionManager.appendModelChange(nextModel.provider, nextModel.id);
1261
- this.settingsManager.setDefaultModelAndProvider(nextModel.provider, nextModel.id);
1262
- // Re-clamp thinking level for new model's capabilities
1409
+ if (options.persist) {
1410
+ this.settingsManager.setDefaultModelAndProvider(nextModel.provider, nextModel.id);
1411
+ }
1412
+ // Apply thinking level for the new model.
1413
+ // Model persistence does not implicitly rewrite the global thinking default.
1263
1414
  this.setThinkingLevel(thinkingLevel);
1264
1415
  await this._emitModelSelect(nextModel, currentModel, "cycle");
1265
1416
  return { model: nextModel, thinkingLevel: this.thinkingLevel, isScoped: false };
@@ -1270,20 +1421,21 @@ export class AgentSession {
1270
1421
  /**
1271
1422
  * Set thinking level.
1272
1423
  * Clamps to model capabilities based on available thinking levels.
1273
- * Saves to session and settings only if the level actually changes.
1424
+ * Saves the clamped level to the session transcript only if the level actually changes.
1425
+ * Persists the requested level to global defaults only when options.persist is true.
1274
1426
  */
1275
- setThinkingLevel(level) {
1427
+ setThinkingLevel(level, options = {}) {
1276
1428
  const availableLevels = this.getAvailableThinkingLevels();
1277
1429
  const effectiveLevel = availableLevels.includes(level) ? level : this._clampThinkingLevel(level, availableLevels);
1278
1430
  // Only persist if actually changing
1279
1431
  const previousLevel = this.agent.state.thinkingLevel;
1280
1432
  const isChanging = effectiveLevel !== previousLevel;
1281
1433
  this.agent.state.thinkingLevel = effectiveLevel;
1434
+ if (options.persist) {
1435
+ this.settingsManager.setDefaultThinkingLevel(level);
1436
+ }
1282
1437
  if (isChanging) {
1283
1438
  this.sessionManager.appendThinkingLevelChange(effectiveLevel);
1284
- if (this.supportsThinking() || effectiveLevel !== "off") {
1285
- this.settingsManager.setDefaultThinkingLevel(effectiveLevel);
1286
- }
1287
1439
  this._emit({ type: "thinking_level_changed", level: effectiveLevel });
1288
1440
  void this._extensionRunner.emit({
1289
1441
  type: "thinking_level_select",
@@ -1296,14 +1448,14 @@ export class AgentSession {
1296
1448
  * Cycle to next thinking level.
1297
1449
  * @returns New level, or undefined if model doesn't support thinking
1298
1450
  */
1299
- cycleThinkingLevel() {
1451
+ cycleThinkingLevel(options = {}) {
1300
1452
  if (!this.supportsThinking())
1301
1453
  return undefined;
1302
1454
  const levels = this.getAvailableThinkingLevels();
1303
1455
  const currentIndex = levels.indexOf(this.thinkingLevel);
1304
1456
  const nextIndex = (currentIndex + 1) % levels.length;
1305
1457
  const nextLevel = levels[nextIndex];
1306
- this.setThinkingLevel(nextLevel);
1458
+ this.setThinkingLevel(nextLevel, options);
1307
1459
  return nextLevel;
1308
1460
  }
1309
1461
  /**
@@ -1312,7 +1464,7 @@ export class AgentSession {
1312
1464
  */
1313
1465
  getAvailableThinkingLevels() {
1314
1466
  if (!this.model)
1315
- return THINKING_LEVELS;
1467
+ return [...THINKING_LEVEL_OPTIONS];
1316
1468
  return getSupportedThinkingLevels(this.model);
1317
1469
  }
1318
1470
  /**
@@ -1321,14 +1473,18 @@ export class AgentSession {
1321
1473
  supportsThinking() {
1322
1474
  return !!this.model?.reasoning;
1323
1475
  }
1324
- _getThinkingLevelForModelSwitch(explicitLevel) {
1476
+ _getThinkingLevelForModelSwitch(targetModel, explicitLevel) {
1325
1477
  if (explicitLevel !== undefined) {
1326
1478
  return explicitLevel;
1327
1479
  }
1328
- if (!this.supportsThinking()) {
1329
- return this.settingsManager.getDefaultThinkingLevel() ?? DEFAULT_THINKING_LEVEL;
1480
+ // Per-model default takes priority when switching to a model that has one
1481
+ if (targetModel) {
1482
+ const perModel = this.settingsManager.getModelThinkingLevel(targetModel.provider, targetModel.id);
1483
+ if (perModel !== undefined) {
1484
+ return perModel;
1485
+ }
1330
1486
  }
1331
- return this.thinkingLevel;
1487
+ return this.settingsManager.getDefaultThinkingLevel() ?? this.thinkingLevel ?? DEFAULT_THINKING_LEVEL;
1332
1488
  }
1333
1489
  _clampThinkingLevel(level, _availableLevels) {
1334
1490
  return this.model ? clampThinkingLevel(this.model, level) : "off";
@@ -1359,15 +1515,30 @@ export class AgentSession {
1359
1515
  // =========================================================================
1360
1516
  // Compaction
1361
1517
  // =========================================================================
1518
+ /** Generate Pi's built-in compaction summary for manual and automatic compaction. */
1519
+ async _runDefaultCompaction(preparation, requestModel, apiKey, headers, customInstructions, signal, env, reason) {
1520
+ return compact(preparation, requestModel, apiKey, headers, customInstructions, signal, this.thinkingLevel, this.agent.streamFunction, env, this.settingsManager.getRetrySettings(), this._summarizationRetryCallbacks({ source: "compaction", reason }), undefined);
1521
+ }
1362
1522
  /**
1363
1523
  * Manually compact the session context.
1364
- * Aborts current agent operation first.
1524
+ *
1525
+ * This is the manual entry point used by `/compact`, RPC, and extensions. It is
1526
+ * separate from automatic threshold/overflow compaction, which enters through
1527
+ * `_checkCompaction()` and `_runAutoCompaction()`. After preparation and the
1528
+ * `session_before_compact` hook, both paths call the lower-level `compact()`
1529
+ * function imported from `./compaction/index.ts`, unless the hook cancels or
1530
+ * supplies a custom result.
1531
+ *
1532
+ * Aborts the current agent operation first. Manual compaction never retries or
1533
+ * continues the interrupted agent turn.
1534
+ *
1365
1535
  * @param customInstructions Optional instructions for the compaction summary
1366
1536
  */
1367
1537
  async compact(customInstructions) {
1368
1538
  await this.abort();
1369
1539
  this._compactionAbortController = new AbortController();
1370
1540
  this._emit({ type: "compaction_start", reason: "manual" });
1541
+ let fromExtension = false;
1371
1542
  try {
1372
1543
  if (!this.model) {
1373
1544
  throw new Error(formatNoModelSelectedMessage());
@@ -1385,7 +1556,6 @@ export class AgentSession {
1385
1556
  throw new Error("Nothing to compact (session too small)");
1386
1557
  }
1387
1558
  let extensionCompaction;
1388
- let fromExtension = false;
1389
1559
  if (this._extensionRunner.hasHandlers("session_before_compact")) {
1390
1560
  const result = (await this._extensionRunner.emit({
1391
1561
  type: "session_before_compact",
@@ -1418,8 +1588,8 @@ export class AgentSession {
1418
1588
  details = extensionCompaction.details;
1419
1589
  }
1420
1590
  else {
1421
- // Generate compaction result
1422
- const result = await compact(preparation, requestModel, apiKey, headers, customInstructions, this._compactionAbortController.signal, this.thinkingLevel, this.agent.streamFunction, env, this.settingsManager.getRetrySettings(), this._summarizationRetryCallbacks({ source: "compaction", reason: "manual" }));
1591
+ // Shared default summary generator, also used by automatic compaction.
1592
+ const result = await this._runDefaultCompaction(preparation, requestModel, apiKey, headers, customInstructions, this._compactionAbortController.signal, env, "manual");
1423
1593
  summary = result.summary;
1424
1594
  firstKeptEntryId = result.firstKeptEntryId;
1425
1595
  tokensBefore = result.tokensBefore;
@@ -1467,6 +1637,7 @@ export class AgentSession {
1467
1637
  catch (error) {
1468
1638
  const message = error instanceof Error ? error.message : String(error);
1469
1639
  const aborted = message === "Compaction cancelled" || (error instanceof Error && error.name === "AbortError");
1640
+ const errorMessage = aborted ? undefined : `Compaction failed: ${message}`;
1470
1641
  this._compactionAbortController = undefined;
1471
1642
  this._emit({
1472
1643
  type: "compaction_end",
@@ -1474,7 +1645,14 @@ export class AgentSession {
1474
1645
  result: undefined,
1475
1646
  aborted,
1476
1647
  willRetry: false,
1477
- errorMessage: aborted ? undefined : `Compaction failed: ${message}`,
1648
+ errorMessage,
1649
+ });
1650
+ await this._emitSessionCompactFailed({
1651
+ reason: "manual",
1652
+ errorMessage,
1653
+ aborted,
1654
+ willRetry: false,
1655
+ fromExtension,
1478
1656
  });
1479
1657
  throw error;
1480
1658
  }
@@ -1496,16 +1674,25 @@ export class AgentSession {
1496
1674
  this._branchSummaryAbortController?.abort();
1497
1675
  }
1498
1676
  /**
1499
- * Check if compaction is needed and run it.
1500
- * Called after agent_end and before prompt submission.
1677
+ * Dispatch automatic compaction after `agent_end` or before prompt submission.
1678
+ * Manual compaction does not call this method; it enters through `compact()`.
1679
+ *
1680
+ * Automatic cases:
1681
+ * 1. Overflow with retry: a context-overflow error or recoverable length stop;
1682
+ * remove the failed assistant message, compact, and retry the turn once.
1683
+ * 2. Overflow without retry: a successful response exceeded the configured
1684
+ * context window; compact but preserve the completed response.
1685
+ * 3. Threshold without retry: valid or estimated context usage crossed the
1686
+ * configured threshold; compact without retrying the completed response.
1501
1687
  *
1502
- * Two cases:
1503
- * 1. Recoverable failure: LLM returned context overflow or stopped below its desired output limit;
1504
- * remove the assistant message, compact, and auto-retry once
1505
- * 2. Threshold: Context over threshold, compact, NO auto-retry (user continues manually)
1688
+ * Each case calls `_runAutoCompaction()`. After preparation and the
1689
+ * `session_before_compact` hook, that method calls the lower-level `compact()`
1690
+ * function imported from `./compaction/index.ts`, unless the hook cancels or
1691
+ * supplies a custom result.
1506
1692
  *
1507
1693
  * @param assistantMessage The assistant message to check
1508
1694
  * @param skipAbortedCheck If false, include aborted messages (for pre-prompt check). Default: true
1695
+ * @returns Whether the post-run loop should call `agent.continue()` for overflow recovery or queued messages
1509
1696
  */
1510
1697
  async _checkCompaction(assistantMessage, skipAbortedCheck = true) {
1511
1698
  const settings = this.settingsManager.getCompactionSettings();
@@ -1528,38 +1715,49 @@ export class AgentSession {
1528
1715
  if (assistantIsFromBeforeCompaction) {
1529
1716
  return false;
1530
1717
  }
1531
- // Case 1: Recoverable failure. Explicit/silent context overflow still uses context metadata.
1718
+ // Automatic cases 1 and 2: context overflow.
1532
1719
  // A length stop is recoverable when output ended below the model's original desired limit,
1533
1720
  // independent of the configured context size or any context-clamped provider request limit.
1534
- // A successful response over the configured window should compact but must not retry: the
1535
- // assistant answer already completed and agent.continue() cannot continue from an assistant.
1721
+ const contextOverflow = sameModel && isContextOverflow(assistantMessage, contextWindow);
1536
1722
  const recoverableLength = sameModel && isRecoverableLength(assistantMessage, this.model?.maxTokens ?? 0);
1537
- if (sameModel && (isContextOverflow(assistantMessage, contextWindow) || recoverableLength)) {
1723
+ if (contextOverflow || recoverableLength) {
1538
1724
  const willRetry = assistantMessage.stopReason !== "stop";
1725
+ // Case 2: the response completed successfully. Compact, but do not retry because
1726
+ // agent.continue() cannot continue from a completed assistant response.
1539
1727
  if (!willRetry) {
1540
1728
  return await this._runAutoCompaction("overflow", false);
1541
1729
  }
1542
1730
  if (this._overflowRecoveryAttempted) {
1731
+ const errorMessage = contextOverflow
1732
+ ? "Context overflow recovery failed after one compact-and-retry attempt. Try reducing context or switching to a larger-context model."
1733
+ : "Truncated response recovery failed after one compact-and-retry attempt.";
1543
1734
  this._emit({
1544
1735
  type: "compaction_end",
1545
1736
  reason: "overflow",
1546
1737
  result: undefined,
1547
1738
  aborted: false,
1548
1739
  willRetry: false,
1549
- errorMessage: "Context overflow recovery failed after one compact-and-retry attempt. Try reducing context or switching to a larger-context model.",
1740
+ errorMessage,
1741
+ });
1742
+ await this._emitSessionCompactFailed({
1743
+ reason: "overflow",
1744
+ errorMessage,
1745
+ aborted: false,
1746
+ willRetry: false,
1747
+ fromExtension: false,
1550
1748
  });
1551
1749
  return false;
1552
1750
  }
1751
+ // Case 1: remove the failed or truncated message from agent state, compact, and
1752
+ // retry once. The message remains in session history but is excluded from retry context.
1553
1753
  this._overflowRecoveryAttempted = true;
1554
- // Remove the failed or truncated message from agent state. It remains in session history,
1555
- // but must not be included in the compact-and-retry context.
1556
1754
  const messages = this.agent.state.messages;
1557
1755
  if (messages.length > 0 && messages[messages.length - 1].role === "assistant") {
1558
1756
  this.agent.state.messages = messages.slice(0, -1);
1559
1757
  }
1560
1758
  return await this._runAutoCompaction("overflow", willRetry);
1561
1759
  }
1562
- // Case 2: Threshold - context is getting large
1760
+ // Case 3: threshold compaction without retry.
1563
1761
  // For error messages or all-zero usage messages, estimate from the last valid response.
1564
1762
  // This ensures sessions that hit persistent API errors (e.g. 529) or malformed zero-usage
1565
1763
  // responses can still compact and do not reset context accounting.
@@ -1568,16 +1766,18 @@ export class AgentSession {
1568
1766
  if (assistantMessage.stopReason === "error" || directContextTokens === 0) {
1569
1767
  const messages = this.agent.state.messages;
1570
1768
  const estimate = estimateContextTokens(messages);
1571
- if (estimate.lastUsageIndex === null)
1572
- return false; // No usage data at all
1573
- // Verify the usage source is post-compaction. Kept pre-compaction messages
1574
- // have stale usage reflecting the old (larger) context and would falsely
1575
- // trigger compaction right after one just finished.
1576
- const usageMsg = messages[estimate.lastUsageIndex];
1577
- if (compactionEntry &&
1578
- usageMsg.role === "assistant" &&
1579
- usageMsg.timestamp <= new Date(compactionEntry.timestamp).getTime()) {
1580
- return false;
1769
+ // Without provider usage, estimate.tokens is the pure message-size estimate.
1770
+ // Only usage-backed estimates need the stale pre-compaction check.
1771
+ if (estimate.lastUsageIndex !== null) {
1772
+ // Verify the usage source is post-compaction. Kept pre-compaction messages
1773
+ // have stale usage reflecting the old (larger) context and would falsely
1774
+ // trigger compaction right after one just finished.
1775
+ const usageMsg = messages[estimate.lastUsageIndex];
1776
+ if (compactionEntry &&
1777
+ usageMsg.role === "assistant" &&
1778
+ usageMsg.timestamp <= new Date(compactionEntry.timestamp).getTime()) {
1779
+ return false;
1780
+ }
1581
1781
  }
1582
1782
  contextTokens = estimate.tokens;
1583
1783
  }
@@ -1590,11 +1790,19 @@ export class AgentSession {
1590
1790
  return false;
1591
1791
  }
1592
1792
  /**
1593
- * Internal: Run auto-compaction with events.
1793
+ * Execute threshold or overflow compaction. Manual compaction uses
1794
+ * `AgentSession.compact()` instead. Both paths call the lower-level `compact()`
1795
+ * function imported from `./compaction/index.ts` after preparation and extension
1796
+ * interception.
1797
+ *
1798
+ * @param reason Automatic trigger selected by `_checkCompaction()`
1799
+ * @param willRetry Whether to continue the interrupted turn after overflow compaction
1800
+ * @returns Whether the post-run loop should call `agent.continue()`
1594
1801
  */
1595
1802
  async _runAutoCompaction(reason, willRetry) {
1596
1803
  const settings = this.settingsManager.getCompactionSettings();
1597
1804
  let started = false;
1805
+ let fromExtension = false;
1598
1806
  try {
1599
1807
  if (!this.model) {
1600
1808
  return false;
@@ -1609,7 +1817,6 @@ export class AgentSession {
1609
1817
  this._autoCompactionAbortController = new AbortController();
1610
1818
  started = true;
1611
1819
  let extensionCompaction;
1612
- let fromExtension = false;
1613
1820
  if (this._extensionRunner.hasHandlers("session_before_compact")) {
1614
1821
  const extensionResult = (await this._extensionRunner.emit({
1615
1822
  type: "session_before_compact",
@@ -1628,6 +1835,12 @@ export class AgentSession {
1628
1835
  aborted: true,
1629
1836
  willRetry: false,
1630
1837
  });
1838
+ await this._emitSessionCompactFailed({
1839
+ reason,
1840
+ aborted: true,
1841
+ willRetry: false,
1842
+ fromExtension: false,
1843
+ });
1631
1844
  return false;
1632
1845
  }
1633
1846
  if (extensionResult?.compaction) {
@@ -1649,8 +1862,8 @@ export class AgentSession {
1649
1862
  details = extensionCompaction.details;
1650
1863
  }
1651
1864
  else {
1652
- // Generate compaction result
1653
- const compactResult = await compact(preparation, requestModel, apiKey, headers, undefined, this._autoCompactionAbortController.signal, this.thinkingLevel, this.agent.streamFunction, env, this.settingsManager.getRetrySettings(), this._summarizationRetryCallbacks({ source: "compaction", reason }));
1865
+ // Shared default summary generator, also used by manual compaction.
1866
+ const compactResult = await this._runDefaultCompaction(preparation, requestModel, apiKey, headers, undefined, this._autoCompactionAbortController.signal, env, reason);
1654
1867
  summary = compactResult.summary;
1655
1868
  firstKeptEntryId = compactResult.firstKeptEntryId;
1656
1869
  tokensBefore = compactResult.tokensBefore;
@@ -1665,6 +1878,12 @@ export class AgentSession {
1665
1878
  aborted: true,
1666
1879
  willRetry: false,
1667
1880
  });
1881
+ await this._emitSessionCompactFailed({
1882
+ reason,
1883
+ aborted: true,
1884
+ willRetry: false,
1885
+ fromExtension,
1886
+ });
1668
1887
  return false;
1669
1888
  }
1670
1889
  this.sessionManager.appendCompaction(summary, firstKeptEntryId, tokensBefore, details, fromExtension, usage);
@@ -1711,15 +1930,23 @@ export class AgentSession {
1711
1930
  catch (error) {
1712
1931
  const errorMessage = error instanceof Error ? error.message : "compaction failed";
1713
1932
  if (started) {
1933
+ const formattedErrorMessage = reason === "overflow"
1934
+ ? `Context overflow recovery failed: ${errorMessage}`
1935
+ : `Auto-compaction failed: ${errorMessage}`;
1714
1936
  this._emit({
1715
1937
  type: "compaction_end",
1716
1938
  reason,
1717
1939
  result: undefined,
1718
1940
  aborted: false,
1719
1941
  willRetry: false,
1720
- errorMessage: reason === "overflow"
1721
- ? `Context overflow recovery failed: ${errorMessage}`
1722
- : `Auto-compaction failed: ${errorMessage}`,
1942
+ errorMessage: formattedErrorMessage,
1943
+ });
1944
+ await this._emitSessionCompactFailed({
1945
+ reason,
1946
+ errorMessage: formattedErrorMessage,
1947
+ aborted: false,
1948
+ willRetry: false,
1949
+ fromExtension,
1723
1950
  });
1724
1951
  }
1725
1952
  return false;
@@ -1835,7 +2062,7 @@ export class AgentSession {
1835
2062
  sourceInfo: template.sourceInfo,
1836
2063
  }));
1837
2064
  const skills = this._resourceLoader.getSkills().skills.map((skill) => ({
1838
- name: `skill:${skill.name}`,
2065
+ name: `skill:${slugifySkillCommandName(skill.name)}`,
1839
2066
  description: skill.description,
1840
2067
  source: "skill",
1841
2068
  sourceInfo: skill.sourceInfo,
@@ -2012,6 +2239,14 @@ export class AgentSession {
2012
2239
  }
2013
2240
  }
2014
2241
  }
2242
+ const hasDeferredActiveTool = nextActiveToolNames.some((name) => {
2243
+ const contract = definitionRegistry.get(name)?.definition
2244
+ ?.contract;
2245
+ return contract?.context.deferSchema === true;
2246
+ });
2247
+ if (hasDeferredActiveTool && this._toolRegistry.has("tool_schema")) {
2248
+ nextActiveToolNames.push("tool_schema");
2249
+ }
2015
2250
  this.setActiveToolsByName([...new Set(nextActiveToolNames)]);
2016
2251
  }
2017
2252
  _buildRuntime(options) {
@@ -2026,7 +2261,33 @@ export class AgentSession {
2026
2261
  : createAllToolDefinitions(this._cwd, {
2027
2262
  read: { autoResizeImages },
2028
2263
  bash: { commandPrefix: shellCommandPrefix, shellPath },
2264
+ edit: { diagnosticsOperations: this._diagnosticsOperations },
2265
+ write: { diagnosticsOperations: this._diagnosticsOperations },
2266
+ ...(this._lspOperations ? { lsp: { operations: this._lspOperations } } : {}),
2267
+ ...(this._webSearchOperations ? { web_search: { operations: this._webSearchOperations } } : {}),
2029
2268
  });
2269
+ baseToolDefinitions.tool_schema = createToolSchemaToolDefinition({
2270
+ getTool: (name) => {
2271
+ if (!this.getActiveToolNames().includes(name))
2272
+ return undefined;
2273
+ const definition = this._toolDefinitions.get(name)?.definition;
2274
+ return definition ? { name: definition.name, parameters: definition.parameters } : undefined;
2275
+ },
2276
+ markLoaded: (name) => {
2277
+ this._loadedDeferredSchemas.add(name);
2278
+ },
2279
+ });
2280
+ baseToolDefinitions.todo_write = createTodoWriteToolDefinition({
2281
+ write: (todos) => {
2282
+ this.sessionManager.appendCustomEntry(TODO_CUSTOM_ENTRY_TYPE, todos);
2283
+ },
2284
+ });
2285
+ // Reads the resource loader live on every call (not a snapshot taken here), so
2286
+ // a project-trust change or a settings reload that alters the loaded skill set
2287
+ // is reflected on the next search without rebuilding the tool registry.
2288
+ baseToolDefinitions.skill_search = createSkillSearchToolDefinition({
2289
+ getSkills: () => this.resourceLoader.getSkills().skills,
2290
+ });
2030
2291
  this._baseToolDefinitions = new Map(Object.entries(baseToolDefinitions).map(([name, tool]) => [name, tool]));
2031
2292
  const extensionsResult = this._resourceLoader.getExtensions();
2032
2293
  if (options.flagValues) {
@@ -2042,7 +2303,9 @@ export class AgentSession {
2042
2303
  this._applyExtensionBindings(this._extensionRunner);
2043
2304
  const defaultActiveToolNames = this._baseToolsOverride
2044
2305
  ? Object.keys(this._baseToolsOverride)
2045
- : ["read", "bash", "edit", "write"];
2306
+ : this._lspOperations
2307
+ ? ["read", "bash", "edit", "write", "lsp"]
2308
+ : ["read", "bash", "edit", "write"];
2046
2309
  const baseActiveToolNames = options.activeToolNames ?? defaultActiveToolNames;
2047
2310
  this._refreshToolRegistry({
2048
2311
  activeToolNames: baseActiveToolNames,
@@ -2583,11 +2846,11 @@ export class AgentSession {
2583
2846
  /**
2584
2847
  * Export session to HTML.
2585
2848
  * @param outputPath Optional output path (defaults to session directory)
2849
+ * @param options Optional export presentation settings
2586
2850
  * @returns Path to exported file
2587
2851
  */
2588
- async exportToHtml(outputPath) {
2589
- const configuredThemeName = this.settingsManager.getTheme();
2590
- const themeName = configuredThemeName && getThemeByName(configuredThemeName) ? configuredThemeName : undefined;
2852
+ async exportToHtml(outputPath, options = {}) {
2853
+ const themeName = [options.themeName, this.settingsManager.getTheme()].find((candidate) => candidate !== undefined && getThemeByName(candidate) !== undefined);
2591
2854
  // Create tool renderer if we have an extension runner (for custom tool HTML rendering)
2592
2855
  const toolRenderer = createToolHtmlRenderer({
2593
2856
  getToolDefinition: (name) => this.getToolDefinition(name),
@@ -2607,29 +2870,7 @@ export class AgentSession {
2607
2870
  * @returns The resolved output file path.
2608
2871
  */
2609
2872
  exportToJsonl(outputPath) {
2610
- const filePath = resolvePath(outputPath ?? `session-${new Date().toISOString().replace(/[:.]/g, "-")}.jsonl`, process.cwd());
2611
- const dir = dirname(filePath);
2612
- if (!existsSync(dir)) {
2613
- mkdirSync(dir, { recursive: true });
2614
- }
2615
- const header = {
2616
- type: "session",
2617
- version: CURRENT_SESSION_VERSION,
2618
- id: this.sessionManager.getSessionId(),
2619
- timestamp: new Date().toISOString(),
2620
- cwd: this.sessionManager.getCwd(),
2621
- };
2622
- const branchEntries = this.sessionManager.getBranch();
2623
- const lines = [JSON.stringify(header)];
2624
- // Re-chain parentIds to form a linear sequence
2625
- let prevId = null;
2626
- for (const entry of branchEntries) {
2627
- const linear = { ...entry, parentId: prevId };
2628
- lines.push(JSON.stringify(linear));
2629
- prevId = entry.id;
2630
- }
2631
- writeFileSync(filePath, `${lines.join("\n")}\n`);
2632
- return filePath;
2873
+ return exportSessionToJsonl(this.sessionManager, outputPath);
2633
2874
  }
2634
2875
  // =========================================================================
2635
2876
  // Utilities