@asterxsk/kiln 0.1.0 → 0.3.0

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 (491) hide show
  1. package/README.md +155 -170
  2. package/agent/AGENTS.md +67 -67
  3. package/agent/README.md +5 -5
  4. package/agent/extensions/ask-user/index.ts +418 -418
  5. package/agent/extensions/ask-user/install.ps1 +4 -0
  6. package/agent/extensions/ask-user/install.sh +3 -0
  7. package/agent/extensions/ask-user/package-lock.json +769 -769
  8. package/agent/extensions/ask-user/package.json +19 -19
  9. package/agent/extensions/ask-user/prompt.ts +45 -45
  10. package/agent/extensions/ask-user/tsconfig.json +7 -7
  11. package/agent/extensions/background-terminals/docs/implementation-guide.md +942 -942
  12. package/agent/extensions/background-terminals/index.ts +627 -627
  13. package/agent/extensions/background-terminals/install.ps1 +4 -0
  14. package/agent/extensions/background-terminals/install.sh +3 -0
  15. package/agent/extensions/background-terminals/manager.test.ts +735 -735
  16. package/agent/extensions/background-terminals/output.test.ts +109 -109
  17. package/agent/extensions/background-terminals/package-lock.json +769 -769
  18. package/agent/extensions/background-terminals/package.json +17 -17
  19. package/agent/extensions/background-terminals/prompt.test.ts +125 -125
  20. package/agent/extensions/background-terminals/ps.test.ts +82 -82
  21. package/agent/extensions/background-terminals/result-delivery.test.ts +44 -44
  22. package/agent/extensions/background-terminals/src/domain.ts +87 -87
  23. package/agent/extensions/background-terminals/src/manager.ts +907 -907
  24. package/agent/extensions/background-terminals/src/output.ts +84 -84
  25. package/agent/extensions/background-terminals/src/prompt.ts +142 -142
  26. package/agent/extensions/background-terminals/src/result-delivery.ts +27 -27
  27. package/agent/extensions/background-terminals/src/runtime.ts +36 -36
  28. package/agent/extensions/background-terminals/src/ui/output-view.ts +79 -79
  29. package/agent/extensions/background-terminals/src/ui/ps.ts +621 -621
  30. package/agent/extensions/background-terminals/tsconfig.json +7 -7
  31. package/agent/extensions/destructive/install.ps1 +4 -0
  32. package/agent/extensions/destructive/install.sh +3 -0
  33. package/agent/extensions/file-search/index.spec.ts +443 -443
  34. package/agent/extensions/file-search/index.ts +459 -459
  35. package/agent/extensions/file-search/install.ps1 +4 -0
  36. package/agent/extensions/file-search/install.sh +3 -0
  37. package/agent/extensions/file-search/package-lock.json +2253 -2253
  38. package/agent/extensions/file-search/package.json +23 -23
  39. package/agent/extensions/file-search/src/args.ts +122 -122
  40. package/agent/extensions/file-search/src/binaries.ts +422 -422
  41. package/agent/extensions/file-search/src/output.ts +126 -126
  42. package/agent/extensions/file-search/src/process.ts +146 -146
  43. package/agent/extensions/file-search/src/prompt.ts +52 -52
  44. package/agent/extensions/file-search/tsconfig.json +7 -7
  45. package/agent/extensions/goal/install.ps1 +4 -0
  46. package/agent/extensions/goal/install.sh +3 -0
  47. package/agent/extensions/herdr-agent-state.ts +257 -0
  48. package/agent/extensions/kiln-update/README.md +25 -0
  49. package/agent/extensions/kiln-update/index.ts +99 -0
  50. package/agent/extensions/kiln-update/install.ps1 +27 -0
  51. package/agent/extensions/kiln-update/install.sh +24 -0
  52. package/agent/extensions/modelconf/PLAN.md +915 -915
  53. package/agent/extensions/modelconf/index.ts +296 -296
  54. package/agent/extensions/modelconf/install.ps1 +4 -0
  55. package/agent/extensions/modelconf/install.sh +3 -0
  56. package/agent/extensions/modelconf/src/ui/ModelConfView.ts +1101 -1101
  57. package/agent/extensions/pi-web-access/CHANGELOG.md +690 -690
  58. package/agent/extensions/pi-web-access/LICENSE +21 -21
  59. package/agent/extensions/pi-web-access/README.md +470 -470
  60. package/agent/extensions/pi-web-access/SECURITY.md +5 -5
  61. package/agent/extensions/pi-web-access/activity.ts +101 -101
  62. package/agent/extensions/pi-web-access/auth-fetch.ts +148 -148
  63. package/agent/extensions/pi-web-access/brightdata-unlocker.ts +272 -272
  64. package/agent/extensions/pi-web-access/chrome-cookies.ts +669 -669
  65. package/agent/extensions/pi-web-access/content-find.ts +139 -139
  66. package/agent/extensions/pi-web-access/credential-source.ts +191 -191
  67. package/agent/extensions/pi-web-access/data-uri-sanitize.ts +406 -406
  68. package/agent/extensions/pi-web-access/datalab-pdf-extract.ts +568 -568
  69. package/agent/extensions/pi-web-access/declared-web-links.ts +173 -173
  70. package/agent/extensions/pi-web-access/evidence/CONTRACT-EVIDENCE.md +496 -496
  71. package/agent/extensions/pi-web-access/evidence/contract-probe.mjs +140 -140
  72. package/agent/extensions/pi-web-access/exa.ts +526 -526
  73. package/agent/extensions/pi-web-access/extract.ts +1196 -1196
  74. package/agent/extensions/pi-web-access/feature-config.ts +29 -29
  75. package/agent/extensions/pi-web-access/fetch-params.ts +111 -111
  76. package/agent/extensions/pi-web-access/gemini-adc.ts +298 -298
  77. package/agent/extensions/pi-web-access/gemini-api.ts +353 -353
  78. package/agent/extensions/pi-web-access/gemini-pdf-extract.ts +108 -108
  79. package/agent/extensions/pi-web-access/gemini-url-context.ts +128 -128
  80. package/agent/extensions/pi-web-access/gemini-web-config.ts +101 -101
  81. package/agent/extensions/pi-web-access/gemini-web.ts +487 -487
  82. package/agent/extensions/pi-web-access/github-api.ts +197 -197
  83. package/agent/extensions/pi-web-access/github-extract.ts +746 -746
  84. package/agent/extensions/pi-web-access/github-issue-pr.ts +700 -700
  85. package/agent/extensions/pi-web-access/index.ts +1737 -1737
  86. package/agent/extensions/pi-web-access/package-lock.json +5808 -5808
  87. package/agent/extensions/pi-web-access/package.json +64 -64
  88. package/agent/extensions/pi-web-access/page-query.ts +96 -96
  89. package/agent/extensions/pi-web-access/pdf-extract.ts +409 -409
  90. package/agent/extensions/pi-web-access/promise-try.d.ts +7 -7
  91. package/agent/extensions/pi-web-access/query-rewrite.ts +51 -51
  92. package/agent/extensions/pi-web-access/render-search-error.ts +170 -170
  93. package/agent/extensions/pi-web-access/rsc-extract.ts +338 -338
  94. package/agent/extensions/pi-web-access/source-check.ts +282 -282
  95. package/agent/extensions/pi-web-access/ssrf-protection.ts +526 -526
  96. package/agent/extensions/pi-web-access/storage.ts +521 -521
  97. package/agent/extensions/pi-web-access/summary-model-scope.ts +125 -125
  98. package/agent/extensions/pi-web-access/test/auth-fetch.test.mjs +208 -208
  99. package/agent/extensions/pi-web-access/test/brightdata-unlocker.test.mjs +840 -840
  100. package/agent/extensions/pi-web-access/test/chrome-cookie-extraction.test.mjs +441 -441
  101. package/agent/extensions/pi-web-access/test/config-path.test.mjs +283 -283
  102. package/agent/extensions/pi-web-access/test/content-find.test.mjs +25 -25
  103. package/agent/extensions/pi-web-access/test/credential-source.test.mjs +118 -118
  104. package/agent/extensions/pi-web-access/test/data-uri-sanitize.test.mjs +210 -210
  105. package/agent/extensions/pi-web-access/test/datalab-pdf-extract.test.mjs +552 -552
  106. package/agent/extensions/pi-web-access/test/declared-web-links.test.mjs +212 -212
  107. package/agent/extensions/pi-web-access/test/fetch-answer-storage.test.mjs +40 -40
  108. package/agent/extensions/pi-web-access/test/fetch-cache-storage.test.mjs +334 -334
  109. package/agent/extensions/pi-web-access/test/fetch-content-domain-policy.test.mjs +95 -95
  110. package/agent/extensions/pi-web-access/test/fetch-modes.test.mjs +53 -53
  111. package/agent/extensions/pi-web-access/test/fetch-not-found-guidance.test.mjs +92 -92
  112. package/agent/extensions/pi-web-access/test/fetch-params.test.mjs +86 -86
  113. package/agent/extensions/pi-web-access/test/fetch-render-call.test.mjs +34 -34
  114. package/agent/extensions/pi-web-access/test/fetch-routing.test.mjs +173 -173
  115. package/agent/extensions/pi-web-access/test/gemini-adc-auth.test.mjs +257 -257
  116. package/agent/extensions/pi-web-access/test/gemini-api-transport.test.mjs +170 -170
  117. package/agent/extensions/pi-web-access/test/gemini-pdf-extract.test.mjs +133 -133
  118. package/agent/extensions/pi-web-access/test/gemini-web-cookie-opt-in.test.mjs +178 -178
  119. package/agent/extensions/pi-web-access/test/gemini-web-header-overflow.test.mjs +148 -148
  120. package/agent/extensions/pi-web-access/test/get-search-content.test.mjs +223 -223
  121. package/agent/extensions/pi-web-access/test/github-extract.test.mjs +378 -378
  122. package/agent/extensions/pi-web-access/test/github-issue-pr.test.mjs +565 -565
  123. package/agent/extensions/pi-web-access/test/inline-content-config.test.mjs +99 -99
  124. package/agent/extensions/pi-web-access/test/lazy-extract-load.test.mjs +118 -118
  125. package/agent/extensions/pi-web-access/test/local-video-oversize.test.mjs +52 -52
  126. package/agent/extensions/pi-web-access/test/package-typebox-dependency.test.mjs +50 -50
  127. package/agent/extensions/pi-web-access/test/page-query.test.mjs +51 -51
  128. package/agent/extensions/pi-web-access/test/pdf-config.test.mjs +140 -140
  129. package/agent/extensions/pi-web-access/test/pdf-extract.test.mjs +500 -500
  130. package/agent/extensions/pi-web-access/test/proxy-transport.test.mjs +286 -286
  131. package/agent/extensions/pi-web-access/test/query-rewrite.test.mjs +52 -52
  132. package/agent/extensions/pi-web-access/test/rsc-fallback.test.mjs +102 -102
  133. package/agent/extensions/pi-web-access/test/search-error-render.test.mjs +152 -152
  134. package/agent/extensions/pi-web-access/test/search-providers.test.mjs +274 -274
  135. package/agent/extensions/pi-web-access/test/source-check.test.mjs +179 -179
  136. package/agent/extensions/pi-web-access/test/ssrf-allow-ranges-config.test.mjs +205 -205
  137. package/agent/extensions/pi-web-access/test/ssrf-protection.test.mjs +456 -456
  138. package/agent/extensions/pi-web-access/test/tool-registration-config.test.mjs +182 -182
  139. package/agent/extensions/pi-web-access/test/youtube-extract-errors.test.mjs +64 -64
  140. package/agent/extensions/pi-web-access/tsconfig.json +11 -11
  141. package/agent/extensions/pi-web-access/utils.ts +451 -451
  142. package/agent/extensions/pi-web-access/video-extract.ts +392 -392
  143. package/agent/extensions/pi-web-access/youtube-extract.ts +328 -328
  144. package/agent/extensions/shared/activity-status.ts +31 -31
  145. package/agent/extensions/shared/child-session.test.ts +270 -270
  146. package/agent/extensions/shared/child-session.ts +148 -148
  147. package/agent/extensions/shared/context-utilization.test.ts +48 -48
  148. package/agent/extensions/shared/context-utilization.ts +47 -47
  149. package/agent/extensions/shared/dashboard-state.ts +99 -99
  150. package/agent/extensions/shared/install.ps1 +4 -0
  151. package/agent/extensions/shared/install.sh +3 -0
  152. package/agent/extensions/shared/tool-call-timeout.test.ts +117 -117
  153. package/agent/extensions/shared/tool-call-timeout.ts +104 -104
  154. package/agent/extensions/skillsconf/install.ps1 +4 -0
  155. package/agent/extensions/skillsconf/install.sh +3 -0
  156. package/agent/extensions/statusline/index.ts +282 -0
  157. package/agent/extensions/statusline/install.ps1 +27 -0
  158. package/agent/extensions/statusline/install.sh +24 -0
  159. package/agent/extensions/subagents/by-the-way.test.ts +29 -29
  160. package/agent/extensions/subagents/claude.test.ts +119 -119
  161. package/agent/extensions/subagents/codex.test.ts +102 -102
  162. package/agent/extensions/subagents/context-usage.test.ts +107 -107
  163. package/agent/extensions/subagents/docs/design-plan.md +568 -568
  164. package/agent/extensions/subagents/docs/effect-v4-extension-guide.md +354 -354
  165. package/agent/extensions/subagents/docs/effect-v4-notes.md +571 -571
  166. package/agent/extensions/subagents/index.ts +779 -779
  167. package/agent/extensions/subagents/install.ps1 +4 -0
  168. package/agent/extensions/subagents/install.sh +3 -0
  169. package/agent/extensions/subagents/manager.test.ts +276 -276
  170. package/agent/extensions/subagents/package-lock.json +2244 -2244
  171. package/agent/extensions/subagents/package.json +19 -19
  172. package/agent/extensions/subagents/result-delivery.test.ts +27 -27
  173. package/agent/extensions/subagents/src/backend.ts +73 -73
  174. package/agent/extensions/subagents/src/backends/claude.ts +701 -701
  175. package/agent/extensions/subagents/src/backends/codex.ts +1060 -1060
  176. package/agent/extensions/subagents/src/backends/pi.ts +575 -575
  177. package/agent/extensions/subagents/src/backends/stub.ts +300 -300
  178. package/agent/extensions/subagents/src/by-the-way.ts +21 -21
  179. package/agent/extensions/subagents/src/domain.ts +253 -253
  180. package/agent/extensions/subagents/src/format.ts +74 -74
  181. package/agent/extensions/subagents/src/manager.ts +736 -736
  182. package/agent/extensions/subagents/src/prompt.ts +92 -92
  183. package/agent/extensions/subagents/src/result-delivery.ts +20 -20
  184. package/agent/extensions/subagents/src/runtime.ts +53 -53
  185. package/agent/extensions/subagents/src/ui/takeover.ts +583 -583
  186. package/agent/extensions/subagents/src/ui/transcript.ts +201 -201
  187. package/agent/extensions/subagents/takeover.test.ts +29 -29
  188. package/agent/extensions/subagents/tsconfig.json +7 -7
  189. package/agent/extensions/taste/install.ps1 +4 -0
  190. package/agent/extensions/taste/install.sh +3 -0
  191. package/agent/extensions/todo/AGENTS.md +38 -38
  192. package/agent/extensions/todo/LICENSE +21 -21
  193. package/agent/extensions/todo/config.ts +55 -55
  194. package/agent/extensions/todo/index.ts +151 -151
  195. package/agent/extensions/todo/install.ps1 +4 -0
  196. package/agent/extensions/todo/install.sh +3 -0
  197. package/agent/extensions/todo/locales/de.json +17 -17
  198. package/agent/extensions/todo/locales/en.json +15 -15
  199. package/agent/extensions/todo/locales/es.json +17 -17
  200. package/agent/extensions/todo/locales/fr.json +17 -17
  201. package/agent/extensions/todo/locales/pt-BR.json +17 -17
  202. package/agent/extensions/todo/locales/pt.json +17 -17
  203. package/agent/extensions/todo/locales/ru.json +17 -17
  204. package/agent/extensions/todo/locales/uk.json +17 -17
  205. package/agent/extensions/todo/locales/zh.json +17 -17
  206. package/agent/extensions/todo/package-lock.json +3358 -3358
  207. package/agent/extensions/todo/package.json +67 -67
  208. package/agent/extensions/todo/state/i18n-bridge.ts +64 -64
  209. package/agent/extensions/todo/state/invariants.ts +20 -20
  210. package/agent/extensions/todo/state/replay.ts +38 -38
  211. package/agent/extensions/todo/state/selectors.ts +107 -107
  212. package/agent/extensions/todo/state/state-reducer.ts +326 -326
  213. package/agent/extensions/todo/state/state.ts +18 -18
  214. package/agent/extensions/todo/state/store.ts +82 -82
  215. package/agent/extensions/todo/state/task-graph.ts +57 -57
  216. package/agent/extensions/todo/todo-overlay.ts +200 -200
  217. package/agent/extensions/todo/todo.ts +155 -155
  218. package/agent/extensions/todo/tool/response-envelope.ts +109 -109
  219. package/agent/extensions/todo/tool/types.ts +206 -206
  220. package/agent/extensions/todo/view/format.ts +177 -177
  221. package/agent/extensions/trim-context/install.ps1 +4 -0
  222. package/agent/extensions/trim-context/install.sh +3 -0
  223. package/agent/keybindings.json +7 -7
  224. package/agent/version.txt +1 -0
  225. package/agent.bak.20260905-190020/AGENTS.md +67 -0
  226. package/agent.bak.20260905-190020/README.md +5 -0
  227. package/agent.bak.20260905-190020/extensions/ask-user/index.ts +418 -0
  228. package/agent.bak.20260905-190020/extensions/ask-user/package-lock.json +769 -0
  229. package/agent.bak.20260905-190020/extensions/ask-user/package.json +19 -0
  230. package/agent.bak.20260905-190020/extensions/ask-user/prompt.ts +45 -0
  231. package/agent.bak.20260905-190020/extensions/ask-user/tsconfig.json +7 -0
  232. package/agent.bak.20260905-190020/extensions/background-terminals/docs/implementation-guide.md +942 -0
  233. package/agent.bak.20260905-190020/extensions/background-terminals/index.ts +629 -0
  234. package/agent.bak.20260905-190020/extensions/background-terminals/install.ps1 +23 -0
  235. package/agent.bak.20260905-190020/extensions/background-terminals/install.sh +21 -0
  236. package/agent.bak.20260905-190020/extensions/background-terminals/package-lock.json +769 -0
  237. package/agent.bak.20260905-190020/extensions/background-terminals/package.json +17 -0
  238. package/agent.bak.20260905-190020/extensions/background-terminals/src/domain.ts +87 -0
  239. package/agent.bak.20260905-190020/extensions/background-terminals/src/manager.ts +907 -0
  240. package/agent.bak.20260905-190020/extensions/background-terminals/src/output.ts +84 -0
  241. package/agent.bak.20260905-190020/extensions/background-terminals/src/prompt.ts +142 -0
  242. package/agent.bak.20260905-190020/extensions/background-terminals/src/result-delivery.ts +27 -0
  243. package/agent.bak.20260905-190020/extensions/background-terminals/src/runtime.ts +36 -0
  244. package/agent.bak.20260905-190020/extensions/background-terminals/src/ui/output-view.ts +79 -0
  245. package/agent.bak.20260905-190020/extensions/background-terminals/src/ui/ps.ts +621 -0
  246. package/agent.bak.20260905-190020/extensions/background-terminals/src/widget-order.ts +121 -0
  247. package/agent.bak.20260905-190020/extensions/background-terminals/test/manager.test.ts +735 -0
  248. package/agent.bak.20260905-190020/extensions/background-terminals/test/output.test.ts +109 -0
  249. package/agent.bak.20260905-190020/extensions/background-terminals/test/prompt.test.ts +125 -0
  250. package/agent.bak.20260905-190020/extensions/background-terminals/test/ps.test.ts +82 -0
  251. package/agent.bak.20260905-190020/extensions/background-terminals/test/result-delivery.test.ts +44 -0
  252. package/agent.bak.20260905-190020/extensions/background-terminals/tsconfig.json +7 -0
  253. package/agent.bak.20260905-190020/extensions/destructive/README.md +34 -0
  254. package/agent.bak.20260905-190020/extensions/destructive/index.ts +124 -0
  255. package/agent.bak.20260905-190020/extensions/destructive/install.ps1 +23 -0
  256. package/agent.bak.20260905-190020/extensions/destructive/install.sh +21 -0
  257. package/agent.bak.20260905-190020/extensions/file-search/index.ts +459 -0
  258. package/agent.bak.20260905-190020/extensions/file-search/install.ps1 +23 -0
  259. package/agent.bak.20260905-190020/extensions/file-search/install.sh +21 -0
  260. package/agent.bak.20260905-190020/extensions/file-search/package-lock.json +2253 -0
  261. package/agent.bak.20260905-190020/extensions/file-search/package.json +23 -0
  262. package/agent.bak.20260905-190020/extensions/file-search/src/args.ts +122 -0
  263. package/agent.bak.20260905-190020/extensions/file-search/src/binaries.ts +422 -0
  264. package/agent.bak.20260905-190020/extensions/file-search/src/output.ts +126 -0
  265. package/agent.bak.20260905-190020/extensions/file-search/src/process.ts +146 -0
  266. package/agent.bak.20260905-190020/extensions/file-search/src/prompt.ts +52 -0
  267. package/agent.bak.20260905-190020/extensions/file-search/test/index.spec.ts +443 -0
  268. package/agent.bak.20260905-190020/extensions/file-search/tsconfig.json +7 -0
  269. package/agent.bak.20260905-190020/extensions/goal/README.md +50 -0
  270. package/agent.bak.20260905-190020/extensions/goal/index.ts +155 -0
  271. package/agent.bak.20260905-190020/extensions/goal/install.ps1 +23 -0
  272. package/agent.bak.20260905-190020/extensions/goal/install.sh +21 -0
  273. package/agent.bak.20260905-190020/extensions/kiln-update/README.md +25 -0
  274. package/agent.bak.20260905-190020/extensions/kiln-update/index.ts +99 -0
  275. package/agent.bak.20260905-190020/extensions/kiln-update/install.ps1 +23 -0
  276. package/agent.bak.20260905-190020/extensions/kiln-update/install.sh +21 -0
  277. package/agent.bak.20260905-190020/extensions/modelconf/PLAN.md +915 -0
  278. package/agent.bak.20260905-190020/extensions/modelconf/README.md +66 -0
  279. package/agent.bak.20260905-190020/extensions/modelconf/index.ts +296 -0
  280. package/agent.bak.20260905-190020/extensions/modelconf/install.ps1 +23 -0
  281. package/agent.bak.20260905-190020/extensions/modelconf/install.sh +21 -0
  282. package/agent.bak.20260905-190020/extensions/modelconf/package-lock.json +1809 -0
  283. package/agent.bak.20260905-190020/extensions/modelconf/package.json +13 -0
  284. package/agent.bak.20260905-190020/extensions/modelconf/src/fuzzy.ts +26 -0
  285. package/agent.bak.20260905-190020/extensions/modelconf/src/glob.ts +13 -0
  286. package/agent.bak.20260905-190020/extensions/modelconf/src/persistence.test.ts +46 -0
  287. package/agent.bak.20260905-190020/extensions/modelconf/src/persistence.ts +164 -0
  288. package/agent.bak.20260905-190020/extensions/modelconf/src/ui/ModelConfView.test.ts +75 -0
  289. package/agent.bak.20260905-190020/extensions/modelconf/src/ui/ModelConfView.ts +1101 -0
  290. package/agent.bak.20260905-190020/extensions/modelconf/tsconfig.json +15 -0
  291. package/agent.bak.20260905-190020/extensions/pi-web-access/CHANGELOG.md +690 -0
  292. package/agent.bak.20260905-190020/extensions/pi-web-access/LICENSE +21 -0
  293. package/agent.bak.20260905-190020/extensions/pi-web-access/README.md +470 -0
  294. package/agent.bak.20260905-190020/extensions/pi-web-access/SECURITY.md +5 -0
  295. package/agent.bak.20260905-190020/extensions/pi-web-access/activity.ts +101 -0
  296. package/agent.bak.20260905-190020/extensions/pi-web-access/auth-fetch.ts +148 -0
  297. package/agent.bak.20260905-190020/extensions/pi-web-access/banner.png +0 -0
  298. package/agent.bak.20260905-190020/extensions/pi-web-access/brightdata-unlocker.ts +272 -0
  299. package/agent.bak.20260905-190020/extensions/pi-web-access/chrome-cookies.ts +669 -0
  300. package/agent.bak.20260905-190020/extensions/pi-web-access/content-find.ts +139 -0
  301. package/agent.bak.20260905-190020/extensions/pi-web-access/credential-source.ts +191 -0
  302. package/agent.bak.20260905-190020/extensions/pi-web-access/data-uri-sanitize.ts +406 -0
  303. package/agent.bak.20260905-190020/extensions/pi-web-access/datalab-pdf-extract.ts +568 -0
  304. package/agent.bak.20260905-190020/extensions/pi-web-access/declared-web-links.ts +173 -0
  305. package/agent.bak.20260905-190020/extensions/pi-web-access/evidence/CONTRACT-EVIDENCE.md +496 -0
  306. package/agent.bak.20260905-190020/extensions/pi-web-access/evidence/contract-probe.mjs +140 -0
  307. package/agent.bak.20260905-190020/extensions/pi-web-access/exa.ts +526 -0
  308. package/agent.bak.20260905-190020/extensions/pi-web-access/extract.ts +1196 -0
  309. package/agent.bak.20260905-190020/extensions/pi-web-access/feature-config.ts +29 -0
  310. package/agent.bak.20260905-190020/extensions/pi-web-access/fetch-params.ts +111 -0
  311. package/agent.bak.20260905-190020/extensions/pi-web-access/gemini-adc.ts +298 -0
  312. package/agent.bak.20260905-190020/extensions/pi-web-access/gemini-api.ts +353 -0
  313. package/agent.bak.20260905-190020/extensions/pi-web-access/gemini-pdf-extract.ts +108 -0
  314. package/agent.bak.20260905-190020/extensions/pi-web-access/gemini-search.ts +21 -0
  315. package/agent.bak.20260905-190020/extensions/pi-web-access/gemini-url-context.ts +128 -0
  316. package/agent.bak.20260905-190020/extensions/pi-web-access/gemini-web-config.ts +101 -0
  317. package/agent.bak.20260905-190020/extensions/pi-web-access/gemini-web.ts +487 -0
  318. package/agent.bak.20260905-190020/extensions/pi-web-access/github-api.ts +197 -0
  319. package/agent.bak.20260905-190020/extensions/pi-web-access/github-extract.ts +746 -0
  320. package/agent.bak.20260905-190020/extensions/pi-web-access/github-issue-pr.ts +700 -0
  321. package/agent.bak.20260905-190020/extensions/pi-web-access/index.ts +1737 -0
  322. package/agent.bak.20260905-190020/extensions/pi-web-access/package-lock.json +5808 -0
  323. package/agent.bak.20260905-190020/extensions/pi-web-access/package.json +64 -0
  324. package/agent.bak.20260905-190020/extensions/pi-web-access/page-query.ts +96 -0
  325. package/agent.bak.20260905-190020/extensions/pi-web-access/pdf-extract.ts +409 -0
  326. package/agent.bak.20260905-190020/extensions/pi-web-access/pi-web-fetch-demo.mp4 +0 -0
  327. package/agent.bak.20260905-190020/extensions/pi-web-access/promise-try.d.ts +7 -0
  328. package/agent.bak.20260905-190020/extensions/pi-web-access/query-rewrite.ts +51 -0
  329. package/agent.bak.20260905-190020/extensions/pi-web-access/render-search-error.ts +170 -0
  330. package/agent.bak.20260905-190020/extensions/pi-web-access/rsc-extract.ts +338 -0
  331. package/agent.bak.20260905-190020/extensions/pi-web-access/search-types.ts +20 -0
  332. package/agent.bak.20260905-190020/extensions/pi-web-access/source-check.ts +282 -0
  333. package/agent.bak.20260905-190020/extensions/pi-web-access/ssrf-protection.ts +526 -0
  334. package/agent.bak.20260905-190020/extensions/pi-web-access/storage.ts +521 -0
  335. package/agent.bak.20260905-190020/extensions/pi-web-access/summary-model-scope.ts +125 -0
  336. package/agent.bak.20260905-190020/extensions/pi-web-access/test/auth-fetch.test.mjs +208 -0
  337. package/agent.bak.20260905-190020/extensions/pi-web-access/test/brightdata-unlocker.test.mjs +840 -0
  338. package/agent.bak.20260905-190020/extensions/pi-web-access/test/chrome-cookie-extraction.test.mjs +441 -0
  339. package/agent.bak.20260905-190020/extensions/pi-web-access/test/config-path.test.mjs +283 -0
  340. package/agent.bak.20260905-190020/extensions/pi-web-access/test/content-find.test.mjs +25 -0
  341. package/agent.bak.20260905-190020/extensions/pi-web-access/test/credential-source.test.mjs +118 -0
  342. package/agent.bak.20260905-190020/extensions/pi-web-access/test/data-uri-sanitize.test.mjs +210 -0
  343. package/agent.bak.20260905-190020/extensions/pi-web-access/test/datalab-pdf-extract.test.mjs +552 -0
  344. package/agent.bak.20260905-190020/extensions/pi-web-access/test/declared-web-links.test.mjs +212 -0
  345. package/agent.bak.20260905-190020/extensions/pi-web-access/test/fetch-answer-storage.test.mjs +40 -0
  346. package/agent.bak.20260905-190020/extensions/pi-web-access/test/fetch-cache-storage.test.mjs +334 -0
  347. package/agent.bak.20260905-190020/extensions/pi-web-access/test/fetch-content-domain-policy.test.mjs +95 -0
  348. package/agent.bak.20260905-190020/extensions/pi-web-access/test/fetch-modes.test.mjs +53 -0
  349. package/agent.bak.20260905-190020/extensions/pi-web-access/test/fetch-not-found-guidance.test.mjs +92 -0
  350. package/agent.bak.20260905-190020/extensions/pi-web-access/test/fetch-params.test.mjs +86 -0
  351. package/agent.bak.20260905-190020/extensions/pi-web-access/test/fetch-render-call.test.mjs +34 -0
  352. package/agent.bak.20260905-190020/extensions/pi-web-access/test/fetch-routing.test.mjs +173 -0
  353. package/agent.bak.20260905-190020/extensions/pi-web-access/test/gemini-adc-auth.test.mjs +257 -0
  354. package/agent.bak.20260905-190020/extensions/pi-web-access/test/gemini-api-transport.test.mjs +170 -0
  355. package/agent.bak.20260905-190020/extensions/pi-web-access/test/gemini-pdf-extract.test.mjs +133 -0
  356. package/agent.bak.20260905-190020/extensions/pi-web-access/test/gemini-web-cookie-opt-in.test.mjs +178 -0
  357. package/agent.bak.20260905-190020/extensions/pi-web-access/test/gemini-web-header-overflow.test.mjs +148 -0
  358. package/agent.bak.20260905-190020/extensions/pi-web-access/test/get-search-content.test.mjs +223 -0
  359. package/agent.bak.20260905-190020/extensions/pi-web-access/test/github-extract.test.mjs +378 -0
  360. package/agent.bak.20260905-190020/extensions/pi-web-access/test/github-issue-pr.test.mjs +565 -0
  361. package/agent.bak.20260905-190020/extensions/pi-web-access/test/inline-content-config.test.mjs +99 -0
  362. package/agent.bak.20260905-190020/extensions/pi-web-access/test/lazy-extract-load.test.mjs +118 -0
  363. package/agent.bak.20260905-190020/extensions/pi-web-access/test/local-video-oversize.test.mjs +52 -0
  364. package/agent.bak.20260905-190020/extensions/pi-web-access/test/package-typebox-dependency.test.mjs +50 -0
  365. package/agent.bak.20260905-190020/extensions/pi-web-access/test/page-query.test.mjs +51 -0
  366. package/agent.bak.20260905-190020/extensions/pi-web-access/test/pdf-config.test.mjs +140 -0
  367. package/agent.bak.20260905-190020/extensions/pi-web-access/test/pdf-extract.test.mjs +500 -0
  368. package/agent.bak.20260905-190020/extensions/pi-web-access/test/proxy-transport.test.mjs +286 -0
  369. package/agent.bak.20260905-190020/extensions/pi-web-access/test/query-rewrite.test.mjs +52 -0
  370. package/agent.bak.20260905-190020/extensions/pi-web-access/test/rsc-fallback.test.mjs +102 -0
  371. package/agent.bak.20260905-190020/extensions/pi-web-access/test/search-error-render.test.mjs +152 -0
  372. package/agent.bak.20260905-190020/extensions/pi-web-access/test/search-providers.test.mjs +274 -0
  373. package/agent.bak.20260905-190020/extensions/pi-web-access/test/source-check.test.mjs +179 -0
  374. package/agent.bak.20260905-190020/extensions/pi-web-access/test/ssrf-allow-ranges-config.test.mjs +205 -0
  375. package/agent.bak.20260905-190020/extensions/pi-web-access/test/ssrf-protection.test.mjs +456 -0
  376. package/agent.bak.20260905-190020/extensions/pi-web-access/test/summary-model-scope.test.mjs +106 -0
  377. package/agent.bak.20260905-190020/extensions/pi-web-access/test/tool-registration-config.test.mjs +182 -0
  378. package/agent.bak.20260905-190020/extensions/pi-web-access/test/web-search-answer-render.test.mjs +66 -0
  379. package/agent.bak.20260905-190020/extensions/pi-web-access/test/youtube-extract-errors.test.mjs +64 -0
  380. package/agent.bak.20260905-190020/extensions/pi-web-access/tsconfig.json +11 -0
  381. package/agent.bak.20260905-190020/extensions/pi-web-access/utils.ts +451 -0
  382. package/agent.bak.20260905-190020/extensions/pi-web-access/video-extract.ts +392 -0
  383. package/agent.bak.20260905-190020/extensions/pi-web-access/youtube-extract.ts +328 -0
  384. package/agent.bak.20260905-190020/extensions/shared/activity-status.ts +31 -0
  385. package/agent.bak.20260905-190020/extensions/shared/child-session.ts +148 -0
  386. package/agent.bak.20260905-190020/extensions/shared/context-utilization.ts +47 -0
  387. package/agent.bak.20260905-190020/extensions/shared/dashboard-state.ts +99 -0
  388. package/agent.bak.20260905-190020/extensions/shared/install.ps1 +23 -0
  389. package/agent.bak.20260905-190020/extensions/shared/install.sh +21 -0
  390. package/agent.bak.20260905-190020/extensions/shared/test/child-session.test.ts +270 -0
  391. package/agent.bak.20260905-190020/extensions/shared/test/context-utilization.test.ts +48 -0
  392. package/agent.bak.20260905-190020/extensions/shared/test/tool-call-timeout.test.ts +117 -0
  393. package/agent.bak.20260905-190020/extensions/shared/test/widget-order.test.ts +167 -0
  394. package/agent.bak.20260905-190020/extensions/shared/tool-call-timeout.ts +104 -0
  395. package/agent.bak.20260905-190020/extensions/skillsconf/README.md +74 -0
  396. package/agent.bak.20260905-190020/extensions/skillsconf/index.ts +92 -0
  397. package/agent.bak.20260905-190020/extensions/skillsconf/install.ps1 +23 -0
  398. package/agent.bak.20260905-190020/extensions/skillsconf/install.sh +21 -0
  399. package/agent.bak.20260905-190020/extensions/skillsconf/package-lock.json +1809 -0
  400. package/agent.bak.20260905-190020/extensions/skillsconf/package.json +18 -0
  401. package/agent.bak.20260905-190020/extensions/skillsconf/src/delete-skill.test.ts +64 -0
  402. package/agent.bak.20260905-190020/extensions/skillsconf/src/delete-skill.ts +45 -0
  403. package/agent.bak.20260905-190020/extensions/skillsconf/src/filter.test.ts +80 -0
  404. package/agent.bak.20260905-190020/extensions/skillsconf/src/filter.ts +74 -0
  405. package/agent.bak.20260905-190020/extensions/skillsconf/src/fuzzy.ts +26 -0
  406. package/agent.bak.20260905-190020/extensions/skillsconf/src/persistence.test.ts +72 -0
  407. package/agent.bak.20260905-190020/extensions/skillsconf/src/persistence.ts +169 -0
  408. package/agent.bak.20260905-190020/extensions/skillsconf/src/ui/SkillConfView.test.ts +337 -0
  409. package/agent.bak.20260905-190020/extensions/skillsconf/src/ui/SkillConfView.ts +758 -0
  410. package/agent.bak.20260905-190020/extensions/skillsconf/src/ui/text-input.ts +91 -0
  411. package/agent.bak.20260905-190020/extensions/skillsconf/src/ui/tui-helpers.ts +144 -0
  412. package/agent.bak.20260905-190020/extensions/skillsconf/tsconfig.json +15 -0
  413. package/agent.bak.20260905-190020/extensions/statusline/install.ps1 +23 -0
  414. package/agent.bak.20260905-190020/extensions/statusline/install.sh +21 -0
  415. package/agent.bak.20260905-190020/extensions/subagents/docs/design-plan.md +568 -0
  416. package/agent.bak.20260905-190020/extensions/subagents/docs/effect-v4-extension-guide.md +354 -0
  417. package/agent.bak.20260905-190020/extensions/subagents/docs/effect-v4-notes.md +571 -0
  418. package/agent.bak.20260905-190020/extensions/subagents/index.ts +826 -0
  419. package/agent.bak.20260905-190020/extensions/subagents/install.ps1 +23 -0
  420. package/agent.bak.20260905-190020/extensions/subagents/install.sh +21 -0
  421. package/agent.bak.20260905-190020/extensions/subagents/package-lock.json +2244 -0
  422. package/agent.bak.20260905-190020/extensions/subagents/package.json +19 -0
  423. package/agent.bak.20260905-190020/extensions/subagents/src/backend.ts +73 -0
  424. package/agent.bak.20260905-190020/extensions/subagents/src/backends/claude.ts +701 -0
  425. package/agent.bak.20260905-190020/extensions/subagents/src/backends/codex.ts +1060 -0
  426. package/agent.bak.20260905-190020/extensions/subagents/src/backends/pi.ts +575 -0
  427. package/agent.bak.20260905-190020/extensions/subagents/src/backends/stub.ts +300 -0
  428. package/agent.bak.20260905-190020/extensions/subagents/src/by-the-way.ts +21 -0
  429. package/agent.bak.20260905-190020/extensions/subagents/src/domain.ts +253 -0
  430. package/agent.bak.20260905-190020/extensions/subagents/src/format.ts +74 -0
  431. package/agent.bak.20260905-190020/extensions/subagents/src/manager.ts +736 -0
  432. package/agent.bak.20260905-190020/extensions/subagents/src/prompt.ts +92 -0
  433. package/agent.bak.20260905-190020/extensions/subagents/src/result-delivery.ts +20 -0
  434. package/agent.bak.20260905-190020/extensions/subagents/src/runtime.ts +53 -0
  435. package/agent.bak.20260905-190020/extensions/subagents/src/ui/takeover.ts +583 -0
  436. package/agent.bak.20260905-190020/extensions/subagents/src/ui/transcript.ts +201 -0
  437. package/agent.bak.20260905-190020/extensions/subagents/src/widget-order.ts +121 -0
  438. package/agent.bak.20260905-190020/extensions/subagents/test/by-the-way.test.ts +29 -0
  439. package/agent.bak.20260905-190020/extensions/subagents/test/claude.test.ts +119 -0
  440. package/agent.bak.20260905-190020/extensions/subagents/test/codex.test.ts +102 -0
  441. package/agent.bak.20260905-190020/extensions/subagents/test/context-usage.test.ts +107 -0
  442. package/agent.bak.20260905-190020/extensions/subagents/test/manager.test.ts +276 -0
  443. package/agent.bak.20260905-190020/extensions/subagents/test/result-delivery.test.ts +27 -0
  444. package/agent.bak.20260905-190020/extensions/subagents/test/takeover.test.ts +29 -0
  445. package/agent.bak.20260905-190020/extensions/subagents/tsconfig.json +7 -0
  446. package/agent.bak.20260905-190020/extensions/taste/index.ts +443 -0
  447. package/agent.bak.20260905-190020/extensions/taste/install.ps1 +23 -0
  448. package/agent.bak.20260905-190020/extensions/taste/install.sh +21 -0
  449. package/agent.bak.20260905-190020/extensions/todo/AGENTS.md +38 -0
  450. package/agent.bak.20260905-190020/extensions/todo/LICENSE +21 -0
  451. package/agent.bak.20260905-190020/extensions/todo/config.ts +55 -0
  452. package/agent.bak.20260905-190020/extensions/todo/index.ts +151 -0
  453. package/agent.bak.20260905-190020/extensions/todo/install.ps1 +23 -0
  454. package/agent.bak.20260905-190020/extensions/todo/install.sh +21 -0
  455. package/agent.bak.20260905-190020/extensions/todo/locales/de.json +17 -0
  456. package/agent.bak.20260905-190020/extensions/todo/locales/en.json +15 -0
  457. package/agent.bak.20260905-190020/extensions/todo/locales/es.json +17 -0
  458. package/agent.bak.20260905-190020/extensions/todo/locales/fr.json +17 -0
  459. package/agent.bak.20260905-190020/extensions/todo/locales/pt-BR.json +17 -0
  460. package/agent.bak.20260905-190020/extensions/todo/locales/pt.json +17 -0
  461. package/agent.bak.20260905-190020/extensions/todo/locales/ru.json +17 -0
  462. package/agent.bak.20260905-190020/extensions/todo/locales/uk.json +17 -0
  463. package/agent.bak.20260905-190020/extensions/todo/locales/zh.json +17 -0
  464. package/agent.bak.20260905-190020/extensions/todo/package-lock.json +3358 -0
  465. package/agent.bak.20260905-190020/extensions/todo/package.json +67 -0
  466. package/agent.bak.20260905-190020/extensions/todo/state/i18n-bridge.ts +64 -0
  467. package/agent.bak.20260905-190020/extensions/todo/state/invariants.ts +20 -0
  468. package/agent.bak.20260905-190020/extensions/todo/state/replay.ts +38 -0
  469. package/agent.bak.20260905-190020/extensions/todo/state/selectors.ts +107 -0
  470. package/agent.bak.20260905-190020/extensions/todo/state/state-reducer.ts +326 -0
  471. package/agent.bak.20260905-190020/extensions/todo/state/state.ts +18 -0
  472. package/agent.bak.20260905-190020/extensions/todo/state/store.ts +82 -0
  473. package/agent.bak.20260905-190020/extensions/todo/state/task-graph.ts +57 -0
  474. package/agent.bak.20260905-190020/extensions/todo/todo-overlay.ts +204 -0
  475. package/agent.bak.20260905-190020/extensions/todo/todo.ts +155 -0
  476. package/agent.bak.20260905-190020/extensions/todo/tool/response-envelope.ts +109 -0
  477. package/agent.bak.20260905-190020/extensions/todo/tool/types.ts +206 -0
  478. package/agent.bak.20260905-190020/extensions/todo/view/format.ts +177 -0
  479. package/agent.bak.20260905-190020/extensions/todo/widget-order.ts +121 -0
  480. package/agent.bak.20260905-190020/extensions/trim-context/README.md +54 -0
  481. package/agent.bak.20260905-190020/extensions/trim-context/index.ts +487 -0
  482. package/agent.bak.20260905-190020/extensions/trim-context/install.ps1 +23 -0
  483. package/agent.bak.20260905-190020/extensions/trim-context/install.sh +21 -0
  484. package/agent.bak.20260905-190020/keybindings.json +7 -0
  485. package/bin/kiln.js +588 -358
  486. package/package.json +27 -21
  487. package/agent/install.ps1 +0 -527
  488. package/agent/install.sh +0 -511
  489. /package/{agent/extensions/status line → agent.bak.20260905-190020/extensions/ask-user}/install.ps1 +0 -0
  490. /package/{agent/extensions/status line → agent.bak.20260905-190020/extensions/ask-user}/install.sh +0 -0
  491. /package/{agent/extensions/status line → agent.bak.20260905-190020/extensions/statusline}/index.ts +0 -0
@@ -0,0 +1,629 @@
1
+ /**
2
+ * Background terminals — start long-running shell processes the model can
3
+ * inspect and stop, but never write to (stdin is ignored at the OS level).
4
+ *
5
+ * Tools (for the LLM):
6
+ * - bg_start: fire-and-forget spawn (command, title, working_dir). Max 8
7
+ * running at once. The model is notified exactly once when a process exits.
8
+ * - bg_status: peek at one terminal's status + tail-truncated output.
9
+ * - bg_list: list all tracked terminals (running and settled).
10
+ * - bg_kill: SIGTERM→SIGKILL the whole process tree; returns final state.
11
+ *
12
+ * While ≥1 process runs, a one-line widget above the editor shows
13
+ * "N background terminal(s) running • /ps to view". `/ps` opens a two-stage
14
+ * full-screen overlay (list → read-only detail with stdout/stderr toggle).
15
+ *
16
+ * Architecture: Effect v4 core (manager service behind one ManagedRuntime);
17
+ * this file is the async boundary where tool handlers run effects via
18
+ * runTool. Node stream plumbing inside the manager is plain callbacks.
19
+ */
20
+
21
+ import * as fs from "node:fs";
22
+ import * as path from "node:path";
23
+ import type {
24
+ ExtensionAPI,
25
+ ExtensionContext,
26
+ ExtensionUIContext,
27
+ } from "@earendil-works/pi-coding-agent";
28
+ import { getMarkdownTheme } from "@earendil-works/pi-coding-agent";
29
+ import { Markdown, Text } from "@earendil-works/pi-tui";
30
+ import { Type } from "typebox";
31
+ import type { TerminalSnapshot } from "./src/domain.ts";
32
+ import { TerminalManager, type TerminalManagerShape } from "./src/manager.ts";
33
+ import {
34
+ BG_KILL_PARAMETER_DESCRIPTIONS,
35
+ BG_KILL_TOOL_DESCRIPTION,
36
+ BG_LIST_TOOL_DESCRIPTION,
37
+ BG_START_PARAMETER_DESCRIPTIONS,
38
+ BG_START_PROMPT_GUIDELINES,
39
+ BG_START_PROMPT_SNIPPET,
40
+ BG_START_TOOL_DESCRIPTION,
41
+ BG_STATUS_PARAMETER_DESCRIPTIONS,
42
+ BG_STATUS_TOOL_DESCRIPTION,
43
+ buildKillReport,
44
+ buildStartResult,
45
+ buildStatusResult,
46
+ buildTerminalResultMessage,
47
+ describeTerminal,
48
+ } from "./src/prompt.ts";
49
+ import { createDeferredResultDelivery } from "./src/result-delivery.ts";
50
+ import { hideOrderedWidget, setOrderedWidget } from "./src/widget-order.ts";
51
+ import {
52
+ createTerminalRuntime,
53
+ runTool,
54
+ type TerminalRuntime,
55
+ } from "./src/runtime.ts";
56
+ import { sanitizeText } from "./src/ui/output-view.ts";
57
+ import { openTerminalPicker } from "./src/ui/ps.ts";
58
+ import { createBashTool } from "@earendil-works/pi-coding-agent";
59
+
60
+ const WIDGET_KEY = "background-terminals";
61
+
62
+ const AUTO_PROMOTE_MS = 50_000;
63
+ const AUTO_PROMOTE_SEC = AUTO_PROMOTE_MS / 1000;
64
+
65
+ const RESULT_PREVIEW_LINES = 10;
66
+
67
+ /** Tool call line: bold-white tool name, 2-space indent (Box adds 1 + Text 1). */
68
+ function renderToolCall(name: string, theme: any): Text {
69
+ return new Text(theme.fg("toolTitle", theme.bold(name)), 1, 0);
70
+ }
71
+
72
+ /** Tool result: grey text at 2-space indent, collapsed to a short preview. */
73
+ function renderToolResult(result: any, theme: any): Text {
74
+ const text = (result?.content ?? [])
75
+ .filter((c: any) => c?.type === "text" && typeof c?.text === "string")
76
+ .map((c: any) => c.text)
77
+ .join("\n");
78
+ if (!text) return new Text("", 1, 0);
79
+ const lines = text.split("\n");
80
+ const preview = lines.slice(0, RESULT_PREVIEW_LINES);
81
+ let out = theme.fg("toolOutput", preview.join("\n"));
82
+ if (lines.length > RESULT_PREVIEW_LINES) {
83
+ out += theme.fg("dim", `\n... (${lines.length - RESULT_PREVIEW_LINES} more lines)`);
84
+ }
85
+ return new Text(out, 1, 0);
86
+ }
87
+
88
+ export default function (pi: ExtensionAPI) {
89
+ let runtime: TerminalRuntime | undefined;
90
+ let managerPromise: Promise<TerminalManagerShape> | undefined;
91
+ let sessionContext: ExtensionContext | undefined;
92
+ let ui: ExtensionUIContext | undefined;
93
+ let unsubStatus: (() => void) | undefined;
94
+ const resultDelivery = createDeferredResultDelivery<TerminalSnapshot>();
95
+
96
+ const getRuntime = () => (runtime ??= createTerminalRuntime());
97
+
98
+ /** Resolve the manager service once per runtime and wire the extension hooks. */
99
+ const getManager = () => {
100
+ managerPromise ??= getRuntime()
101
+ .runPromise(TerminalManager)
102
+ .then((manager) => {
103
+ manager.view.setOnSettled(onSettled);
104
+ unsubStatus?.();
105
+ unsubStatus = manager.view.subscribe(() => updateWidget(manager));
106
+ updateWidget(manager);
107
+ return manager;
108
+ });
109
+ return managerPromise;
110
+ };
111
+
112
+ /** One-line widget directly above the editor, only while ≥1 is running.
113
+ * Called on every manager notification (including per-output-chunk), so it
114
+ * only touches setWidget when the running count actually changes —
115
+ * replacing the widget factory hundreds of times a second would churn
116
+ * component creation for no visible difference. */
117
+ let widgetRunning = 0;
118
+ const updateWidget = (manager: TerminalManagerShape) => {
119
+ if (!ui) return;
120
+ try {
121
+ const running = manager.view
122
+ .list()
123
+ .filter((snap) => snap.status === "running").length;
124
+ if (running === widgetRunning) return;
125
+ widgetRunning = running;
126
+ if (running === 0) {
127
+ // Ordered helper keeps todos above us and subagents below us.
128
+ hideOrderedWidget(ui, WIDGET_KEY);
129
+ return;
130
+ }
131
+ setOrderedWidget(ui, WIDGET_KEY, (_tui, theme) => {
132
+ const line =
133
+ theme.fg("warning", "■ ") +
134
+ theme.fg(
135
+ "text",
136
+ `${running} background terminal${running === 1 ? "" : "s"} running`,
137
+ ) +
138
+ theme.fg("dim", " • ") +
139
+ theme.fg("accent", "/ps") +
140
+ theme.fg("dim", " to view");
141
+ return { render: () => [line], invalidate: () => {} };
142
+ });
143
+ } catch {
144
+ // UI may be unavailable (print/RPC modes or teardown).
145
+ }
146
+ };
147
+
148
+ const deliverResult = (snap: TerminalSnapshot) => {
149
+ try {
150
+ pi.sendMessage(
151
+ {
152
+ customType: "background-terminal-result",
153
+ content: buildTerminalResultMessage(snap),
154
+ display: true,
155
+ details: {
156
+ id: snap.id,
157
+ title: snap.title,
158
+ status: snap.status,
159
+ exitCode: snap.exitCode,
160
+ signal: snap.signal,
161
+ },
162
+ },
163
+ // followUp: queued until the agent has no more tool calls — never
164
+ // interrupts a mid-turn stream. triggerTurn: wakes the model
165
+ // immediately iff idle; if busy, the queued follow-up is delivered
166
+ // when the current run settles. Either way exactly one delivery.
167
+ { deliverAs: "followUp", triggerTurn: true },
168
+ );
169
+ return true;
170
+ } catch (error) {
171
+ // Session may be shutting down, but retain the snapshot so any later
172
+ // agent-settled flush can retry instead of silently dropping it.
173
+ console.error("background-terminals: failed to deliver result", error);
174
+ return false;
175
+ }
176
+ };
177
+
178
+ const flushResults = () => {
179
+ for (const snap of resultDelivery.drain()) {
180
+ if (!deliverResult(snap)) resultDelivery.defer(snap);
181
+ }
182
+ };
183
+
184
+ const onSettled = (snap: TerminalSnapshot, consumed: boolean) => {
185
+ if (consumed) {
186
+ // An in-flight bg_kill is returning this settlement itself.
187
+ resultDelivery.consume([snap.id]);
188
+ return;
189
+ }
190
+ // Defer a deep-enough copy: the live snapshot's output views keep
191
+ // mutating (late flushes) after settle.
192
+ resultDelivery.defer({
193
+ ...snap,
194
+ stdout: { ...snap.stdout },
195
+ stderr: { ...snap.stderr },
196
+ });
197
+ if (sessionContext?.isIdle()) flushResults();
198
+ };
199
+
200
+ pi.on("session_start", (_event, ctx) => {
201
+ sessionContext = ctx;
202
+ if (ctx.hasUI) ui = ctx.ui;
203
+ });
204
+
205
+ // Drain deferred results when the agent settles: together with the
206
+ // isIdle() fast path above and the Map-keyed delivery (drain clears),
207
+ // double delivery is structurally impossible — whoever drains first wins.
208
+ pi.on("agent_settled", flushResults);
209
+
210
+ // /new, /resume, /fork, /reload, and quit all emit session_shutdown for
211
+ // the old extension instance. Processes never survive a session
212
+ // transition: disposing the runtime runs the manager finalizer →
213
+ // disposeAll → every entry scope → SIGTERM→SIGKILL tree kill, each close
214
+ // bounded so a wedged process cannot hang shutdown.
215
+ pi.on("session_shutdown", async () => {
216
+ sessionContext = undefined;
217
+ resultDelivery.clear();
218
+ unsubStatus?.();
219
+ unsubStatus = undefined;
220
+ try {
221
+ hideOrderedWidget(ui, WIDGET_KEY);
222
+ } catch {
223
+ // UI may already be gone.
224
+ }
225
+ widgetRunning = 0;
226
+ ui = undefined;
227
+ const closing = runtime;
228
+ runtime = undefined;
229
+ managerPromise = undefined;
230
+ await closing?.dispose();
231
+ });
232
+
233
+ // --- Tools -------------------------------------------------------------
234
+
235
+ pi.registerTool({
236
+ name: "bg_start",
237
+ label: "Start Background Terminal",
238
+ renderCall: (_args: any, theme: any) => renderToolCall("bg_start", theme),
239
+ renderResult: (result: any, _options: any, theme: any) => renderToolResult(result, theme),
240
+ description: BG_START_TOOL_DESCRIPTION,
241
+ promptSnippet: BG_START_PROMPT_SNIPPET,
242
+ promptGuidelines: BG_START_PROMPT_GUIDELINES,
243
+ parameters: Type.Object({
244
+ command: Type.String({
245
+ description: BG_START_PARAMETER_DESCRIPTIONS.command,
246
+ }),
247
+ title: Type.String({
248
+ description: BG_START_PARAMETER_DESCRIPTIONS.title,
249
+ }),
250
+ working_dir: Type.Optional(
251
+ Type.String({
252
+ description: BG_START_PARAMETER_DESCRIPTIONS.workingDir,
253
+ }),
254
+ ),
255
+ }),
256
+ async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
257
+ const manager = await getManager();
258
+
259
+ const command = params.command.trim();
260
+ if (!command) throw new Error("command must not be empty.");
261
+
262
+ const cwd = path.resolve(ctx.cwd, params.working_dir ?? ".");
263
+ if (!fs.existsSync(cwd) || !fs.statSync(cwd).isDirectory()) {
264
+ throw new Error(`working_dir is not a directory: ${cwd}`);
265
+ }
266
+
267
+ // Collapse whitespace (a newline inside a one-line UI row desyncs the
268
+ // TUI renderer) before bounding the length.
269
+ const title =
270
+ params.title.replace(/\s+/g, " ").trim().slice(0, 80) || "terminal";
271
+ const snap = await runTool(
272
+ getRuntime(),
273
+ manager.start({ command, title, cwd }),
274
+ );
275
+
276
+ return {
277
+ content: [{ type: "text", text: buildStartResult(snap) }],
278
+ details: { id: snap.id, title: snap.title, cwd, pid: snap.pid },
279
+ };
280
+ },
281
+ });
282
+
283
+ pi.registerTool({
284
+ name: "bg_status",
285
+ label: "Check Background Terminal",
286
+ renderCall: (_args: any, theme: any) => renderToolCall("bg_status", theme),
287
+ renderResult: (result: any, _options: any, theme: any) => renderToolResult(result, theme),
288
+ description: BG_STATUS_TOOL_DESCRIPTION,
289
+ parameters: Type.Object({
290
+ id: Type.String({ description: BG_STATUS_PARAMETER_DESCRIPTIONS.id }),
291
+ }),
292
+ async execute(_toolCallId, params) {
293
+ const manager = await getManager();
294
+ const snap = manager.view.get(params.id);
295
+ if (!snap) {
296
+ const known = manager.view.list().map((s) => s.id);
297
+ throw new Error(
298
+ `Unknown terminal id "${params.id}". Known: ${known.join(", ") || "none"}.`,
299
+ );
300
+ }
301
+
302
+ // This status is returning the settlement itself; a pending automatic
303
+ // follow-up for the same settle would be a duplicate.
304
+ if (snap.status !== "running") resultDelivery.consume([snap.id]);
305
+
306
+ return {
307
+ content: [{ type: "text", text: buildStatusResult(snap) }],
308
+ details: {
309
+ id: snap.id,
310
+ status: snap.status,
311
+ pid: snap.pid,
312
+ exitCode: snap.exitCode,
313
+ signal: snap.signal,
314
+ },
315
+ };
316
+ },
317
+ });
318
+
319
+ pi.registerTool({
320
+ name: "bg_list",
321
+ label: "List Background Terminals",
322
+ renderCall: (_args: any, theme: any) => renderToolCall("bg_list", theme),
323
+ renderResult: (result: any, _options: any, theme: any) => renderToolResult(result, theme),
324
+ description: BG_LIST_TOOL_DESCRIPTION,
325
+ parameters: Type.Object({}),
326
+ async execute() {
327
+ const manager = await getManager();
328
+ const terminals = manager.view.list();
329
+ const text =
330
+ terminals.length === 0
331
+ ? "No background terminals."
332
+ : terminals.map((snap) => describeTerminal(snap)).join("\n");
333
+ return {
334
+ content: [{ type: "text", text }],
335
+ details: {
336
+ terminals: terminals.map((snap) => ({
337
+ id: snap.id,
338
+ title: snap.title,
339
+ status: snap.status,
340
+ pid: snap.pid,
341
+ })),
342
+ },
343
+ };
344
+ },
345
+ });
346
+
347
+ pi.registerTool({
348
+ name: "bg_kill",
349
+ label: "Kill Background Terminals",
350
+ renderCall: (_args: any, theme: any) => renderToolCall("bg_kill", theme),
351
+ renderResult: (result: any, _options: any, theme: any) => renderToolResult(result, theme),
352
+ description: BG_KILL_TOOL_DESCRIPTION,
353
+ parameters: Type.Object({
354
+ ids: Type.Array(Type.String(), {
355
+ description: BG_KILL_PARAMETER_DESCRIPTIONS.ids,
356
+ }),
357
+ }),
358
+ async execute(_toolCallId, params, signal) {
359
+ const manager = await getManager();
360
+ const ids = [...new Set(params.ids)];
361
+ if (ids.length === 0)
362
+ throw new Error("Provide at least one terminal id.");
363
+
364
+ const known = manager.view.list().map((snap) => snap.id);
365
+ const unknown = ids.filter((id) => !manager.view.get(id));
366
+ if (unknown.length > 0) {
367
+ throw new Error(
368
+ `Unknown terminal id(s): ${unknown.join(", ")}. Known: ${known.join(", ") || "none"}.`,
369
+ );
370
+ }
371
+
372
+ const report = await runTool(getRuntime(), manager.kill(ids), {
373
+ signal,
374
+ interruptMessage:
375
+ "Kill wait aborted; termination continues in the background.",
376
+ });
377
+
378
+ // Settlement may have happened before this kill began (or during it,
379
+ // via the killInterest consumed flag). Remove any deferred automatic
380
+ // delivery now that this tool returns the final state itself.
381
+ resultDelivery.consume(ids);
382
+
383
+ return {
384
+ content: [{ type: "text", text: buildKillReport(report) }],
385
+ details: {
386
+ results: report.map((entry) => ({
387
+ id: entry.id,
388
+ title: entry.title,
389
+ status: entry.status,
390
+ killed: entry.killed,
391
+ })),
392
+ },
393
+ };
394
+ },
395
+ });
396
+
397
+ // --- Result message rendering ------------------------------------------
398
+
399
+ pi.registerMessageRenderer(
400
+ "background-terminal-result",
401
+ (message, { expanded }, theme) => {
402
+ const details = (message.details ?? {}) as {
403
+ id?: string;
404
+ title?: string;
405
+ status?: string;
406
+ exitCode?: number;
407
+ signal?: string;
408
+ };
409
+ const failed = details.status === "failed";
410
+ const killed = details.status === "killed";
411
+ const icon = failed
412
+ ? theme.fg("error", "x")
413
+ : killed
414
+ ? theme.fg("muted", "■")
415
+ : theme.fg("success", "■");
416
+ const how = killed
417
+ ? "killed"
418
+ : (details.signal ?? `exit ${details.exitCode ?? "?"}`);
419
+ const header =
420
+ `${icon} ` +
421
+ theme.fg("accent", theme.bold(`terminal ${details.id ?? "?"}`)) +
422
+ theme.fg("muted", ` · ${details.title ?? ""} · ${how}`);
423
+
424
+ const content =
425
+ typeof message.content === "string" ? message.content : "";
426
+ // Remove only the summary line; the Error line (when present) is part
427
+ // of the actual result and must remain visible. The body carries raw
428
+ // process output — sanitize ANSI/control chars or the transcript smears.
429
+ const body = sanitizeText(content.split("\n").slice(1).join("\n").trim());
430
+
431
+ if (expanded) {
432
+ const md = new Markdown(`${body}`, 0, 0, getMarkdownTheme());
433
+ const container = new Text(header, 0, 0);
434
+ return {
435
+ render: (width: number) => [
436
+ ...container.render(width),
437
+ ...md.render(width),
438
+ ],
439
+ invalidate: () => {
440
+ container.invalidate();
441
+ md.invalidate();
442
+ },
443
+ };
444
+ }
445
+
446
+ const previewLines = body.split("\n").slice(0, 8);
447
+ let text = header;
448
+ for (const line of previewLines)
449
+ text += `\n${theme.fg("toolOutput", line)}`;
450
+ if (body.split("\n").length > 8)
451
+ text += `\n${theme.fg("dim", "... (ctrl+o to expand)")}`;
452
+ return new Text(text, 0, 0);
453
+ },
454
+ );
455
+
456
+ // --- Auto-promote long bash to background ---------------------------------
457
+ // If a bash tool call exceeds 50s, abort the blocking call, restart it
458
+ // as a background terminal, and alert the agent + UI. The background
459
+ // result is still delivered as a follow-up when it settles.
460
+ const baseBashTool: any = createBashTool(process.cwd());
461
+ pi.registerTool({
462
+ ...baseBashTool,
463
+ description: `${baseBashTool.description} If execution exceeds ${AUTO_PROMOTE_SEC}s it is automatically promoted to a background terminal (check with bg_status/bg_list or /ps; result arrives as follow-up).`,
464
+ async execute(
465
+ toolCallId: string,
466
+ params: any,
467
+ signal: AbortSignal | undefined,
468
+ onUpdate: any,
469
+ ctx: ExtensionContext,
470
+ ) {
471
+ const command: string = params.command;
472
+ const cwd = (ctx as any).cwd ?? process.cwd();
473
+ const title = command.replace(/\s+/g, " ").trim().slice(0, 80) || "bash auto-promoted";
474
+
475
+ // Delegate tool bound to the current cwd so built-in bash semantics
476
+ // (shell, env, truncation) stay identical for the fast path.
477
+ const delegateTool: any = createBashTool(cwd);
478
+
479
+ let lastPartial = "";
480
+ const wrappedOnUpdate = (update: any) => {
481
+ try {
482
+ const text = update?.content?.[0]?.text;
483
+ if (typeof text === "string") lastPartial = text;
484
+ } catch {}
485
+ if (onUpdate) try { onUpdate(update); } catch {}
486
+ };
487
+
488
+ const execAbortController = new AbortController();
489
+ const onIncomingAbort = () => execAbortController.abort();
490
+ if (signal) {
491
+ if (signal.aborted) execAbortController.abort();
492
+ else signal.addEventListener("abort", onIncomingAbort, { once: true });
493
+ }
494
+
495
+ const execPromise: Promise<{ kind: "done"; res: any } | { kind: "error"; err: unknown }> = delegateTool
496
+ .execute(toolCallId, params, execAbortController.signal, wrappedOnUpdate, ctx as any)
497
+ .then(
498
+ (res: any) => ({ kind: "done" as const, res }),
499
+ (err: unknown) => ({ kind: "error" as const, err }),
500
+ );
501
+
502
+ let timerId: ReturnType<typeof setTimeout> | undefined;
503
+ const timerPromise = new Promise<{ kind: "promote" }>((resolve) => {
504
+ timerId = setTimeout(() => resolve({ kind: "promote" }), AUTO_PROMOTE_MS);
505
+ });
506
+
507
+ const race = (await Promise.race([execPromise, timerPromise])) as
508
+ | { kind: "done"; res: any }
509
+ | { kind: "error"; err: unknown }
510
+ | { kind: "promote" };
511
+
512
+ if (race.kind !== "promote") {
513
+ if (timerId) clearTimeout(timerId);
514
+ if (signal) signal.removeEventListener("abort", onIncomingAbort);
515
+ if (race.kind === "done") return race.res;
516
+ throw race.err;
517
+ }
518
+
519
+ // Timer won — promote to background terminal.
520
+ // Abort the original blocking execution (kills its process tree).
521
+ execAbortController.abort();
522
+ if (signal) signal.removeEventListener("abort", onIncomingAbort);
523
+
524
+ // If the caller already aborted (Esc), don't promote — just propagate.
525
+ if (signal?.aborted) {
526
+ try {
527
+ const settled = await execPromise;
528
+ if (settled.kind === "error") throw settled.err;
529
+ return (settled as any).res;
530
+ } catch (e) {
531
+ throw e;
532
+ }
533
+ }
534
+
535
+ // Let the aborted exec settle (or timeout after 2s if it hangs).
536
+ try {
537
+ await Promise.race([
538
+ execPromise.catch(() => {}),
539
+ new Promise((r) => setTimeout(r, 2000)),
540
+ ]);
541
+ } catch {}
542
+
543
+ let snap: TerminalSnapshot | undefined;
544
+ let spawnError: unknown;
545
+ try {
546
+ const manager = await getManager();
547
+ snap = await runTool(getRuntime(), manager.start({ command, title, cwd }));
548
+ } catch (e) {
549
+ spawnError = e;
550
+ }
551
+
552
+ if (!snap || spawnError) {
553
+ const msg = spawnError instanceof Error ? spawnError.message : String(spawnError ?? "unknown error");
554
+ const text = [
555
+ `⚠️ Bash command exceeded ${AUTO_PROMOTE_SEC}s but could not be promoted to a background terminal: ${msg}`,
556
+ "",
557
+ `Command: ${command}`,
558
+ "",
559
+ lastPartial ? `Partial output (first ${AUTO_PROMOTE_SEC}s, truncated):\n${lastPartial.slice(-3000)}` : "No output captured before promotion attempt.",
560
+ "",
561
+ "The original blocking command was aborted. Retry with bg_start directly or free a slot with bg_kill (/ps).",
562
+ ].join("\n");
563
+ if ((ctx as any).hasUI) {
564
+ try { (ctx as any).ui.notify(`Bash auto-promote failed: ${msg}`, "warning"); } catch {}
565
+ }
566
+ return {
567
+ content: [{ type: "text", text }],
568
+ details: { promoted: false, error: msg, command, cwd, partialOutput: lastPartial },
569
+ };
570
+ }
571
+
572
+ const partialPreview = lastPartial ? lastPartial.slice(-3000) : "(no output yet)";
573
+ const text = [
574
+ `⏳ Bash command exceeded ${AUTO_PROMOTE_SEC}s and was automatically moved to a background terminal.`,
575
+ "",
576
+ `• Terminal ID: ${snap.id}`,
577
+ `• Title: ${snap.title}`,
578
+ `• Command: ${command}`,
579
+ `• CWD: ${cwd}`,
580
+ `• PID: ${snap.pid ?? "pending"}`,
581
+ "",
582
+ "The original blocking bash call was aborted and the command was restarted as a background terminal. It continues running in the background.",
583
+ `Use bg_status with id "${snap.id}" or bg_list or /ps to inspect output. Its result will be delivered automatically when it finishes.`,
584
+ "",
585
+ lastPartial ? `Partial output captured in first ${AUTO_PROMOTE_SEC}s (truncated):\n${partialPreview}` : "",
586
+ ]
587
+ .filter(Boolean)
588
+ .join("\n");
589
+
590
+ if ((ctx as any).hasUI) {
591
+ try { (ctx as any).ui.notify(`Bash auto-promoted to background terminal ${snap.id} (${snap.title})`, "info"); } catch {}
592
+ }
593
+
594
+ return {
595
+ content: [{ type: "text", text }],
596
+ details: { promoted: true, id: snap.id, title: snap.title, pid: snap.pid, cwd, command },
597
+ };
598
+ },
599
+ });
600
+
601
+ // --- Command ------------------------------------------------------------
602
+
603
+ pi.registerCommand("ps", {
604
+ description: "List and inspect background terminals",
605
+ handler: async (_args, ctx) => {
606
+ const manager = await getManager();
607
+ if (ctx.mode !== "tui") {
608
+ if (ctx.hasUI) {
609
+ const terminals = manager.view.list();
610
+ ctx.ui.notify(
611
+ terminals.length === 0
612
+ ? "No background terminals."
613
+ : terminals.map((snap) => describeTerminal(snap)).join("\n"),
614
+ "info",
615
+ );
616
+ }
617
+ return;
618
+ }
619
+ if (manager.view.size() === 0) {
620
+ ctx.ui.notify(
621
+ "No background terminals yet. The agent starts them with bg_start.",
622
+ "info",
623
+ );
624
+ return;
625
+ }
626
+ await openTerminalPicker(ctx, manager.view);
627
+ },
628
+ });
629
+ }
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env pwsh
2
+ # Per-extension installer — Windows / PowerShell
3
+ # Installs npm dependencies for this extension. No-op if no package.json.
4
+ $ErrorActionPreference = "Stop"
5
+ $extDir = $PSScriptRoot
6
+ if (-not $extDir) { $extDir = Split-Path -Parent $MyInvocation.MyCommand.Path }
7
+ if (-not (Test-Path "$extDir/package.json")) {
8
+ Write-Host " - no package.json — skipping" -ForegroundColor DarkGray
9
+ exit 0
10
+ }
11
+ if (-not (Get-Command npm -ErrorAction SilentlyContinue)) {
12
+ Write-Host " x npm not found — install Node.js 22+" -ForegroundColor Red
13
+ exit 1
14
+ }
15
+ if (Test-Path "$extDir/package-lock.json") {
16
+ Write-Host " - npm ci" -ForegroundColor DarkGray
17
+ npm --prefix $extDir ci --no-audit --no-fund
18
+ } else {
19
+ Write-Host " - npm install" -ForegroundColor DarkGray
20
+ npm --prefix $extDir install --no-audit --no-fund
21
+ }
22
+ if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
23
+ Write-Host " + done" -ForegroundColor Green
@@ -0,0 +1,21 @@
1
+ #!/bin/sh
2
+ # Per-extension installer — macOS / Linux
3
+ # Installs npm dependencies for this extension. No-op if no package.json.
4
+ set -eu
5
+ EXT_DIR="$(cd "$(dirname "$0")" && pwd)"
6
+ if [ ! -f "$EXT_DIR/package.json" ]; then
7
+ echo " · no package.json — skipping"
8
+ exit 0
9
+ fi
10
+ if ! command -v npm >/dev/null 2>&1; then
11
+ echo " ✖ npm not found — install Node.js 22+" >&2
12
+ exit 1
13
+ fi
14
+ if [ -f "$EXT_DIR/package-lock.json" ]; then
15
+ echo " · npm ci"
16
+ npm --prefix "$EXT_DIR" ci --no-audit --no-fund
17
+ else
18
+ echo " · npm install"
19
+ npm --prefix "$EXT_DIR" install --no-audit --no-fund
20
+ fi
21
+ echo " ✓ done"