@desplega.ai/agent-swarm 1.161.0 → 1.162.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 (224) hide show
  1. package/README.md +3 -2
  2. package/dist/{acp-adapter-xx489vvb.js → acp-adapter-74m73ae9.js} +1 -1
  3. package/dist/{actions-ykjkn0m9.js → actions-4sr14gnt.js} +34 -31
  4. package/dist/{anthropic-messages-5qx80j9k.js → anthropic-messages-8xxrzky9.js} +22 -26
  5. package/dist/{app-0hdqa4k1.js → app-pt68fbwp.js} +13 -11
  6. package/dist/{artifact-3v5t9jtg.js → artifact-fey7dvj9.js} +3 -2
  7. package/dist/{assistant-am2g5g8a.js → assistant-cv3jytks.js} +37 -34
  8. package/dist/{azure-openai-responses-fszbkp0e.js → azure-openai-responses-f5cqsyj8.js} +15 -10
  9. package/dist/{boot-reembed-xy9t7avg.js → boot-reembed-4ht4gqth.js} +13 -11
  10. package/dist/{boot-reembed-gt5gjkt4.js → boot-reembed-nxpcvpj9.js} +12 -10
  11. package/dist/{boot-scrub-logs-9x0985y5.js → boot-scrub-logs-k93kyw8k.js} +9 -7
  12. package/dist/{boot-seeds-trv0d4vg.js → boot-seeds-1skcrs0e.js} +13 -10
  13. package/dist/{claude-adapter-jb6e1e54.js → claude-adapter-r5g0tzge.js} +23 -20
  14. package/dist/{claude-managed-setup-d1q9hv2b.js → claude-managed-setup-pkyrgshb.js} +3 -2
  15. package/dist/{claude-sdk-session-zga700s2.js → claude-sdk-session-jxyxnrwd.js} +5565 -5512
  16. package/dist/{cli-we0q7t0e.js → cli-2zy95vhm.js} +137 -64
  17. package/dist/{cli-35pj2yva.js → cli-4cwxn7gp.js} +38 -11
  18. package/dist/{cli-ad4qxm6j.js → cli-4dcpaefp.js} +2 -2
  19. package/dist/{cli-82c1pacn.js → cli-4x0csdjq.js} +71 -37
  20. package/dist/{cli-sqm3r5ps.js → cli-5bcd7sfy.js} +14 -18
  21. package/dist/{cli-d56tgd45.js → cli-5k6k8ta3.js} +2 -2
  22. package/dist/{cli-1er0rhz8.js → cli-5xhpb3kv.js} +15 -15
  23. package/dist/{cli-yrg7c73k.js → cli-7af8yhav.js} +10 -183
  24. package/dist/{cli-r6fsxc76.js → cli-7tre70zp.js} +513 -961
  25. package/dist/{cli-bh7jed3k.js → cli-8ev9xqnx.js} +34 -18
  26. package/dist/cli-bsky8g7w.js +449 -0
  27. package/dist/{cli-hn04t9db.js → cli-cebmgwsc.js} +14 -10
  28. package/dist/{cli-cfkrztza.js → cli-cvatsam7.js} +2 -2
  29. package/dist/{cli-2658f6at.js → cli-cvk6yzw5.js} +6 -8
  30. package/dist/{cli-ptr8h7kp.js → cli-eg0b3p0k.js} +5 -218
  31. package/dist/{cli-zb6xbk61.js → cli-g739zqzt.js} +4 -4
  32. package/dist/{cli-dv6cdjs2.js → cli-gd4favx9.js} +28 -7
  33. package/dist/{cli-5p3x4zna.js → cli-gpqpmns7.js} +2 -2
  34. package/dist/{cli-5nbmpy8w.js → cli-hb5c2x5y.js} +1 -1
  35. package/dist/{cli-jpf7e1zq.js → cli-hmsw1gpy.js} +3 -3
  36. package/dist/{cli-1cz0c18q.js → cli-jf7wmv1r.js} +2521 -733
  37. package/dist/{cli-qwsnmjdd.js → cli-jxs2ygaw.js} +168 -61
  38. package/dist/cli-kdkwd3yr.js +615 -0
  39. package/dist/{cli-hgmnf38m.js → cli-kh04eqwe.js} +1 -1
  40. package/dist/{cli-0383bp7f.js → cli-kp42yek0.js} +425 -90
  41. package/dist/{cli-ybgv4kw2.js → cli-mbssg1xv.js} +9 -2
  42. package/dist/{cli-jsp14b6c.js → cli-mzfth0bp.js} +38 -1
  43. package/dist/{cli-8g6mc14k.js → cli-nq7yqw7b.js} +16 -5
  44. package/dist/{cli-ee8bc46j.js → cli-nt8hecg9.js} +33 -32
  45. package/dist/{cli-9s68w752.js → cli-p0r8sxj5.js} +1 -1
  46. package/dist/{cli-58e8yr0d.js → cli-pkd6s2wy.js} +4 -2
  47. package/dist/{cli-17xpf7cm.js → cli-q24re23n.js} +6 -4
  48. package/dist/cli-qjjvzwzd.js +222 -0
  49. package/dist/cli-qrgt5bqf.js +189 -0
  50. package/dist/{cli-et8m9xsv.js → cli-rfjw9jw2.js} +22 -10
  51. package/dist/{cli-798vkbks.js → cli-rj0gqwwp.js} +2 -2
  52. package/dist/{cli-121ph74b.js → cli-rnyzn44p.js} +1 -1
  53. package/dist/{cli-vnnz5ncg.js → cli-s3hwpt9v.js} +95 -16
  54. package/dist/{cli-7119ja3w.js → cli-sptrj5f5.js} +2 -2
  55. package/dist/{cli-a8c82p2t.js → cli-sqvfa090.js} +13 -6
  56. package/dist/{cli-phfg8vy8.js → cli-swfmp1fx.js} +26 -26
  57. package/dist/{cli-nsdxtcbg.js → cli-tcen9p5w.js} +8 -5
  58. package/dist/{cli-9m03pzga.js → cli-vc9bp061.js} +5 -5
  59. package/dist/{cli-rtx9dygp.js → cli-vxe6qa4h.js} +1 -1
  60. package/dist/{cli-ecfxwnyb.js → cli-vy3ed88x.js} +1 -1
  61. package/dist/{cli-0c7ata9h.js → cli-vyqs9ya8.js} +6 -6
  62. package/dist/cli-wbvnn6tk.js +861 -0
  63. package/dist/{cli-kgd3p0bm.js → cli-wjgs5wxe.js} +6 -6
  64. package/dist/cli-wxkkd0e0.js +33 -0
  65. package/dist/{cli-akfj32vj.js → cli-xqpk3rp7.js} +5 -4
  66. package/dist/cli-zp38xvtm.js +9487 -0
  67. package/dist/{cli-3zc55ctx.js → cli-zvhd3f64.js} +2 -2
  68. package/dist/{cli-ze1d3wzv.js → cli-zxqx25nz.js} +5 -5
  69. package/dist/cli.js +32 -25
  70. package/dist/{cloudflare-workers-ai-system-one-k6fbxw9d.js → cloudflare-workers-ai-system-one-k8ddqjkq.js} +8 -6
  71. package/dist/{codex-adapter-04v97vep.js → codex-adapter-esvmnhn7.js} +13 -13
  72. package/dist/{codex-hook-20me6byw.js → codex-hook-m73jmqgx.js} +19 -3
  73. package/dist/{codex-session-runner-ax69mqq3.js → codex-session-runner-ban9excr.js} +13 -13
  74. package/dist/{commands-18gy08n1.js → commands-75413p2n.js} +9 -7
  75. package/dist/{db-d2pvjpyt.js → db-7f5pecwg.js} +11 -7
  76. package/dist/{dispatcher-8wbwyzjg.js → dispatcher-fh9at8nz.js} +33 -30
  77. package/dist/{dsh-adapter-ysqk9snv.js → dsh-adapter-wpze65d4.js} +3 -3
  78. package/dist/{e2b-esmt1r16.js → e2b-gjgdjp91.js} +10 -9
  79. package/dist/{pi-logo-animation-e9a0t68z.js → easter-egg-3d-3w5c2n4c.js} +122 -68
  80. package/dist/{execute-cmagrbrz.js → execute-f50wg9nh.js} +29 -6
  81. package/dist/{google-generative-ai-k6n5nbpp.js → google-generative-ai-jxxpnegy.js} +2 -2
  82. package/dist/{google-vertex-44xxtcvp.js → google-vertex-x7q1angm.js} +5 -5
  83. package/dist/{handlers-6b69m5kp.js → handlers-w13787bb.js} +36 -33
  84. package/dist/{hook-srnkt0hb.js → hook-46g1jrvx.js} +28 -15
  85. package/dist/{hook-k3mydf2n.js → hook-4tpts2ry.js} +20 -17
  86. package/dist/{http-hrf80ca1.js → http-19pzbfrt.js} +964 -176
  87. package/dist/{index-9rxdvj6w.js → index-8fd4dm4h.js} +34 -31
  88. package/dist/{index-1asbaj62.js → index-dqmp15bq.js} +35 -32
  89. package/dist/{index-45evq4ee.js → index-qb4q1y3e.js} +33 -30
  90. package/dist/{index-k4nj18qs.js → index-s75wc4wd.js} +12 -10
  91. package/dist/{index-xmevk2b9.js → index-scptvdxg.js} +27 -25
  92. package/dist/{keepalive-sfdz6ksp.js → keepalive-xa5ts9cd.js} +11 -9
  93. package/dist/{lead-ej91e9hw.js → lead-qp4xkvjq.js} +45 -41
  94. package/dist/{maintenance-80dnd7ke.js → maintenance-rm5885hm.js} +13 -11
  95. package/dist/{mistral-conversations-pc3ntnxt.js → mistral-conversations-rw7fbt22.js} +4 -4
  96. package/dist/{node-a5e00qhp.js → node-8zkdq42h.js} +834 -833
  97. package/dist/{oauth-refresh-sweep-m1etk2mx.js → oauth-refresh-sweep-1csdfebf.js} +10 -8
  98. package/dist/{onboard-0q8sdfqc.js → onboard-r6b78cs4.js} +10 -10
  99. package/dist/{openai-codex-responses-n7n683p2.js → openai-codex-responses-efvrgrq3.js} +4 -4
  100. package/dist/{openai-completions-jpaj5g2b.js → openai-completions-bbbrrz4z.js} +12 -8
  101. package/dist/{openai-responses-9a3nme9j.js → openai-responses-9jjyrcm1.js} +15 -10
  102. package/dist/{opencode-adapter-4wcgmvgf.js → opencode-adapter-kb3g6pkf.js} +2 -2
  103. package/dist/{otel-impl-hnqm9mxq.js → otel-impl-0y9knpky.js} +5 -5
  104. package/dist/{pi-mono-adapter-d6sqm9wr.js → pi-mono-adapter-z6s1bme2.js} +100 -19
  105. package/dist/{pricing-refresh-y60z64pm.js → pricing-refresh-mth26tgp.js} +11 -9
  106. package/dist/{rbac-roles-8pa0754b.js → rbac-roles-kwntb23q.js} +13 -9
  107. package/dist/rbac-roles-vpk4ebm8.js +45 -0
  108. package/dist/{registry-v5wytg0s.js → registry-km6t1jd2.js} +1 -1
  109. package/dist/{render-v2-418s1vj7.js → render-v2-hcm7h00y.js} +13 -11
  110. package/dist/{runtime-3pknc168.js → runtime-vfjsfsc5.js} +4 -4
  111. package/dist/{setup-yghdkj4x.js → setup-hbyzd65h.js} +2 -2
  112. package/dist/{virtual-modules-jcceevt5.js → virtual-modules-9bv7ry91.js} +9 -8
  113. package/dist/{work-objects-j1sz20v9.js → work-objects-m09sxnhe.js} +36 -33
  114. package/dist/{worker-d4gcvkjt.js → worker-0h35rvk4.js} +45 -41
  115. package/openapi.json +491 -12
  116. package/package.json +13 -6
  117. package/src/be/api-drain.ts +184 -0
  118. package/src/be/db/tasks/read.ts +31 -6
  119. package/src/be/db/tasks/write.ts +5 -4
  120. package/src/be/db.ts +42 -18
  121. package/src/be/memory/link-resolver.ts +29 -3
  122. package/src/be/migrations/192_favorites_agent_fs_path.sql +36 -0
  123. package/src/be/onboarding.ts +7 -1
  124. package/src/be/seed-prompt-templates.ts +1 -0
  125. package/src/be/swarm-config-guard.ts +35 -16
  126. package/src/be/task-citations.ts +11 -5
  127. package/src/be/users.ts +3 -0
  128. package/src/cli.tsx +3 -2
  129. package/src/comb/agent-fs.ts +39 -0
  130. package/src/comb/config.ts +37 -0
  131. package/src/comb/markers.ts +37 -0
  132. package/src/comb/review-batch.ts +486 -0
  133. package/src/comb/templates.ts +88 -0
  134. package/src/commands/context-preamble.ts +4 -1
  135. package/src/commands/hook.ts +2 -1
  136. package/src/commands/runner.ts +262 -68
  137. package/src/commands/templates.ts +10 -0
  138. package/src/extensions/contract-types.generated.ts +1 -1
  139. package/src/fs/agent-fs-provider.ts +106 -2
  140. package/src/heartbeat/heartbeat.ts +4 -0
  141. package/src/hooks/codex-hook.ts +25 -1
  142. package/src/hooks/hook.ts +13 -0
  143. package/src/hooks/pr-body-guard.ts +983 -0
  144. package/src/http/all-routes.ts +1 -0
  145. package/src/http/assets.ts +5 -17
  146. package/src/http/comb.ts +131 -0
  147. package/src/http/core.ts +2 -1
  148. package/src/http/fs.ts +9 -17
  149. package/src/http/index.ts +23 -9
  150. package/src/http/onboarding.ts +21 -2
  151. package/src/http/poll.ts +30 -3
  152. package/src/http/realtime.ts +62 -0
  153. package/src/http/request-principal.ts +22 -0
  154. package/src/http/status.ts +34 -2
  155. package/src/kv-reserved-namespaces.ts +10 -5
  156. package/src/providers/dsh-adapter.ts +1 -1
  157. package/src/providers/pi-mono-adapter.ts +123 -0
  158. package/src/rbac/legacy-policy.ts +1 -0
  159. package/src/rbac/permissions.ts +4 -0
  160. package/src/realtime/auth.ts +63 -1
  161. package/src/realtime/tickets.ts +52 -0
  162. package/src/realtime/transport.ts +51 -22
  163. package/src/scripts-runtime/types/swarm-extension.d.ts +3 -1
  164. package/src/telemetry-context.ts +175 -0
  165. package/src/telemetry-contract/EVENTS.md +81 -0
  166. package/src/telemetry-contract/SOURCE.json +9 -0
  167. package/src/telemetry-contract/catalog.json +1335 -0
  168. package/src/telemetry-contract/index.ts +60 -0
  169. package/src/telemetry-contract/types.gen.ts +1971 -0
  170. package/src/telemetry-identity.ts +129 -0
  171. package/src/telemetry-snapshot.ts +211 -0
  172. package/src/telemetry-trigger.ts +125 -0
  173. package/src/telemetry-types.typetest.ts +40 -0
  174. package/src/telemetry.ts +271 -67
  175. package/src/tests/api-drain-e2e.test.ts +249 -0
  176. package/src/tests/api-drain-worker-e2e.test.ts +216 -0
  177. package/src/tests/api-drain.test.ts +351 -0
  178. package/src/tests/comb-config-guard.test.ts +38 -0
  179. package/src/tests/comb-links.test.ts +162 -0
  180. package/src/tests/comb-markers.test.ts +68 -0
  181. package/src/tests/comb-review-batch.test.ts +770 -0
  182. package/src/tests/comb-status.test.ts +152 -0
  183. package/src/tests/db-task-read-contract.test.ts +2 -0
  184. package/src/tests/db-task-write-contract.test.ts +1 -0
  185. package/src/tests/docs-index-footprint.test.js +3 -3
  186. package/src/tests/dsh-adapter.test.ts +1 -1
  187. package/src/tests/favorites-agent-fs-path.test.ts +226 -0
  188. package/src/tests/memory-link-resolver.test.ts +34 -0
  189. package/src/tests/onboarding.test.ts +108 -0
  190. package/src/tests/pi-mono-adapter.test.ts +265 -2
  191. package/src/tests/pr-body-leaks.test.ts +789 -0
  192. package/src/tests/preload.ts +8 -0
  193. package/src/tests/rbac-engine.test.ts +19 -0
  194. package/src/tests/realtime-room-auth.test.ts +104 -1
  195. package/src/tests/realtime-tickets.test.ts +74 -0
  196. package/src/tests/realtime-transport.test.ts +131 -4
  197. package/src/tests/runner-api-drain.test.ts +301 -0
  198. package/src/tests/runner-fallback-output.test.ts +61 -0
  199. package/src/tests/runner-fenced-json-output.test.ts +178 -0
  200. package/src/tests/script-connections.test.ts +2 -0
  201. package/src/tests/send-task-requested-by.test.ts +133 -15
  202. package/src/tests/task-lifecycle-telemetry.test.ts +8 -3
  203. package/src/tests/telemetry-context.test.ts +314 -0
  204. package/src/tests/telemetry-init.test.ts +51 -19
  205. package/src/tests/telemetry-snapshot.test.ts +229 -0
  206. package/src/tests/telemetry-trigger.test.ts +200 -0
  207. package/src/tests/template-registry-helpers.ts +1 -0
  208. package/src/tests/workflow-agent-task-retry.test.ts +363 -0
  209. package/src/tests/workflow-definition-telemetry.test.ts +4 -4
  210. package/src/tools/poll-task.ts +20 -1
  211. package/src/tools/send-task.ts +9 -1
  212. package/src/tools/task-action.ts +11 -0
  213. package/src/types.ts +2 -1
  214. package/src/utils/api-drain.ts +24 -0
  215. package/src/utils/constants.ts +57 -16
  216. package/src/utils/pr-body-leaks.ts +172 -0
  217. package/src/utils/task-attachment-links.ts +14 -8
  218. package/src/workflows/recovery.ts +26 -1
  219. package/src/workflows/resume.ts +31 -4
  220. package/src/workflows/task-step-routing.ts +75 -2
  221. package/tsconfig.json +3 -0
  222. package/dist/cli-tjf4cn8z.js +0 -9119
  223. package/dist/cli-tsk3nz8a.js +0 -582
  224. package/dist/{cli-t6v2ah3r.js → cli-twrh04ap.js} +3 -3
@@ -1,3 +1,17 @@
1
+ import {
2
+ CODEMODE_TOOL_NAME,
3
+ TOOL_SEARCH_TOOL_NAME,
4
+ addUsageToTotals,
5
+ combineUsage,
6
+ createCodemodeToolDefinition,
7
+ createToolDefinitionFromAgentTool,
8
+ createToolSearchToolDefinition,
9
+ createUsageTotals,
10
+ getUsageCostBreakdown,
11
+ isCodemodeTool,
12
+ isToolSearchTool,
13
+ wrapToolDefinition
14
+ } from "./cli-hmsw1gpy.js";
1
15
  import {
2
16
  ProjectTrustStore,
3
17
  addMcpServerConfig,
@@ -6,7 +20,7 @@ import {
6
20
  loadMcpConfig,
7
21
  openBrowser,
8
22
  updateMcpServerConfig
9
- } from "./cli-35pj2yva.js";
23
+ } from "./cli-4cwxn7gp.js";
10
24
  import {
11
25
  AuthStorage,
12
26
  DEFAULT_MAX_BYTES,
@@ -21,6 +35,7 @@ import {
21
35
  createMcpResourceToolDefinitions,
22
36
  createMcpToolDefinition,
23
37
  createMcpToolName,
38
+ createMcpToolRenderers,
24
39
  formatSize,
25
40
  getConfigValueEnvVarNames,
26
41
  getMcpToolExposure,
@@ -37,21 +52,7 @@ import {
37
52
  truncateLine,
38
53
  truncateTail,
39
54
  validateMcpServerConfig
40
- } from "./cli-bh7jed3k.js";
41
- import {
42
- CODEMODE_TOOL_NAME,
43
- TOOL_SEARCH_TOOL_NAME,
44
- addUsageToTotals,
45
- combineUsage,
46
- createCodemodeToolDefinition,
47
- createToolDefinitionFromAgentTool,
48
- createToolSearchToolDefinition,
49
- createUsageTotals,
50
- getUsageCostBreakdown,
51
- isCodemodeTool,
52
- isToolSearchTool,
53
- wrapToolDefinition
54
- } from "./cli-jpf7e1zq.js";
55
+ } from "./cli-8ev9xqnx.js";
55
56
  import {
56
57
  VisualLinePreview,
57
58
  formatToolCallWithArgs,
@@ -72,7 +73,10 @@ import {
72
73
  trackDetachedChildPid,
73
74
  truncateToVisualLines,
74
75
  untrackDetachedChildPid
75
- } from "./cli-9s68w752.js";
76
+ } from "./cli-p0r8sxj5.js";
77
+ import {
78
+ ArminComponent
79
+ } from "./cli-bsky8g7w.js";
76
80
  import {
77
81
  APP_NAME,
78
82
  APP_TITLE,
@@ -178,6 +182,7 @@ import {
178
182
  resolveThemeSetting,
179
183
  rgbColor,
180
184
  setCapabilityOverrides,
185
+ setImageTranscoder,
181
186
  setKeybindings,
182
187
  setRegisteredThemes,
183
188
  setTerminalColorScheme,
@@ -198,7 +203,7 @@ import {
198
203
  waitForChildProcess,
199
204
  watchWithErrorHandler,
200
205
  wrapTextWithAnsi
201
- } from "./cli-vnnz5ncg.js";
206
+ } from "./cli-s3hwpt9v.js";
202
207
  import {
203
208
  require_dist
204
209
  } from "./cli-7nxes1hs.js";
@@ -221,7 +226,7 @@ import {
221
226
  stream,
222
227
  streamSimple,
223
228
  validateToolArguments
224
- } from "./cli-ee8bc46j.js";
229
+ } from "./cli-nt8hecg9.js";
225
230
  import {
226
231
  exports_typebox
227
232
  } from "./cli-rb9m6rpe.js";
@@ -232,12 +237,6 @@ import {
232
237
  import {
233
238
  require_semver
234
239
  } from "./cli-3er6gcsn.js";
235
- import {
236
- getProviderEnvValue
237
- } from "./cli-btbzvq95.js";
238
- import {
239
- parseStreamingJson
240
- } from "./cli-1m2e086m.js";
241
240
  import {
242
241
  ModelsError,
243
242
  assertChatModel,
@@ -263,6 +262,12 @@ import {
263
262
  normalizeContext,
264
263
  toToolDeclaration
265
264
  } from "./cli-ykk5jaax.js";
265
+ import {
266
+ getProviderEnvValue
267
+ } from "./cli-btbzvq95.js";
268
+ import {
269
+ parseStreamingJson
270
+ } from "./cli-1m2e086m.js";
266
271
  import {
267
272
  EventStream
268
273
  } from "./cli-bzr0ftht.js";
@@ -30569,6 +30574,16 @@ var ThinkingLevelMapSchema = exports_typebox.Object({
30569
30574
  xhigh: exports_typebox.Optional(ThinkingLevelMapValueSchema),
30570
30575
  max: exports_typebox.Optional(ThinkingLevelMapValueSchema)
30571
30576
  });
30577
+ var SamplingParamsSchema = exports_typebox.Record(exports_typebox.String(), exports_typebox.Unknown());
30578
+ var SamplingParamsByThinkingLevelSchema = exports_typebox.Object({
30579
+ off: exports_typebox.Optional(SamplingParamsSchema),
30580
+ minimal: exports_typebox.Optional(SamplingParamsSchema),
30581
+ low: exports_typebox.Optional(SamplingParamsSchema),
30582
+ medium: exports_typebox.Optional(SamplingParamsSchema),
30583
+ high: exports_typebox.Optional(SamplingParamsSchema),
30584
+ xhigh: exports_typebox.Optional(SamplingParamsSchema),
30585
+ max: exports_typebox.Optional(SamplingParamsSchema)
30586
+ });
30572
30587
  var ChatTemplateKwargScalarSchema = exports_typebox.Union([exports_typebox.String(), exports_typebox.Number(), exports_typebox.Boolean(), exports_typebox.Null()]);
30573
30588
  var ChatTemplateKwargVariableSchema = exports_typebox.Object({
30574
30589
  $var: exports_typebox.Union([exports_typebox.Literal("thinking.enabled"), exports_typebox.Literal("thinking.effort")]),
@@ -30685,7 +30700,8 @@ var ModelDefinitionSchema = exports_typebox.Object({
30685
30700
  promptCache: exports_typebox.Optional(ModelPromptCacheSchema),
30686
30701
  contextWindow: exports_typebox.Optional(exports_typebox.Number()),
30687
30702
  maxTokens: exports_typebox.Optional(exports_typebox.Number()),
30688
- samplingParams: exports_typebox.Optional(exports_typebox.Record(exports_typebox.String(), exports_typebox.Unknown())),
30703
+ samplingParams: exports_typebox.Optional(SamplingParamsSchema),
30704
+ samplingParamsByThinkingLevel: exports_typebox.Optional(SamplingParamsByThinkingLevelSchema),
30689
30705
  headers: exports_typebox.Optional(exports_typebox.Record(exports_typebox.String(), exports_typebox.String())),
30690
30706
  compat: exports_typebox.Optional(ProviderCompatSchema)
30691
30707
  });
@@ -30705,7 +30721,8 @@ var ModelOverrideSchema = exports_typebox.Object({
30705
30721
  promptCache: exports_typebox.Optional(ModelPromptCacheSchema),
30706
30722
  contextWindow: exports_typebox.Optional(exports_typebox.Number()),
30707
30723
  maxTokens: exports_typebox.Optional(exports_typebox.Number()),
30708
- samplingParams: exports_typebox.Optional(exports_typebox.Record(exports_typebox.String(), exports_typebox.Unknown())),
30724
+ samplingParams: exports_typebox.Optional(SamplingParamsSchema),
30725
+ samplingParamsByThinkingLevel: exports_typebox.Optional(SamplingParamsByThinkingLevelSchema),
30709
30726
  headers: exports_typebox.Optional(exports_typebox.Record(exports_typebox.String(), exports_typebox.String())),
30710
30727
  compat: exports_typebox.Optional(ProviderCompatSchema)
30711
30728
  });
@@ -30942,6 +30959,17 @@ function mergeInputLimits(base, override) {
30942
30959
  } : base?.images
30943
30960
  };
30944
30961
  }
30962
+ function mergeSamplingParamsByThinkingLevel(base, override) {
30963
+ if (!override)
30964
+ return base;
30965
+ const merged = { ...base };
30966
+ for (const level of ["off", "minimal", "low", "medium", "high", "xhigh", "max"]) {
30967
+ const params = override[level];
30968
+ if (params)
30969
+ merged[level] = { ...base?.[level], ...params };
30970
+ }
30971
+ return merged;
30972
+ }
30945
30973
  function applyModelOverride(model, override) {
30946
30974
  return {
30947
30975
  ...model,
@@ -30961,6 +30989,7 @@ function applyModelOverride(model, override) {
30961
30989
  contextWindow: override.contextWindow ?? model.contextWindow,
30962
30990
  maxTokens: override.maxTokens ?? model.maxTokens,
30963
30991
  samplingParams: override.samplingParams ? { ...model.samplingParams, ...override.samplingParams } : model.samplingParams,
30992
+ samplingParamsByThinkingLevel: mergeSamplingParamsByThinkingLevel(model.samplingParamsByThinkingLevel, override.samplingParamsByThinkingLevel),
30964
30993
  compat: mergeCompat(model.compat, override.compat)
30965
30994
  };
30966
30995
  }
@@ -30993,6 +31022,7 @@ function modelFromJson(providerId, definition, providerConfig, defaults) {
30993
31022
  contextWindow: definition.contextWindow ?? 128000,
30994
31023
  maxTokens: definition.maxTokens ?? 16384,
30995
31024
  samplingParams: definition.samplingParams,
31025
+ samplingParamsByThinkingLevel: definition.samplingParamsByThinkingLevel,
30996
31026
  headers: undefined,
30997
31027
  compat: mergeCompat(providerConfig.compat, definition.compat)
30998
31028
  };
@@ -32483,7 +32513,7 @@ function getCreateJiti() {
32483
32513
  }
32484
32514
  var virtualModulesPromise;
32485
32515
  function getVirtualModules() {
32486
- virtualModulesPromise ??= import("./virtual-modules-jcceevt5.js").then((module) => module.VIRTUAL_MODULES);
32516
+ virtualModulesPromise ??= import("./virtual-modules-9bv7ry91.js").then((module) => module.VIRTUAL_MODULES);
32487
32517
  return virtualModulesPromise;
32488
32518
  }
32489
32519
  var _aliases = null;
@@ -32720,6 +32750,11 @@ function createExtensionAPI(extension, runtime, cwd, eventBus) {
32720
32750
  extension.entryRenderers ??= new Map;
32721
32751
  extension.entryRenderers.set(customType, renderer);
32722
32752
  },
32753
+ registerToolRenderer(resolver) {
32754
+ assertActive();
32755
+ extension.toolRenderers ??= [];
32756
+ extension.toolRenderers.push(resolver);
32757
+ },
32723
32758
  getFlag(name) {
32724
32759
  assertActive();
32725
32760
  if (!extension.flags.has(name))
@@ -39160,11 +39195,7 @@ async function loadPhoton() {
39160
39195
  }
39161
39196
 
39162
39197
  // node_modules/@earendil-works/pi-coding-agent/dist/utils/image-convert.js
39163
- async function convertImageBytesToPng(bytes) {
39164
- const photon = await loadPhoton();
39165
- if (!photon) {
39166
- return null;
39167
- }
39198
+ function encodePng(photon, bytes) {
39168
39199
  try {
39169
39200
  const rawImage = photon.PhotonImage.new_from_byteslice(bytes);
39170
39201
  const image = applyExifOrientation(photon, rawImage, bytes);
@@ -39179,6 +39210,13 @@ async function convertImageBytesToPng(bytes) {
39179
39210
  return null;
39180
39211
  }
39181
39212
  }
39213
+ async function convertImageBytesToPng(bytes) {
39214
+ const photon = await loadPhoton();
39215
+ if (!photon) {
39216
+ return null;
39217
+ }
39218
+ return encodePng(photon, bytes);
39219
+ }
39182
39220
  async function convertToPng(base64Data, mimeType) {
39183
39221
  if (mimeType === "image/png") {
39184
39222
  return { data: base64Data, mimeType };
@@ -39193,6 +39231,32 @@ async function convertToPng(base64Data, mimeType) {
39193
39231
  mimeType: "image/png"
39194
39232
  };
39195
39233
  }
39234
+ async function loadPngTranscoder() {
39235
+ const photon = await loadPhoton();
39236
+ if (!photon)
39237
+ return;
39238
+ return (base64Data) => {
39239
+ const pngBytes = encodePng(photon, new Uint8Array(Buffer.from(base64Data, "base64")));
39240
+ return pngBytes ? Buffer.from(pngBytes).toString("base64") : null;
39241
+ };
39242
+ }
39243
+ var pngTranscoderLoad;
39244
+ var pngTranscoderRegistered = false;
39245
+ function ensurePngTranscoder(onRegistered) {
39246
+ if (pngTranscoderRegistered || getCapabilities().images !== "kitty")
39247
+ return;
39248
+ pngTranscoderLoad ??= loadPngTranscoder().then((transcoder) => {
39249
+ if (!transcoder)
39250
+ return false;
39251
+ setImageTranscoder(transcoder);
39252
+ pngTranscoderRegistered = true;
39253
+ return true;
39254
+ });
39255
+ pngTranscoderLoad.then((registered) => {
39256
+ if (registered)
39257
+ onRegistered();
39258
+ });
39259
+ }
39196
39260
 
39197
39261
  // node_modules/@earendil-works/pi-coding-agent/dist/utils/image-resize.js
39198
39262
  import { Worker } from "node:worker_threads";
@@ -41256,7 +41320,7 @@ function trimRenderedResultLines(lines) {
41256
41320
  return lines.slice(start, end);
41257
41321
  }
41258
41322
  function createToolHtmlRenderer(deps) {
41259
- const { getToolDefinition, theme: theme2, cwd, width = 100 } = deps;
41323
+ const { getToolRenderers, theme: theme2, cwd, width = 100 } = deps;
41260
41324
  const renderedCallComponents = new Map;
41261
41325
  const renderedResultComponents = new Map;
41262
41326
  const renderedStates = new Map;
@@ -41289,7 +41353,7 @@ function createToolHtmlRenderer(deps) {
41289
41353
  renderCall(toolCallId, toolName, args) {
41290
41354
  try {
41291
41355
  renderedArgs.set(toolCallId, args);
41292
- const toolDef = getToolDefinition(toolName);
41356
+ const toolDef = getToolRenderers(toolName);
41293
41357
  if (!toolDef?.renderCall) {
41294
41358
  return;
41295
41359
  }
@@ -41303,7 +41367,7 @@ function createToolHtmlRenderer(deps) {
41303
41367
  },
41304
41368
  renderResult(toolCallId, toolName, result, details, isError) {
41305
41369
  try {
41306
- const toolDef = getToolDefinition(toolName);
41370
+ const toolDef = getToolRenderers(toolName);
41307
41371
  if (!toolDef?.renderResult) {
41308
41372
  return;
41309
41373
  }
@@ -41973,6 +42037,11 @@ class ExtensionRunner {
41973
42037
  getMarkdownTransformers() {
41974
42038
  return this.extensions.flatMap((ext2) => ext2.markdownTransformer ? [ext2.markdownTransformer] : []);
41975
42039
  }
42040
+ resolveToolRenderers(toolName, base) {
42041
+ const resolvers = this.extensions.flatMap((ext2) => ext2.toolRenderers ?? []);
42042
+ const resolve8 = (index) => index < resolvers.length ? resolvers[index](toolName, () => resolve8(index + 1)) : base();
42043
+ return resolve8(0);
42044
+ }
41976
42045
  getEntryRenderer(customType) {
41977
42046
  for (const ext2 of this.extensions) {
41978
42047
  const renderer = ext2.entryRenderers?.get(customType);
@@ -49657,7 +49726,7 @@ ${command}` : command;
49657
49726
  async exportToHtml(outputPath, options = {}) {
49658
49727
  const themeName = [options.themeName, this.settingsManager.getTheme()].find((candidate) => candidate !== undefined && getThemeByName(candidate) !== undefined);
49659
49728
  const toolRenderer = createToolHtmlRenderer({
49660
- getToolDefinition: (name) => this.getToolDefinition(name),
49729
+ getToolRenderers: (name) => this._extensionRunner.resolveToolRenderers(name, () => this.getToolDefinition(name)),
49661
49730
  theme,
49662
49731
  cwd: this.sessionManager.getCwd()
49663
49732
  });
@@ -50095,7 +50164,7 @@ function parseArgs(args) {
50095
50164
  } else if (arg === "--session-dir" && i + 1 < args.length) {
50096
50165
  result.sessionDir = args[++i];
50097
50166
  } else if (arg === "--models" && i + 1 < args.length) {
50098
- result.models = args[++i].split(",").map((s) => s.trim());
50167
+ result.models = args[++i].split(",").map((s) => s.trim()).filter((pattern) => pattern.length > 0);
50099
50168
  } else if (arg === "--no-tools" || arg === "-nt") {
50100
50169
  result.noTools = true;
50101
50170
  } else if (arg === "--no-builtin-tools" || arg === "-nbt") {
@@ -50413,7 +50482,7 @@ var defaultModelPerProvider = {
50413
50482
  "azure-openai-responses": "gpt-5.4",
50414
50483
  "openai-codex": "gpt-6.1-sol",
50415
50484
  radius: "balanced",
50416
- nvidia: "nvidia/nemotron-3-super-120b-a12b",
50485
+ nvidia: "nvidia/nemotron-3-ultra-550b-a55b",
50417
50486
  deepseek: "deepseek-v4-pro",
50418
50487
  google: "gemini-3.1-pro-preview",
50419
50488
  "google-vertex": "gemini-3.1-pro-preview",
@@ -51581,10 +51650,229 @@ function createCodemodeExtension(options = {}) {
51581
51650
  var codemode_default = createCodemodeExtension();
51582
51651
 
51583
51652
  // node_modules/@earendil-works/pi-coding-agent/dist/extensions/mcp/index.js
51584
- import { join as join20, resolve as resolve10 } from "node:path";
51653
+ import { join as join21, resolve as resolve10 } from "node:path";
51585
51654
 
51586
51655
  // node_modules/@earendil-works/pi-coding-agent/dist/extensions/mcp/runtime.lazy.js
51587
- var loadMcpRuntime = () => import("./runtime-3pknc168.js");
51656
+ var loadMcpRuntime = () => import("./runtime-vfjsfsc5.js");
51657
+
51658
+ // node_modules/@earendil-works/pi-coding-agent/dist/utils/clipboard.js
51659
+ import { randomUUID as randomUUID3 } from "node:crypto";
51660
+ import { unlinkSync, writeFileSync as writeFileSync6 } from "node:fs";
51661
+ import { platform as platform2, tmpdir as tmpdir3 } from "node:os";
51662
+ import { join as join20 } from "node:path";
51663
+
51664
+ // node_modules/@earendil-works/pi-coding-agent/dist/utils/clipboard-command.js
51665
+ import { spawn as spawn5 } from "node:child_process";
51666
+ function runClipboardCommand(command, args, options) {
51667
+ return new Promise((resolve10) => {
51668
+ const child = spawn5(command, args, {
51669
+ stdio: ["pipe", options?.input === undefined ? "pipe" : "ignore", "ignore"],
51670
+ windowsHide: true
51671
+ });
51672
+ const chunks = [];
51673
+ let length = 0;
51674
+ let settled = false;
51675
+ const finish = (result) => {
51676
+ if (settled)
51677
+ return;
51678
+ settled = true;
51679
+ clearTimeout(timer);
51680
+ resolve10(result);
51681
+ };
51682
+ const abort = () => {
51683
+ child.kill("SIGKILL");
51684
+ child.stdout?.destroy();
51685
+ child.stdin?.destroy();
51686
+ finish(undefined);
51687
+ };
51688
+ const timer = setTimeout(abort, options?.timeoutMs ?? 3000);
51689
+ child.on("error", () => finish(undefined));
51690
+ child.on("close", (code) => {
51691
+ if (!settled)
51692
+ finish(code === 0 ? Buffer.concat(chunks, length) : undefined);
51693
+ });
51694
+ child.stdout?.on("data", (chunk) => {
51695
+ if (settled)
51696
+ return;
51697
+ length += chunk.length;
51698
+ if (length > (options?.maxBufferBytes ?? 50 * 1024 * 1024))
51699
+ abort();
51700
+ else
51701
+ chunks.push(chunk);
51702
+ });
51703
+ child.stdin?.on("error", () => {});
51704
+ child.stdin?.end(options?.input);
51705
+ });
51706
+ }
51707
+
51708
+ // node_modules/@earendil-works/pi-coding-agent/dist/utils/wsl.js
51709
+ import { readFileSync as readFileSync10 } from "node:fs";
51710
+ function isWSL(env = process.env) {
51711
+ if (env.WSL_DISTRO_NAME || env.WSLENV) {
51712
+ return true;
51713
+ }
51714
+ try {
51715
+ const release2 = readFileSync10("/proc/version", "utf-8");
51716
+ return /microsoft|wsl/i.test(release2);
51717
+ } catch {
51718
+ return false;
51719
+ }
51720
+ }
51721
+
51722
+ // node_modules/@earendil-works/pi-coding-agent/dist/utils/clipboard.js
51723
+ var MAX_OSC52_ENCODED_LENGTH = 1e5;
51724
+ function isRemoteSession(env) {
51725
+ return Boolean(env.SSH_CONNECTION || env.SSH_CLIENT || env.MOSH_CONNECTION);
51726
+ }
51727
+ function emitOsc52(text) {
51728
+ const encoded = Buffer.from(text).toString("base64");
51729
+ if (encoded.length > MAX_OSC52_ENCODED_LENGTH) {
51730
+ return false;
51731
+ }
51732
+ process.stdout.write(`\x1B]52;c;${encoded}\x07`);
51733
+ return true;
51734
+ }
51735
+ async function copyViaWindowsClipboard(text) {
51736
+ const tmpFile = join20(tmpdir3(), `pi-wsl-clip-${randomUUID3()}.txt`);
51737
+ try {
51738
+ writeFileSync6(tmpFile, text, { encoding: "utf8", mode: 384 });
51739
+ const winPath = (await runClipboardCommand("wslpath", ["-w", tmpFile], { timeoutMs: 1000 }))?.toString("utf8").trim();
51740
+ if (!winPath)
51741
+ return false;
51742
+ const script = `Set-Clipboard -Value ([System.IO.File]::ReadAllText('${winPath.replaceAll("'", "''")}', [System.Text.Encoding]::UTF8))`;
51743
+ const result = await runClipboardCommand("powershell.exe", ["-NoProfile", "-Command", script], {
51744
+ timeoutMs: 5000
51745
+ });
51746
+ return result !== undefined;
51747
+ } catch {
51748
+ return false;
51749
+ } finally {
51750
+ try {
51751
+ unlinkSync(tmpFile);
51752
+ } catch {}
51753
+ }
51754
+ }
51755
+ async function readClipboardText() {
51756
+ if (platform2() === "linux") {
51757
+ const commands = [];
51758
+ if (process.env.TERMUX_VERSION)
51759
+ commands.push(["termux-clipboard-get", []]);
51760
+ if (process.env.WAYLAND_DISPLAY)
51761
+ commands.push(["wl-paste", ["--no-newline", "--type", "text"]]);
51762
+ if (process.env.DISPLAY) {
51763
+ commands.push(["xclip", ["-selection", "clipboard", "-out"]], ["xsel", ["--clipboard", "--output"]]);
51764
+ }
51765
+ for (const [command, args] of commands) {
51766
+ const bytes = await runClipboardCommand(command, args, { timeoutMs: 5000 });
51767
+ if (bytes !== undefined)
51768
+ return bytes.toString("utf8") || null;
51769
+ }
51770
+ }
51771
+ try {
51772
+ return await getNativeClipboard()?.getText() || null;
51773
+ } catch {
51774
+ return null;
51775
+ }
51776
+ }
51777
+ async function readClipboardFilePaths() {
51778
+ const paths = await getNativeClipboard()?.getFilePaths?.();
51779
+ return paths?.length ? paths : null;
51780
+ }
51781
+ async function copyToClipboard(text) {
51782
+ const p = platform2();
51783
+ const env = process.env;
51784
+ let copied = false;
51785
+ if (p !== "linux") {
51786
+ try {
51787
+ const clipboard = getNativeClipboard();
51788
+ if (clipboard?.setText) {
51789
+ await clipboard.setText(text);
51790
+ copied = true;
51791
+ }
51792
+ } catch {}
51793
+ }
51794
+ if (!copied) {
51795
+ const commands = [];
51796
+ if (p === "darwin")
51797
+ commands.push(["pbcopy", []]);
51798
+ else if (p === "win32")
51799
+ commands.push(["clip", []]);
51800
+ else {
51801
+ if (env.TERMUX_VERSION)
51802
+ commands.push(["termux-clipboard-set", []]);
51803
+ if (env.WAYLAND_DISPLAY)
51804
+ commands.push(["wl-copy", []]);
51805
+ if (env.DISPLAY) {
51806
+ commands.push(["xclip", ["-selection", "clipboard"]], ["xsel", ["--clipboard", "--input"]]);
51807
+ }
51808
+ }
51809
+ for (const [command, args] of commands) {
51810
+ if (await runClipboardCommand(command, args, { input: text, timeoutMs: 5000 }) !== undefined) {
51811
+ copied = true;
51812
+ break;
51813
+ }
51814
+ }
51815
+ }
51816
+ let osc52Emitted = false;
51817
+ if (!copied && p === "linux" && isWSL(env)) {
51818
+ if (env.WT_SESSION)
51819
+ osc52Emitted = emitOsc52(text);
51820
+ copied = osc52Emitted || await copyViaWindowsClipboard(text);
51821
+ }
51822
+ const headless = p === "linux" && !env.DISPLAY && !env.WAYLAND_DISPLAY && !env.TERMUX_VERSION;
51823
+ let oversized = false;
51824
+ if (!osc52Emitted && (isRemoteSession(env) || !copied && headless)) {
51825
+ if (emitOsc52(text))
51826
+ copied = true;
51827
+ else
51828
+ oversized = true;
51829
+ }
51830
+ if (copied)
51831
+ return;
51832
+ if (oversized)
51833
+ throw new Error("Clipboard unavailable: text exceeds the OSC 52 size limit");
51834
+ if (p === "linux") {
51835
+ if (env.TERMUX_VERSION) {
51836
+ throw new Error("Clipboard unavailable: install the Termux:API app and `termux-api` package");
51837
+ }
51838
+ if (env.WAYLAND_DISPLAY) {
51839
+ throw new Error("Clipboard unavailable: install `wl-clipboard` (`wl-copy`) or check Wayland access");
51840
+ }
51841
+ if (env.DISPLAY) {
51842
+ throw new Error("Clipboard unavailable: install `xclip` or `xsel`, or check X11 access");
51843
+ }
51844
+ }
51845
+ throw new Error("Clipboard unavailable");
51846
+ }
51847
+
51848
+ // node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/auth-url.js
51849
+ class AuthUrlComponent extends Container {
51850
+ url;
51851
+ tui;
51852
+ hint;
51853
+ constructor(tui, url) {
51854
+ super();
51855
+ this.tui = tui;
51856
+ this.url = url;
51857
+ this.addChild(new Text(theme.fg("accent", hyperlink(url, url)), 1, 0));
51858
+ this.hint = new Text("", 1, 0);
51859
+ this.addChild(this.hint);
51860
+ this.setHint(keyHint("app.message.copy", "to copy"));
51861
+ }
51862
+ setHint(suffix) {
51863
+ const clickHint = process.platform === "darwin" ? "Cmd+click to open" : "Ctrl+click to open";
51864
+ this.hint.setText(`${theme.fg("dim", hyperlink(clickHint, this.url))} ${theme.fg("dim", "•")} ${suffix}`);
51865
+ this.tui.requestRender();
51866
+ }
51867
+ async copy() {
51868
+ try {
51869
+ await copyToClipboard(this.url);
51870
+ this.setHint(theme.fg("success", "Copied URL to clipboard"));
51871
+ } catch (error) {
51872
+ this.setHint(theme.fg("error", error instanceof Error ? error.message : String(error)));
51873
+ }
51874
+ }
51875
+ }
51588
51876
 
51589
51877
  // node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js
51590
51878
  class DynamicBorder {
@@ -51716,12 +52004,11 @@ class McpManagerView {
51716
52004
  }
51717
52005
  signal.addEventListener("abort", onAbort, { once: true });
51718
52006
  const input = new Input;
51719
- const clickHint = process.platform === "darwin" ? "Cmd+click to open" : "Ctrl+click to open";
52007
+ const link = new AuthUrlComponent(this.tui, authorizationUrl);
51720
52008
  const body = [
51721
52009
  new Spacer(1),
51722
52010
  new Text(this.theme.fg("muted", "Approve access in your browser. If it did not open, visit:"), 1, 0),
51723
- new Text(this.theme.fg("accent", hyperlink(authorizationUrl, authorizationUrl)), 1, 0),
51724
- new Text(this.theme.fg("dim", hyperlink(clickHint, authorizationUrl)), 1, 0),
52011
+ link,
51725
52012
  new Spacer(1),
51726
52013
  new Text(this.theme.fg("muted", "If the browser runs on another machine, paste the URL it was redirected to:"), 1, 0),
51727
52014
  input
@@ -51737,6 +52024,10 @@ class McpManagerView {
51737
52024
  finish(undefined);
51738
52025
  return;
51739
52026
  }
52027
+ if (this.keybindings.matches(data, "app.message.copy")) {
52028
+ link.copy();
52029
+ return;
52030
+ }
51740
52031
  input.handleInput(data);
51741
52032
  }, input);
51742
52033
  });
@@ -51896,6 +52187,7 @@ function createMcpExtension(options = {}) {
51896
52187
  let servers = [];
51897
52188
  let configuredEntries = [];
51898
52189
  let configErrors = [];
52190
+ let projectConfig;
51899
52191
  let overridden = [];
51900
52192
  let sessionActive = false;
51901
52193
  let autoEnableCodemode = true;
@@ -51909,7 +52201,9 @@ function createMcpExtension(options = {}) {
51909
52201
  let modelRegistry;
51910
52202
  let serverLog;
51911
52203
  const openUrl = options.openUrl ?? openBrowser;
51912
- const updateConfig = options.updateConfig ?? ((entry, patch) => updateMcpServerConfig(entry.source, entry.name, patch));
52204
+ const updateConfig = options.updateConfig ?? ((entry, patch) => updateMcpServerConfig(entry.override ?? entry.source, entry.name, patch, {
52205
+ override: entry.override !== undefined
52206
+ }));
51913
52207
  const listeners = new Set;
51914
52208
  const emitChange = () => {
51915
52209
  for (const listener of listeners)
@@ -51944,12 +52238,16 @@ function createMcpExtension(options = {}) {
51944
52238
  return credentials;
51945
52239
  };
51946
52240
  const getServerLog = (runtime) => {
51947
- serverLog ??= new runtime.McpServerLog(options.logPath ?? join20(getAgentDir(), "mcp.log"));
52241
+ serverLog ??= new runtime.McpServerLog(options.logPath ?? join21(getAgentDir(), "mcp.log"));
51948
52242
  return serverLog;
51949
52243
  };
51950
52244
  const toolOwners = new Map;
51951
52245
  const serverTools = new Map;
51952
52246
  const definitions = new Map;
52247
+ pi.registerToolRenderer((toolName, next) => {
52248
+ const match2 = /^mcp__(.+?)__(.+)$/.exec(toolName);
52249
+ return next() ?? (match2 ? createMcpToolRenderers(`${match2[1]}/${match2[2]}`) : undefined);
52250
+ });
51953
52251
  const registerTools = (connection) => {
51954
52252
  const server = connection.entry.name;
51955
52253
  const entry = findServer(server)?.entry ?? connection.entry;
@@ -52139,15 +52437,17 @@ ${lines.map((line) => ` ${line}`).join(`
52139
52437
  `)}
52140
52438
  Run /mcp to fix.`, "warning");
52141
52439
  };
52142
- const saveConfig = (server, patch) => {
52143
- if (server.entry.scope !== "extension") {
52440
+ const saveConfig = (server, patch, inProject = false) => {
52441
+ const override = inProject ? projectConfig : server.entry.override;
52442
+ const entry = override ? { ...server.entry, override } : server.entry;
52443
+ if (entry.scope !== "extension") {
52144
52444
  try {
52145
- updateConfig(server.entry, patch);
52445
+ updateConfig(entry, patch);
52146
52446
  } catch (error) {
52147
- return `Could not update ${server.entry.source}: ${errorMessage(error)}`;
52447
+ return `Could not update ${entry.override ?? entry.source}: ${errorMessage(error)}`;
52148
52448
  }
52149
52449
  }
52150
- server.entry = { ...server.entry, config: { ...server.entry.config, ...patch } };
52450
+ server.entry = { ...entry, config: { ...entry.config, ...patch } };
52151
52451
  return;
52152
52452
  };
52153
52453
  const signIn = async (server, prompt) => {
@@ -52197,8 +52497,8 @@ Run /mcp to fix.`, "warning");
52197
52497
  return errorMessage(error);
52198
52498
  }
52199
52499
  };
52200
- const setEnabled = async (server, enabled) => {
52201
- const failed = saveConfig(server, { enabled });
52500
+ const setEnabled = async (server, enabled, inProject = false) => {
52501
+ const failed = saveConfig(server, { enabled }, inProject);
52202
52502
  if (failed)
52203
52503
  return failed;
52204
52504
  if (!enabled) {
@@ -52236,7 +52536,7 @@ Run /mcp to fix.`, "warning");
52236
52536
  items: [...servers].sort((a, b) => attentionRank(a) - attentionRank(b) || a.entry.name.localeCompare(b.entry.name)).map((server) => ({
52237
52537
  value: server.entry.name,
52238
52538
  label: server.entry.name,
52239
- description: `${describeState(server)} · ${exposureOf(server.entry)} · ${server.entry.scope ?? server.entry.source}`
52539
+ description: `${describeState(server)} · ${exposureOf(server.entry)} · ${server.entry.override ? "global, project override" : server.entry.scope ?? server.entry.source}`
52240
52540
  })),
52241
52541
  empty: `No MCP servers configured. Add them to ${resolve10(getAgentDir(), "mcp.json")} or .pi/mcp.json.`,
52242
52542
  confirmLabel: "manage",
@@ -52254,10 +52554,15 @@ Run /mcp to fix.`, "warning");
52254
52554
  };
52255
52555
  }
52256
52556
  const { entry, connection } = server;
52257
- const saved = entry.scope === "extension" ? "for this session" : entry.scope ? `saved to the ${entry.scope} mcp.json` : "saved to mcp.json";
52557
+ const saved = entry.scope === "extension" ? "for this session" : entry.override ? "saved to the project mcp.json" : entry.scope ? `saved to the ${entry.scope} mcp.json` : "saved to mcp.json";
52558
+ const inProject = entry.scope === "global" && !entry.override && projectConfig !== undefined;
52559
+ const inProjectSaved = "saved to the project mcp.json";
52258
52560
  const items = [];
52259
52561
  if (!isEnabled(server)) {
52260
52562
  items.push({ value: "enable", label: "Enable", description: saved });
52563
+ if (inProject) {
52564
+ items.push({ value: "enable-project", label: "Enable in this project", description: inProjectSaved });
52565
+ }
52261
52566
  } else {
52262
52567
  const state = connection?.state;
52263
52568
  if (state === "needs-auth")
@@ -52273,10 +52578,14 @@ Run /mcp to fix.`, "warning");
52273
52578
  }
52274
52579
  items.push({ value: "exposure", label: "Exposure", description: exposureOf(entry) });
52275
52580
  items.push({ value: "disable", label: "Disable", description: saved });
52581
+ if (inProject) {
52582
+ items.push({ value: "disable-project", label: "Disable in this project", description: inProjectSaved });
52583
+ }
52276
52584
  }
52277
52585
  const details = [
52278
52586
  describeTransport(entry),
52279
52587
  `${entry.scope ?? "config"}: ${entry.source}`,
52588
+ ...entry.override ? [`project override: ${entry.override}`] : [],
52280
52589
  `State: ${describeState(server, false)}`
52281
52590
  ];
52282
52591
  const error = [server.message, connection?.state === "connected" ? undefined : connection?.error].filter((line) => line !== undefined).join(`
@@ -52317,7 +52626,7 @@ Some tools override it with toolExposure.` : ""}`,
52317
52626
  const current = exposureOf(server.entry);
52318
52627
  const choice = await ui.menu(() => ({
52319
52628
  title: `Exposure of ${server.entry.name}`,
52320
- details: server.entry.scope === "extension" ? `Applies to this session; the server is registered by ${server.entry.source}.` : `Saved to ${server.entry.source}.`,
52629
+ details: server.entry.scope === "extension" ? `Applies to this session; the server is registered by ${server.entry.source}.` : `Saved to ${server.entry.override ?? server.entry.source}.`,
52321
52630
  items: Object.keys(EXPOSURE_DESCRIPTIONS).map((exposure) => ({
52322
52631
  value: exposure,
52323
52632
  label: `${exposure === current ? "✓ " : " "}${exposure}`,
@@ -52331,27 +52640,29 @@ Some tools override it with toolExposure.` : ""}`,
52331
52640
  return;
52332
52641
  return setExposure(server, choice);
52333
52642
  };
52643
+ const signInWithUi = (ui, server) => {
52644
+ const title = `Sign in to ${server.entry.name}`;
52645
+ let authorizationUrl = "";
52646
+ ui.status(title, "Contacting the authorization server…");
52647
+ return signIn(server, {
52648
+ showAuthorizationUrl: (url) => {
52649
+ authorizationUrl = url.href;
52650
+ openUrl(url.href);
52651
+ },
52652
+ promptForRedirectUrl: async (signal) => {
52653
+ const value = await ui.redirectUrl(title, authorizationUrl, signal);
52654
+ ui.status(title, "Connecting…");
52655
+ return value;
52656
+ }
52657
+ });
52658
+ };
52334
52659
  const runAction = async (ui, ctx, server, action) => {
52335
52660
  const { name } = server.entry;
52336
52661
  let message;
52337
52662
  switch (action) {
52338
- case "signin": {
52339
- const title = `Sign in to ${name}`;
52340
- let authorizationUrl = "";
52341
- ui.status(title, "Contacting the authorization server…");
52342
- message = await signIn(server, {
52343
- showAuthorizationUrl: (url) => {
52344
- authorizationUrl = url.href;
52345
- openUrl(url.href);
52346
- },
52347
- promptForRedirectUrl: async (signal) => {
52348
- const value = await ui.redirectUrl(title, authorizationUrl, signal);
52349
- ui.status(title, "Connecting…");
52350
- return value;
52351
- }
52352
- });
52663
+ case "signin":
52664
+ message = await signInWithUi(ui, server);
52353
52665
  break;
52354
- }
52355
52666
  case "reconnect":
52356
52667
  ui.status(`MCP server ${name}`, "Reconnecting…");
52357
52668
  await reconnect(server);
@@ -52367,9 +52678,13 @@ Some tools override it with toolExposure.` : ""}`,
52367
52678
  break;
52368
52679
  case "enable":
52369
52680
  case "disable":
52370
- ui.status(`MCP server ${name}`, action === "enable" ? "Connecting…" : "Disconnecting…");
52371
- message = await setEnabled(server, action === "enable");
52681
+ case "enable-project":
52682
+ case "disable-project": {
52683
+ const enable = action.startsWith("enable");
52684
+ ui.status(`MCP server ${name}`, enable ? "Connecting…" : "Disconnecting…");
52685
+ message = await setEnabled(server, enable, action.endsWith("-project"));
52372
52686
  break;
52687
+ }
52373
52688
  }
52374
52689
  server.message = message;
52375
52690
  ensureDiscoveryActive(ctx);
@@ -52448,16 +52763,21 @@ Some tools override it with toolExposure.` : ""}`,
52448
52763
  ctx.ui.notify(`Signing in to MCP server "${name}" requires interactive mode.`, "error");
52449
52764
  return;
52450
52765
  }
52451
- const failure = await signIn(server, {
52452
- showAuthorizationUrl: (url) => {
52453
- const lines = ctx.mode === "tui" ? `${hyperlink(url.href, url.href)}
52454
- ${hyperlink(process.platform === "darwin" ? "Cmd+click to open" : "Ctrl+click to open", url.href)}` : url.href;
52455
- ctx.ui.notify(`Sign in to MCP server "${name}" in your browser:
52456
- ${lines}`, "info");
52457
- openUrl(url.href);
52458
- },
52459
- promptForRedirectUrl: (signal) => ctx.ui.input(`Waiting for sign-in to "${name}". If the browser cannot reach this machine, paste the URL it was redirected to.`, "http://127.0.0.1:.../callback?code=...", { signal })
52460
- });
52766
+ let failure;
52767
+ if (ctx.mode === "tui") {
52768
+ await showMcpManager(ctx, async (ui) => {
52769
+ failure = await signInWithUi(ui, server);
52770
+ });
52771
+ } else {
52772
+ failure = await signIn(server, {
52773
+ showAuthorizationUrl: (url) => {
52774
+ ctx.ui.notify(`Sign in to MCP server "${name}" in your browser:
52775
+ ${url.href}`, "info");
52776
+ openUrl(url.href);
52777
+ },
52778
+ promptForRedirectUrl: (signal) => ctx.ui.input(`Waiting for sign-in to "${name}". If the browser cannot reach this machine, paste the URL it was redirected to.`, "http://127.0.0.1:.../callback?code=...", { signal })
52779
+ });
52780
+ }
52461
52781
  if (failure) {
52462
52782
  ctx.ui.notify(failure, failure === "Sign-in cancelled." ? "info" : "error");
52463
52783
  return;
@@ -52468,6 +52788,7 @@ ${lines}`, "info");
52468
52788
  pi.on("session_start", (_event, ctx) => {
52469
52789
  const loaded = (options.loadConfig ?? defaultLoadConfig)(ctx);
52470
52790
  configErrors = loaded.errors;
52791
+ projectConfig = loaded.projectConfig;
52471
52792
  autoEnableCodemode = loaded.autoEnableCodemode ?? true;
52472
52793
  warnedUnreachable = false;
52473
52794
  waitedForStartup = false;
@@ -53210,10 +53531,10 @@ function areExperimentalFeaturesEnabled() {
53210
53531
  }
53211
53532
 
53212
53533
  // node_modules/@earendil-works/pi-coding-agent/dist/core/keybindings.js
53213
- import { existsSync as existsSync14, readFileSync as readFileSync10 } from "fs";
53214
- import { join as join21 } from "path";
53215
- function useWindowsKeybindings(platform2 = process.platform, env = process.env) {
53216
- return platform2 === "win32" || platform2 === "linux" && Boolean(env.WSL_DISTRO_NAME || env.WSL_INTEROP);
53534
+ import { existsSync as existsSync14, readFileSync as readFileSync11 } from "fs";
53535
+ import { join as join22 } from "path";
53536
+ function useWindowsKeybindings(platform3 = process.platform, env = process.env) {
53537
+ return platform3 === "win32" || platform3 === "linux" && Boolean(env.WSL_DISTRO_NAME || env.WSL_INTEROP);
53217
53538
  }
53218
53539
  var windowsKeybindings = useWindowsKeybindings();
53219
53540
  var KEYBINDINGS = {
@@ -53490,7 +53811,7 @@ function loadRawConfig(path6) {
53490
53811
  if (!existsSync14(path6))
53491
53812
  return;
53492
53813
  try {
53493
- const parsed = JSON.parse(stripBom(readFileSync10(path6, "utf-8")));
53814
+ const parsed = JSON.parse(stripBom(readFileSync11(path6, "utf-8")));
53494
53815
  if (typeof parsed !== "object" || parsed === null)
53495
53816
  return;
53496
53817
  return parsed;
@@ -53506,7 +53827,7 @@ class KeybindingsManager2 extends KeybindingsManager {
53506
53827
  this.configPath = configPath;
53507
53828
  }
53508
53829
  static create(agentDir = getAgentDir()) {
53509
- const configPath = join21(agentDir, "keybindings.json");
53830
+ const configPath = join22(agentDir, "keybindings.json");
53510
53831
  const userBindings = KeybindingsManager2.loadFromFile(configPath);
53511
53832
  return new KeybindingsManager2(userBindings, configPath);
53512
53833
  }
@@ -55523,7 +55844,7 @@ class LlamaClient {
55523
55844
  // node_modules/@earendil-works/pi-coding-agent/dist/extensions/llama/huggingface.js
55524
55845
  import { readFile as readFile4 } from "node:fs/promises";
55525
55846
  import { homedir as homedir3 } from "node:os";
55526
- import { join as join22 } from "node:path";
55847
+ import { join as join23 } from "node:path";
55527
55848
  var DEFAULT_HUGGING_FACE_URL = "https://huggingface.co";
55528
55849
  var QUANTIZATION_PATTERN = /(?:^|[-_.])((?:UD-)?(?:IQ\d(?:_[A-Z0-9]+)+|Q\d(?:_[A-Z0-9]+)+|BF16|F16|F32|MXFP\d(?:_[A-Z0-9]+)*))$/iu;
55529
55850
  var SHARD_SUFFIX_PATTERN = /-\d{5}-of-\d{5}$/u;
@@ -55551,9 +55872,9 @@ async function findHuggingFaceToken(env = process.env) {
55551
55872
  return fromEnvironment;
55552
55873
  const paths = [
55553
55874
  env.HF_TOKEN_PATH,
55554
- env.HF_HOME ? join22(env.HF_HOME, "token") : undefined,
55555
- env.XDG_CACHE_HOME ? join22(env.XDG_CACHE_HOME, "huggingface", "token") : undefined,
55556
- join22(homedir3(), ".cache", "huggingface", "token")
55875
+ env.HF_HOME ? join23(env.HF_HOME, "token") : undefined,
55876
+ env.XDG_CACHE_HOME ? join23(env.XDG_CACHE_HOME, "huggingface", "token") : undefined,
55877
+ join23(homedir3(), ".cache", "huggingface", "token")
55557
55878
  ].filter((path6) => Boolean(path6));
55558
55879
  for (const path6 of new Set(paths)) {
55559
55880
  const token = await readToken(path6);
@@ -56494,25 +56815,25 @@ var builtInExtensions = [
56494
56815
  ];
56495
56816
 
56496
56817
  // node_modules/@earendil-works/pi-coding-agent/dist/extensions/mcp/cli.lazy.js
56497
- var loadMcpCommand = () => import("./cli-nsdxtcbg.js");
56818
+ var loadMcpCommand = () => import("./cli-tcen9p5w.js");
56498
56819
 
56499
56820
  // node_modules/@earendil-works/pi-coding-agent/dist/migrations.js
56500
- import { existsSync as existsSync17, mkdirSync as mkdirSync7, readdirSync as readdirSync8, readFileSync as readFileSync11, renameSync as renameSync2, rmSync as rmSync3, writeFileSync as writeFileSync6 } from "fs";
56501
- import { dirname as dirname14, join as join23 } from "path";
56821
+ import { existsSync as existsSync17, mkdirSync as mkdirSync7, readdirSync as readdirSync8, readFileSync as readFileSync12, renameSync as renameSync2, rmSync as rmSync3, writeFileSync as writeFileSync7 } from "fs";
56822
+ import { dirname as dirname14, join as join24 } from "path";
56502
56823
  var MIGRATION_GUIDE_URL = "https://github.com/earendil-works/pi/blob/main/packages/coding-agent/CHANGELOG.md#extensions-migration";
56503
56824
  var EXTENSIONS_DOC_URL = "https://github.com/earendil-works/pi/blob/main/packages/coding-agent/docs/extensions.md";
56504
56825
  function migrateAuthToAuthJson() {
56505
56826
  const agentDir = getAgentDir();
56506
- const authPath = join23(agentDir, "auth.json");
56507
- const oauthPath = join23(agentDir, "oauth.json");
56508
- const settingsPath = join23(agentDir, "settings.json");
56827
+ const authPath = join24(agentDir, "auth.json");
56828
+ const oauthPath = join24(agentDir, "oauth.json");
56829
+ const settingsPath = join24(agentDir, "settings.json");
56509
56830
  if (existsSync17(authPath))
56510
56831
  return [];
56511
56832
  const migrated = {};
56512
56833
  const providers = [];
56513
56834
  if (existsSync17(oauthPath)) {
56514
56835
  try {
56515
- const oauth = JSON.parse(stripBom(readFileSync11(oauthPath, "utf-8")));
56836
+ const oauth = JSON.parse(stripBom(readFileSync12(oauthPath, "utf-8")));
56516
56837
  for (const [provider, cred] of Object.entries(oauth)) {
56517
56838
  migrated[provider] = { type: "oauth", ...cred };
56518
56839
  providers.push(provider);
@@ -56522,7 +56843,7 @@ function migrateAuthToAuthJson() {
56522
56843
  }
56523
56844
  if (existsSync17(settingsPath)) {
56524
56845
  try {
56525
- const content = readFileSync11(settingsPath, "utf-8");
56846
+ const content = readFileSync12(settingsPath, "utf-8");
56526
56847
  const settings = JSON.parse(stripBom(content));
56527
56848
  if (settings.apiKeys && typeof settings.apiKeys === "object") {
56528
56849
  for (const [provider, key] of Object.entries(settings.apiKeys)) {
@@ -56532,13 +56853,13 @@ function migrateAuthToAuthJson() {
56532
56853
  }
56533
56854
  }
56534
56855
  delete settings.apiKeys;
56535
- writeFileSync6(settingsPath, JSON.stringify(settings, null, 2));
56856
+ writeFileSync7(settingsPath, JSON.stringify(settings, null, 2));
56536
56857
  }
56537
56858
  } catch {}
56538
56859
  }
56539
56860
  if (Object.keys(migrated).length > 0) {
56540
56861
  mkdirSync7(dirname14(authPath), { recursive: true });
56541
- writeFileSync6(authPath, JSON.stringify(migrated, null, 2), { mode: 384 });
56862
+ writeFileSync7(authPath, JSON.stringify(migrated, null, 2), { mode: 384 });
56542
56863
  }
56543
56864
  return providers;
56544
56865
  }
@@ -56546,7 +56867,7 @@ function migrateSessionsFromAgentRoot() {
56546
56867
  const agentDir = getAgentDir();
56547
56868
  let files;
56548
56869
  try {
56549
- files = readdirSync8(agentDir).filter((f) => f.endsWith(".jsonl")).map((f) => join23(agentDir, f));
56870
+ files = readdirSync8(agentDir).filter((f) => f.endsWith(".jsonl")).map((f) => join24(agentDir, f));
56550
56871
  } catch {
56551
56872
  return;
56552
56873
  }
@@ -56554,7 +56875,7 @@ function migrateSessionsFromAgentRoot() {
56554
56875
  return;
56555
56876
  for (const file of files) {
56556
56877
  try {
56557
- const content = readFileSync11(file, "utf8");
56878
+ const content = readFileSync12(file, "utf8");
56558
56879
  const firstLine2 = content.split(`
56559
56880
  `)[0];
56560
56881
  if (!firstLine2?.trim())
@@ -56564,12 +56885,12 @@ function migrateSessionsFromAgentRoot() {
56564
56885
  continue;
56565
56886
  const cwd = header.cwd;
56566
56887
  const safePath = `--${cwd.replace(/^[/\\]/, "").replace(/[/\\:]/g, "-")}--`;
56567
- const correctDir = join23(agentDir, "sessions", safePath);
56888
+ const correctDir = join24(agentDir, "sessions", safePath);
56568
56889
  if (!existsSync17(correctDir)) {
56569
56890
  mkdirSync7(correctDir, { recursive: true });
56570
56891
  }
56571
56892
  const fileName = file.split("/").pop() || file.split("\\").pop();
56572
- const newPath = join23(correctDir, fileName);
56893
+ const newPath = join24(correctDir, fileName);
56573
56894
  if (existsSync17(newPath))
56574
56895
  continue;
56575
56896
  renameSync2(file, newPath);
@@ -56577,8 +56898,8 @@ function migrateSessionsFromAgentRoot() {
56577
56898
  }
56578
56899
  }
56579
56900
  function migrateCommandsToPrompts(baseDir, label) {
56580
- const commandsDir = join23(baseDir, "commands");
56581
- const promptsDir = join23(baseDir, "prompts");
56901
+ const commandsDir = join24(baseDir, "commands");
56902
+ const promptsDir = join24(baseDir, "prompts");
56582
56903
  if (existsSync17(commandsDir) && !existsSync17(promptsDir)) {
56583
56904
  try {
56584
56905
  renameSync2(commandsDir, promptsDir);
@@ -56591,32 +56912,32 @@ function migrateCommandsToPrompts(baseDir, label) {
56591
56912
  return false;
56592
56913
  }
56593
56914
  function migrateKeybindingsConfigFile() {
56594
- const configPath = join23(getAgentDir(), "keybindings.json");
56915
+ const configPath = join24(getAgentDir(), "keybindings.json");
56595
56916
  if (!existsSync17(configPath))
56596
56917
  return;
56597
56918
  try {
56598
- const parsed = JSON.parse(stripBom(readFileSync11(configPath, "utf-8")));
56919
+ const parsed = JSON.parse(stripBom(readFileSync12(configPath, "utf-8")));
56599
56920
  if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
56600
56921
  return;
56601
56922
  }
56602
56923
  const { config, migrated } = migrateKeybindingsConfig(parsed);
56603
56924
  if (!migrated)
56604
56925
  return;
56605
- writeFileSync6(configPath, `${JSON.stringify(config, null, 2)}
56926
+ writeFileSync7(configPath, `${JSON.stringify(config, null, 2)}
56606
56927
  `, "utf-8");
56607
56928
  } catch {}
56608
56929
  }
56609
56930
  function migrateToolsToBin() {
56610
56931
  const agentDir = getAgentDir();
56611
- const toolsDir = join23(agentDir, "tools");
56932
+ const toolsDir = join24(agentDir, "tools");
56612
56933
  const binDir = getBinDir();
56613
56934
  if (!existsSync17(toolsDir))
56614
56935
  return;
56615
56936
  const binaries = ["fd", "rg", "fd.exe", "rg.exe"];
56616
56937
  let movedAny = false;
56617
56938
  for (const bin of binaries) {
56618
- const oldPath = join23(toolsDir, bin);
56619
- const newPath = join23(binDir, bin);
56939
+ const oldPath = join24(toolsDir, bin);
56940
+ const newPath = join24(binDir, bin);
56620
56941
  if (existsSync17(oldPath)) {
56621
56942
  if (!existsSync17(binDir)) {
56622
56943
  mkdirSync7(binDir, { recursive: true });
@@ -56638,8 +56959,8 @@ function migrateToolsToBin() {
56638
56959
  }
56639
56960
  }
56640
56961
  function checkDeprecatedExtensionDirs(baseDir, label) {
56641
- const hooksDir = join23(baseDir, "hooks");
56642
- const toolsDir = join23(baseDir, "tools");
56962
+ const hooksDir = join24(baseDir, "hooks");
56963
+ const toolsDir = join24(baseDir, "tools");
56643
56964
  const warnings = [];
56644
56965
  if (existsSync17(hooksDir)) {
56645
56966
  warnings.push(`${label} hooks/ directory found. Hooks have been renamed to extensions.`);
@@ -56660,7 +56981,7 @@ function checkDeprecatedExtensionDirs(baseDir, label) {
56660
56981
  }
56661
56982
  function migrateExtensionSystem(cwd) {
56662
56983
  const agentDir = getAgentDir();
56663
- const projectDir = join23(cwd, CONFIG_DIR_NAME);
56984
+ const projectDir = join24(cwd, CONFIG_DIR_NAME);
56664
56985
  migrateCommandsToPrompts(agentDir, "Global");
56665
56986
  migrateCommandsToPrompts(projectDir, "Project");
56666
56987
  const warnings = [
@@ -56785,16 +57106,16 @@ function detectCacheMiss(entries, message, models) {
56785
57106
  }
56786
57107
 
56787
57108
  // node_modules/@earendil-works/pi-coding-agent/dist/core/crash-log.js
56788
- import { mkdirSync as mkdirSync8, readFileSync as readFileSync12, rmSync as rmSync4, writeFileSync as writeFileSync7 } from "node:fs";
56789
- import { dirname as dirname15, join as join24 } from "node:path";
57109
+ import { mkdirSync as mkdirSync8, readFileSync as readFileSync13, rmSync as rmSync4, writeFileSync as writeFileSync8 } from "node:fs";
57110
+ import { dirname as dirname15, join as join25 } from "node:path";
56790
57111
  var MAX_CRASH_RECORDS = 5;
56791
57112
  var MAX_AGE = 7 * 24 * 60 * 60 * 1000;
56792
57113
  function crashLogPath(agentDir = getAgentDir()) {
56793
- return join24(agentDir, "crashes.json");
57114
+ return join25(agentDir, "crashes.json");
56794
57115
  }
56795
57116
  function readCrashLog(path6 = crashLogPath()) {
56796
57117
  try {
56797
- const records = JSON.parse(readFileSync12(path6, "utf8"));
57118
+ const records = JSON.parse(readFileSync13(path6, "utf8"));
56798
57119
  return Array.isArray(records) ? records.filter((record) => typeof record === "object" && record !== null && typeof record.timestamp === "string" && typeof record.message === "string") : [];
56799
57120
  } catch {
56800
57121
  return [];
@@ -56802,7 +57123,7 @@ function readCrashLog(path6 = crashLogPath()) {
56802
57123
  }
56803
57124
  function writeCrashLog(records, path6) {
56804
57125
  mkdirSync8(dirname15(path6), { recursive: true });
56805
- writeFileSync7(path6, `${JSON.stringify(records, null, 2)}
57126
+ writeFileSync8(path6, `${JSON.stringify(records, null, 2)}
56806
57127
  `);
56807
57128
  }
56808
57129
  function normalizeStackPath(value) {
@@ -56955,7 +57276,7 @@ function withBuiltInRenderers(toolName, definition) {
56955
57276
 
56956
57277
  // node_modules/@earendil-works/pi-coding-agent/dist/utils/changelog.js
56957
57278
  import path6 from "node:path";
56958
- import { existsSync as existsSync18, readFileSync as readFileSync13 } from "fs";
57279
+ import { existsSync as existsSync18, readFileSync as readFileSync14 } from "fs";
56959
57280
  var GITHUB_REPO = "earendil-works/pi";
56960
57281
  var CHANGELOG_LINK_BASE_PATH = "packages/coding-agent";
56961
57282
  var LEGACY_REPO_RE = /^https:\/\/github\.com\/(?:badlogic|earendil-works)\/pi-mono(?=\/|$)/;
@@ -57036,7 +57357,7 @@ function parseChangelog(changelogPath) {
57036
57357
  return [];
57037
57358
  }
57038
57359
  try {
57039
- const content = readFileSync13(changelogPath, "utf-8");
57360
+ const content = readFileSync14(changelogPath, "utf-8");
57040
57361
  const lines = content.split(`
57041
57362
  `);
57042
57363
  const entries = [];
@@ -57098,196 +57419,6 @@ function getNewEntries(entries, lastVersion) {
57098
57419
  return entries.filter((entry) => compareVersions(entry, last) > 0);
57099
57420
  }
57100
57421
 
57101
- // node_modules/@earendil-works/pi-coding-agent/dist/utils/clipboard.js
57102
- import { randomUUID as randomUUID3 } from "node:crypto";
57103
- import { unlinkSync, writeFileSync as writeFileSync8 } from "node:fs";
57104
- import { platform as platform2, tmpdir as tmpdir3 } from "node:os";
57105
- import { join as join25 } from "node:path";
57106
-
57107
- // node_modules/@earendil-works/pi-coding-agent/dist/utils/clipboard-command.js
57108
- import { spawn as spawn5 } from "node:child_process";
57109
- function runClipboardCommand(command, args, options) {
57110
- return new Promise((resolve12) => {
57111
- const child = spawn5(command, args, {
57112
- stdio: ["pipe", options?.input === undefined ? "pipe" : "ignore", "ignore"],
57113
- windowsHide: true
57114
- });
57115
- const chunks = [];
57116
- let length = 0;
57117
- let settled = false;
57118
- const finish = (result) => {
57119
- if (settled)
57120
- return;
57121
- settled = true;
57122
- clearTimeout(timer);
57123
- resolve12(result);
57124
- };
57125
- const abort = () => {
57126
- child.kill("SIGKILL");
57127
- child.stdout?.destroy();
57128
- child.stdin?.destroy();
57129
- finish(undefined);
57130
- };
57131
- const timer = setTimeout(abort, options?.timeoutMs ?? 3000);
57132
- child.on("error", () => finish(undefined));
57133
- child.on("close", (code) => {
57134
- if (!settled)
57135
- finish(code === 0 ? Buffer.concat(chunks, length) : undefined);
57136
- });
57137
- child.stdout?.on("data", (chunk) => {
57138
- if (settled)
57139
- return;
57140
- length += chunk.length;
57141
- if (length > (options?.maxBufferBytes ?? 50 * 1024 * 1024))
57142
- abort();
57143
- else
57144
- chunks.push(chunk);
57145
- });
57146
- child.stdin?.on("error", () => {});
57147
- child.stdin?.end(options?.input);
57148
- });
57149
- }
57150
-
57151
- // node_modules/@earendil-works/pi-coding-agent/dist/utils/wsl.js
57152
- import { readFileSync as readFileSync14 } from "node:fs";
57153
- function isWSL(env = process.env) {
57154
- if (env.WSL_DISTRO_NAME || env.WSLENV) {
57155
- return true;
57156
- }
57157
- try {
57158
- const release2 = readFileSync14("/proc/version", "utf-8");
57159
- return /microsoft|wsl/i.test(release2);
57160
- } catch {
57161
- return false;
57162
- }
57163
- }
57164
-
57165
- // node_modules/@earendil-works/pi-coding-agent/dist/utils/clipboard.js
57166
- var MAX_OSC52_ENCODED_LENGTH = 1e5;
57167
- function isRemoteSession(env) {
57168
- return Boolean(env.SSH_CONNECTION || env.SSH_CLIENT || env.MOSH_CONNECTION);
57169
- }
57170
- function emitOsc52(text) {
57171
- const encoded = Buffer.from(text).toString("base64");
57172
- if (encoded.length > MAX_OSC52_ENCODED_LENGTH) {
57173
- return false;
57174
- }
57175
- process.stdout.write(`\x1B]52;c;${encoded}\x07`);
57176
- return true;
57177
- }
57178
- async function copyViaWindowsClipboard(text) {
57179
- const tmpFile = join25(tmpdir3(), `pi-wsl-clip-${randomUUID3()}.txt`);
57180
- try {
57181
- writeFileSync8(tmpFile, text, { encoding: "utf8", mode: 384 });
57182
- const winPath = (await runClipboardCommand("wslpath", ["-w", tmpFile], { timeoutMs: 1000 }))?.toString("utf8").trim();
57183
- if (!winPath)
57184
- return false;
57185
- const script = `Set-Clipboard -Value ([System.IO.File]::ReadAllText('${winPath.replaceAll("'", "''")}', [System.Text.Encoding]::UTF8))`;
57186
- const result = await runClipboardCommand("powershell.exe", ["-NoProfile", "-Command", script], {
57187
- timeoutMs: 5000
57188
- });
57189
- return result !== undefined;
57190
- } catch {
57191
- return false;
57192
- } finally {
57193
- try {
57194
- unlinkSync(tmpFile);
57195
- } catch {}
57196
- }
57197
- }
57198
- async function readClipboardText() {
57199
- if (platform2() === "linux") {
57200
- const commands = [];
57201
- if (process.env.TERMUX_VERSION)
57202
- commands.push(["termux-clipboard-get", []]);
57203
- if (process.env.WAYLAND_DISPLAY)
57204
- commands.push(["wl-paste", ["--no-newline", "--type", "text"]]);
57205
- if (process.env.DISPLAY) {
57206
- commands.push(["xclip", ["-selection", "clipboard", "-out"]], ["xsel", ["--clipboard", "--output"]]);
57207
- }
57208
- for (const [command, args] of commands) {
57209
- const bytes = await runClipboardCommand(command, args, { timeoutMs: 5000 });
57210
- if (bytes !== undefined)
57211
- return bytes.toString("utf8") || null;
57212
- }
57213
- }
57214
- try {
57215
- return await getNativeClipboard()?.getText() || null;
57216
- } catch {
57217
- return null;
57218
- }
57219
- }
57220
- async function readClipboardFilePaths() {
57221
- const paths = await getNativeClipboard()?.getFilePaths?.();
57222
- return paths?.length ? paths : null;
57223
- }
57224
- async function copyToClipboard(text) {
57225
- const p = platform2();
57226
- const env = process.env;
57227
- let copied = false;
57228
- if (p !== "linux") {
57229
- try {
57230
- const clipboard = getNativeClipboard();
57231
- if (clipboard?.setText) {
57232
- await clipboard.setText(text);
57233
- copied = true;
57234
- }
57235
- } catch {}
57236
- }
57237
- if (!copied) {
57238
- const commands = [];
57239
- if (p === "darwin")
57240
- commands.push(["pbcopy", []]);
57241
- else if (p === "win32")
57242
- commands.push(["clip", []]);
57243
- else {
57244
- if (env.TERMUX_VERSION)
57245
- commands.push(["termux-clipboard-set", []]);
57246
- if (env.WAYLAND_DISPLAY)
57247
- commands.push(["wl-copy", []]);
57248
- if (env.DISPLAY) {
57249
- commands.push(["xclip", ["-selection", "clipboard"]], ["xsel", ["--clipboard", "--input"]]);
57250
- }
57251
- }
57252
- for (const [command, args] of commands) {
57253
- if (await runClipboardCommand(command, args, { input: text, timeoutMs: 5000 }) !== undefined) {
57254
- copied = true;
57255
- break;
57256
- }
57257
- }
57258
- }
57259
- let osc52Emitted = false;
57260
- if (!copied && p === "linux" && isWSL(env)) {
57261
- if (env.WT_SESSION)
57262
- osc52Emitted = emitOsc52(text);
57263
- copied = osc52Emitted || await copyViaWindowsClipboard(text);
57264
- }
57265
- const headless = p === "linux" && !env.DISPLAY && !env.WAYLAND_DISPLAY && !env.TERMUX_VERSION;
57266
- let oversized = false;
57267
- if (!osc52Emitted && (isRemoteSession(env) || !copied && headless)) {
57268
- if (emitOsc52(text))
57269
- copied = true;
57270
- else
57271
- oversized = true;
57272
- }
57273
- if (copied)
57274
- return;
57275
- if (oversized)
57276
- throw new Error("Clipboard unavailable: text exceeds the OSC 52 size limit");
57277
- if (p === "linux") {
57278
- if (env.TERMUX_VERSION) {
57279
- throw new Error("Clipboard unavailable: install the Termux:API app and `termux-api` package");
57280
- }
57281
- if (env.WAYLAND_DISPLAY) {
57282
- throw new Error("Clipboard unavailable: install `wl-clipboard` (`wl-copy`) or check Wayland access");
57283
- }
57284
- if (env.DISPLAY) {
57285
- throw new Error("Clipboard unavailable: install `xclip` or `xsel`, or check X11 access");
57286
- }
57287
- }
57288
- throw new Error("Clipboard unavailable");
57289
- }
57290
-
57291
57422
  // node_modules/@earendil-works/pi-coding-agent/dist/utils/clipboard-image.js
57292
57423
  import { randomUUID as randomUUID4 } from "crypto";
57293
57424
  import { readFileSync as readFileSync15, unlinkSync as unlinkSync2 } from "fs";
@@ -58113,448 +58244,6 @@ function createChatViewport(options) {
58113
58244
  };
58114
58245
  }
58115
58246
 
58116
- // node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/armin.js
58117
- var WIDTH = 31;
58118
- var HEIGHT = 36;
58119
- var BITS = [
58120
- 255,
58121
- 255,
58122
- 255,
58123
- 127,
58124
- 255,
58125
- 240,
58126
- 255,
58127
- 127,
58128
- 255,
58129
- 237,
58130
- 255,
58131
- 127,
58132
- 255,
58133
- 219,
58134
- 255,
58135
- 127,
58136
- 255,
58137
- 183,
58138
- 255,
58139
- 127,
58140
- 255,
58141
- 119,
58142
- 254,
58143
- 127,
58144
- 63,
58145
- 248,
58146
- 254,
58147
- 127,
58148
- 223,
58149
- 255,
58150
- 254,
58151
- 127,
58152
- 223,
58153
- 63,
58154
- 252,
58155
- 127,
58156
- 159,
58157
- 195,
58158
- 251,
58159
- 127,
58160
- 111,
58161
- 252,
58162
- 244,
58163
- 127,
58164
- 247,
58165
- 15,
58166
- 247,
58167
- 127,
58168
- 247,
58169
- 255,
58170
- 247,
58171
- 127,
58172
- 247,
58173
- 255,
58174
- 227,
58175
- 127,
58176
- 247,
58177
- 7,
58178
- 232,
58179
- 127,
58180
- 239,
58181
- 248,
58182
- 103,
58183
- 112,
58184
- 15,
58185
- 255,
58186
- 187,
58187
- 111,
58188
- 241,
58189
- 0,
58190
- 208,
58191
- 91,
58192
- 253,
58193
- 63,
58194
- 236,
58195
- 83,
58196
- 193,
58197
- 255,
58198
- 239,
58199
- 87,
58200
- 159,
58201
- 253,
58202
- 238,
58203
- 95,
58204
- 159,
58205
- 252,
58206
- 174,
58207
- 95,
58208
- 31,
58209
- 120,
58210
- 172,
58211
- 95,
58212
- 63,
58213
- 0,
58214
- 80,
58215
- 108,
58216
- 127,
58217
- 0,
58218
- 220,
58219
- 119,
58220
- 255,
58221
- 192,
58222
- 63,
58223
- 120,
58224
- 255,
58225
- 1,
58226
- 248,
58227
- 127,
58228
- 255,
58229
- 3,
58230
- 156,
58231
- 120,
58232
- 255,
58233
- 7,
58234
- 140,
58235
- 124,
58236
- 255,
58237
- 15,
58238
- 206,
58239
- 120,
58240
- 255,
58241
- 255,
58242
- 207,
58243
- 127,
58244
- 255,
58245
- 255,
58246
- 207,
58247
- 120,
58248
- 255,
58249
- 255,
58250
- 223,
58251
- 120,
58252
- 255,
58253
- 255,
58254
- 223,
58255
- 125,
58256
- 255,
58257
- 255,
58258
- 63,
58259
- 126,
58260
- 255,
58261
- 255,
58262
- 255,
58263
- 127
58264
- ];
58265
- var BYTES_PER_ROW = Math.ceil(WIDTH / 8);
58266
- var DISPLAY_HEIGHT = Math.ceil(HEIGHT / 2);
58267
- var EFFECTS = ["typewriter", "scanline", "rain", "fade", "crt", "glitch", "dissolve"];
58268
- function getPixel(x, y) {
58269
- if (y >= HEIGHT)
58270
- return false;
58271
- const byteIndex = y * BYTES_PER_ROW + Math.floor(x / 8);
58272
- const bitIndex = x % 8;
58273
- return (BITS[byteIndex] >> bitIndex & 1) === 0;
58274
- }
58275
- function getChar(x, row) {
58276
- const upper = getPixel(x, row * 2);
58277
- const lower = getPixel(x, row * 2 + 1);
58278
- if (upper && lower)
58279
- return "█";
58280
- if (upper)
58281
- return "▀";
58282
- if (lower)
58283
- return "▄";
58284
- return " ";
58285
- }
58286
- function buildFinalGrid() {
58287
- const grid = [];
58288
- for (let row = 0;row < DISPLAY_HEIGHT; row++) {
58289
- const line = [];
58290
- for (let x = 0;x < WIDTH; x++) {
58291
- line.push(getChar(x, row));
58292
- }
58293
- grid.push(line);
58294
- }
58295
- return grid;
58296
- }
58297
-
58298
- class ArminComponent {
58299
- ui;
58300
- interval = null;
58301
- effect;
58302
- finalGrid;
58303
- currentGrid;
58304
- effectState = {};
58305
- cachedLines = [];
58306
- cachedWidth = 0;
58307
- gridVersion = 0;
58308
- cachedVersion = -1;
58309
- constructor(ui) {
58310
- this.ui = ui;
58311
- this.effect = EFFECTS[Math.floor(Math.random() * EFFECTS.length)];
58312
- this.finalGrid = buildFinalGrid();
58313
- this.currentGrid = this.createEmptyGrid();
58314
- this.initEffect();
58315
- this.startAnimation();
58316
- }
58317
- invalidate() {
58318
- this.cachedWidth = 0;
58319
- }
58320
- render(width) {
58321
- if (width === this.cachedWidth && this.cachedVersion === this.gridVersion) {
58322
- return this.cachedLines;
58323
- }
58324
- const padding = 1;
58325
- const availableWidth = width - padding;
58326
- this.cachedLines = this.currentGrid.map((row) => {
58327
- const clipped = row.slice(0, availableWidth).join("");
58328
- const padRight = Math.max(0, width - padding - clipped.length);
58329
- return ` ${theme.fg("accent", clipped)}${" ".repeat(padRight)}`;
58330
- });
58331
- const message = "ARMIN SAYS HI";
58332
- const msgPadRight = Math.max(0, width - padding - message.length);
58333
- this.cachedLines.push(` ${theme.fg("accent", message)}${" ".repeat(msgPadRight)}`);
58334
- this.cachedWidth = width;
58335
- this.cachedVersion = this.gridVersion;
58336
- return this.cachedLines;
58337
- }
58338
- createEmptyGrid() {
58339
- return Array.from({ length: DISPLAY_HEIGHT }, () => Array(WIDTH).fill(" "));
58340
- }
58341
- initEffect() {
58342
- switch (this.effect) {
58343
- case "typewriter":
58344
- this.effectState = { pos: 0 };
58345
- break;
58346
- case "scanline":
58347
- this.effectState = { row: 0 };
58348
- break;
58349
- case "rain":
58350
- this.effectState = {
58351
- drops: Array.from({ length: WIDTH }, () => ({
58352
- y: -Math.floor(Math.random() * DISPLAY_HEIGHT * 2),
58353
- settled: 0
58354
- }))
58355
- };
58356
- break;
58357
- case "fade": {
58358
- const positions = [];
58359
- for (let row = 0;row < DISPLAY_HEIGHT; row++) {
58360
- for (let x = 0;x < WIDTH; x++) {
58361
- positions.push([row, x]);
58362
- }
58363
- }
58364
- for (let i = positions.length - 1;i > 0; i--) {
58365
- const j = Math.floor(Math.random() * (i + 1));
58366
- [positions[i], positions[j]] = [positions[j], positions[i]];
58367
- }
58368
- this.effectState = { positions, idx: 0 };
58369
- break;
58370
- }
58371
- case "crt":
58372
- this.effectState = { expansion: 0 };
58373
- break;
58374
- case "glitch":
58375
- this.effectState = { phase: 0, glitchFrames: 8 };
58376
- break;
58377
- case "dissolve": {
58378
- this.currentGrid = Array.from({ length: DISPLAY_HEIGHT }, () => Array.from({ length: WIDTH }, () => {
58379
- const chars = [" ", "░", "▒", "▓", "█", "▀", "▄"];
58380
- return chars[Math.floor(Math.random() * chars.length)];
58381
- }));
58382
- const dissolvePositions = [];
58383
- for (let row = 0;row < DISPLAY_HEIGHT; row++) {
58384
- for (let x = 0;x < WIDTH; x++) {
58385
- dissolvePositions.push([row, x]);
58386
- }
58387
- }
58388
- for (let i = dissolvePositions.length - 1;i > 0; i--) {
58389
- const j = Math.floor(Math.random() * (i + 1));
58390
- [dissolvePositions[i], dissolvePositions[j]] = [dissolvePositions[j], dissolvePositions[i]];
58391
- }
58392
- this.effectState = { positions: dissolvePositions, idx: 0 };
58393
- break;
58394
- }
58395
- }
58396
- }
58397
- startAnimation() {
58398
- const fps = this.effect === "glitch" ? 60 : 30;
58399
- this.interval = setInterval(() => {
58400
- const done = this.tickEffect();
58401
- this.updateDisplay();
58402
- this.ui.requestRender();
58403
- if (done) {
58404
- this.stopAnimation();
58405
- }
58406
- }, 1000 / fps);
58407
- }
58408
- stopAnimation() {
58409
- if (this.interval) {
58410
- clearInterval(this.interval);
58411
- this.interval = null;
58412
- }
58413
- }
58414
- tickEffect() {
58415
- switch (this.effect) {
58416
- case "typewriter":
58417
- return this.tickTypewriter();
58418
- case "scanline":
58419
- return this.tickScanline();
58420
- case "rain":
58421
- return this.tickRain();
58422
- case "fade":
58423
- return this.tickFade();
58424
- case "crt":
58425
- return this.tickCrt();
58426
- case "glitch":
58427
- return this.tickGlitch();
58428
- case "dissolve":
58429
- return this.tickDissolve();
58430
- default:
58431
- return true;
58432
- }
58433
- }
58434
- tickTypewriter() {
58435
- const state = this.effectState;
58436
- const pixelsPerFrame = 3;
58437
- for (let i = 0;i < pixelsPerFrame; i++) {
58438
- const row = Math.floor(state.pos / WIDTH);
58439
- const x = state.pos % WIDTH;
58440
- if (row >= DISPLAY_HEIGHT)
58441
- return true;
58442
- this.currentGrid[row][x] = this.finalGrid[row][x];
58443
- state.pos++;
58444
- }
58445
- return false;
58446
- }
58447
- tickScanline() {
58448
- const state = this.effectState;
58449
- if (state.row >= DISPLAY_HEIGHT)
58450
- return true;
58451
- for (let x = 0;x < WIDTH; x++) {
58452
- this.currentGrid[state.row][x] = this.finalGrid[state.row][x];
58453
- }
58454
- state.row++;
58455
- return false;
58456
- }
58457
- tickRain() {
58458
- const state = this.effectState;
58459
- let allSettled = true;
58460
- this.currentGrid = this.createEmptyGrid();
58461
- for (let x = 0;x < WIDTH; x++) {
58462
- const drop = state.drops[x];
58463
- for (let row = DISPLAY_HEIGHT - 1;row >= DISPLAY_HEIGHT - drop.settled; row--) {
58464
- if (row >= 0) {
58465
- this.currentGrid[row][x] = this.finalGrid[row][x];
58466
- }
58467
- }
58468
- if (drop.settled >= DISPLAY_HEIGHT)
58469
- continue;
58470
- allSettled = false;
58471
- let targetRow = -1;
58472
- for (let row = DISPLAY_HEIGHT - 1 - drop.settled;row >= 0; row--) {
58473
- if (this.finalGrid[row][x] !== " ") {
58474
- targetRow = row;
58475
- break;
58476
- }
58477
- }
58478
- drop.y++;
58479
- if (drop.y >= 0 && drop.y < DISPLAY_HEIGHT) {
58480
- if (targetRow >= 0 && drop.y >= targetRow) {
58481
- drop.settled = DISPLAY_HEIGHT - targetRow;
58482
- drop.y = -Math.floor(Math.random() * 5) - 1;
58483
- } else {
58484
- this.currentGrid[drop.y][x] = "▓";
58485
- }
58486
- }
58487
- }
58488
- return allSettled;
58489
- }
58490
- tickFade() {
58491
- const state = this.effectState;
58492
- const pixelsPerFrame = 15;
58493
- for (let i = 0;i < pixelsPerFrame; i++) {
58494
- if (state.idx >= state.positions.length)
58495
- return true;
58496
- const [row, x] = state.positions[state.idx];
58497
- this.currentGrid[row][x] = this.finalGrid[row][x];
58498
- state.idx++;
58499
- }
58500
- return false;
58501
- }
58502
- tickCrt() {
58503
- const state = this.effectState;
58504
- const midRow = Math.floor(DISPLAY_HEIGHT / 2);
58505
- this.currentGrid = this.createEmptyGrid();
58506
- const top = midRow - state.expansion;
58507
- const bottom = midRow + state.expansion;
58508
- for (let row = Math.max(0, top);row <= Math.min(DISPLAY_HEIGHT - 1, bottom); row++) {
58509
- for (let x = 0;x < WIDTH; x++) {
58510
- this.currentGrid[row][x] = this.finalGrid[row][x];
58511
- }
58512
- }
58513
- state.expansion++;
58514
- return state.expansion > DISPLAY_HEIGHT;
58515
- }
58516
- tickGlitch() {
58517
- const state = this.effectState;
58518
- if (state.phase < state.glitchFrames) {
58519
- this.currentGrid = this.finalGrid.map((row) => {
58520
- const offset = Math.floor(Math.random() * 7) - 3;
58521
- const glitchRow = [...row];
58522
- if (Math.random() < 0.3) {
58523
- const shifted = glitchRow.slice(offset).concat(glitchRow.slice(0, offset));
58524
- return shifted.slice(0, WIDTH);
58525
- }
58526
- if (Math.random() < 0.2) {
58527
- const swapRow = Math.floor(Math.random() * DISPLAY_HEIGHT);
58528
- return [...this.finalGrid[swapRow]];
58529
- }
58530
- return glitchRow;
58531
- });
58532
- state.phase++;
58533
- return false;
58534
- }
58535
- this.currentGrid = this.finalGrid.map((row) => [...row]);
58536
- return true;
58537
- }
58538
- tickDissolve() {
58539
- const state = this.effectState;
58540
- const pixelsPerFrame = 20;
58541
- for (let i = 0;i < pixelsPerFrame; i++) {
58542
- if (state.idx >= state.positions.length)
58543
- return true;
58544
- const [row, x] = state.positions[state.idx];
58545
- this.currentGrid[row][x] = this.finalGrid[row][x];
58546
- state.idx++;
58547
- }
58548
- return false;
58549
- }
58550
- updateDisplay() {
58551
- this.gridVersion++;
58552
- }
58553
- dispose() {
58554
- this.stopAnimation();
58555
- }
58556
- }
58557
-
58558
58247
  // node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/markdown-transform.js
58559
58248
  function createMarkdownTransform(messageType, isStreaming, transformers) {
58560
58249
  return (markdown, availableWidth) => applyMarkdownTransformers(markdown, { messageType, isStreaming, availableWidth }, transformers);
@@ -59140,133 +58829,6 @@ class CustomMessageComponent extends Container {
59140
58829
  }
59141
58830
  }
59142
58831
 
59143
- // node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/daxnuts.js
59144
- var DAX_HEX = "bbbab8b9b9b6b9b8b5bcbbb8b8b7b4b7b5b2b6b5b2b8b7b4b7b6b3b6b4b1bdbcb8bab8b6bbb8b5b8b5b1bbb8b4c2bebbc1bebac0bdbabfbcb9c1bebabfbebbc0bfbcc0bdbabbb8b5c1bfbcbfbcb8bbb9b6bfbcb8c2bfbcc1bfbcbfbbb8bdb9b6b8b7b5b9b8b5b8b8b5b5b5b2b6b5b2b8b7b4b9b8b5b9b8b5b6b5b3bab8b5bcbab7bbb9b6bbb8b5bfb9b5bdb2abbcb0a8beb2aabeb5afbfbab6bebab7c0bfbcbebdbabebbb8c0bdbabfbebbc2bebbbdbab7c3c0bdc3c0bdc1bebbc2bebabfbcb8bab9b6b7b6b3b2b1aeb6b5b2b5b4b1b5b4b2b6b5b2b7b6b4b9b8b6b7b6b3bbbab7b2afaba5988fb49e90b09481b79a88b39683b09583b7a395bfb6b0c0bdbabdbbb8bebcb9c1bfbcc0bebbbdbab7bebbb8c2bfbcc0bdbac0bcb9bdb9b6c0bcb8b5b4b2b4b3b0bab9b6b9b9b6b5b4b1b5b4b1b6b5b3b9b8b5b9b8b6b9b8b6b2aeaa968174a6836eaa856eab846eaf8973ac8973b08f79b18f7ab39786b7a89dbbb3aebfbab6c2c0bdbebcb9bfbdbac3c1bdc2bebbc0bcb9bdb9b6c1bdbabfbbb8b4b3b0b9b8b5b8b7b5b4b3b1b5b4b1b8b7b4b8b7b5bab9b6bbbab7b1afad8c7a719d735ca47860a87d65a98069ae8972ae8c75af8d77aa826ba98067aa8974b39e90b6a79dbbb2adc0bdbac1bfbdbfbbb8c1bdb9bebab6c0bdb9bfbbb8c1bdbab4b2b0b7b6b4b7b6b3b4b2b0bab9b7b6b5b2b6b5b2bab9b6bab9b6958c87977663aa836bac8772b08f7aad8c77b2917db0917db0907cac8971a77d64a87f67ac8972b29887b8a89dbfbab5bfbdbac1bebac0bcb9c0bcb9c0bcb9c1bebabebab7b8b7b4b7b6b4b5b4b1b5b4b2b7b6b3b5b4b2bab9b7bab9b6b4b1ada88f7fad8973ae8d78b19684b19685b29786b69a89b29582b1917daa856ea87e66a97e66ad866ea9826baf9280b8ada6bdbbb8bebab7bfbbb8c1bdbabfbbb8bcb8b4bcb8b5b6b4b2b7b5b3b6b5b2b8b7b4b3b2afb8b7b4b6b5b2b3b2b0b3a59aab856fad8d78b0917eb19886b49b8bb49a89b39785b0917eaf8f7cab866fa77d65a77a61a87d64a9816ab08f79b5a296c1bcb8c3bfbcc2bebbbebab7bfbbb7bdbab6c2bebab8b7b4b7b6b4b6b5b3b7b6b3b6b5b2b9b8b6b4b3b1b6b1acac8f7ca9826bae8f7aaf9583b49c8cb49c8bb79d8cb59987b19380ad8e79ae8c77af8e78ac8771a3775faa826bae8972b39888bbb6b2bebbb8bfbbb8bfbbb8c0bdb9bebbb7c0bdb9b6b5b2b9b8b5b4b3b1b8b7b5b4b3b0b7b6b4b6b5b3b1a7a0aa8772a77d65a88570b49887b19b8d9c887c907a6d987f71aa907faf917daf8e7aad8c78ac8b77a8836ca9836cac8770b49b8abdb6b2c0bcb9c0bdb9bfbbb8bebab7bfbcb9bebab7b9b8b6b5b4b2b9b8b5b8b7b5b8b7b4b7b6b4b5b4b2b3a9a2ad8973a1755da9856fb398858c776a65544b776358725d526e594d9c7f6eb1907ba68672ad8e7aab8771ac856db18f79b3a092beb9b5c1bdbabdb9b5bebab7bfbbb7bebab7bcb9b6b7b6b4b6b6b3b8b7b4b5b4b2b8b6b4b7b6b3b4b3b0b4aba4a6826ba3775fb08e79b19584a88e7daa8e7db29481ad8f7c997e6da38674ac8d79ac8e7aae917f9a7c6a896a599a7c6ab3a398c1bdbabdb9b6bcb8b5bebab6bebab7bdb9b5bdb9b6b5b4b1b7b5b3b5b4b2b7b6b3b7b6b4b3b3b0b3b2b0b4aca5a7846fa97f68ae8f7bae9383b59c8bb2937fae8e79ac8b76af927eaf927eb29683b39885b2988891786a72594c6e594d978d86bdbab7bab7b3c0bcb9c0bcb9bebab7bebbb7bdb9b6b3b2b0b4b3b0b5b4b2b4b4b1b4b3b1b4b3b1b4b3b0b6ada5aa8670a57a62ad8e7ab29b8cb69d8dab856fa9826aa88069ab8771af907db49987b19684b29886b59987b39480b09787b5a9a1bcb8b5bebab7bdb9b5bebab7bfbbb8bfbbb7bbb7b4b3b2afb8b7b5b8b7b5b3b2b0b5b4b2b6b5b3b6b4b1afa299a98975a9826baf907cb39988b49a89af8e7aac8973aa856eaf8c74b1917dae907dac907db39988b29785b49785b7a090b9aca3bfbab7bcb8b5bdb9b6bcb8b4bcb8b5bdb9b5bcb8b4b5b4b2b6b5b3b4b3b0b4b3b0b9b8b5b8b6b4908b88887467aa8f7ea78976ad8973b08b74b59885b69e8eb29888b1917cb1917db1937fae907cb19686b39a8ab29886b59b8ab8a192b6aaa3b7b2afbcb8b4bcb8b5bbb7b4c0bcb9bebab7c0bcb9b6b5b2b6b5b3b4b3b0bab9b7b7b6b4b1b0ae7b716ba083709b806f716158967764b08870b29481b69b8ab69f8fb39a89b69f90b49d8db39a89b29988b49c8cb6a090b8a496baa49593867f8f8986bfbbb7bdb9b5bcb7b4bab6b3b9b5b2bab6b2b4b3b1b3b3b0b6b5b3b8b7b5b4b2b0a7a5a38f837dae917ea084725a504c63544da28370b39784b59e8db2a093a698909b918b998e8790857e95877dad998bb39c8cb5a091b9a2938d827c95908dbebab6bbb7b3bdbab7bbb7b4bdb9b6bbb7b4b4b3b0b5b4b1b8b7b5b6b5b3b8b8b5b4b2af968f8ab29a8bab9485544b483a323073655d96887f70655f61595547403e453e3c453f3d57504f655e5b90847db39c8db7a090b6a09189807aaba6a3bdb9b6c0bcb9bebab7bcb7b4bebab7bbb7b4b3b2b0b6b5b3b2b1afb7b6b4b8b7b4b5b4b1aeaba8b5a89fac998d4d44412d25244d46444e4744322b293a3230423937433a37352d2a59504c534b48524a48988a81b59f8fb19c8d827974b2afacbdb9b5bcb8b4bdb9b5bcb8b5bdb9b6bab6b2b8b7b5b5b4b2b6b6b3b9b8b5b7b6b3b6b5b2b8b6b3b9b4b1b2a9a26c64612d25242d2625312a28352d2c453d3a78675c8d7a6ea09792aea6a0615854332b29524a479f8e82b09d90a49b96c1bdb9bebab7bfbbb8bbb8b4b9b5b1b8b4b0b9b4b0b7b6b4b8b7b5b8b7b4b6b5b3b8b6b3bab9b6b9b8b5b4b3b0b7b5b2a5a29f453d3b261e1d261f1e2e2625413936857268977865b19482b5a69caca5a07c7572453d3b746963a0948cc5bfbbc0bbb8beb9b6bbb7b3bbb6b3b7b3afb8b4b0b9b5b1b7b6b3b6b5b3b5b4b2b5b4b2b7b6b3b7b6b3b8b6b3b4b2afb7b6b3b3b1ae6d6765251f1e1e18172a22212d2523443b3971625ab19888b09482a89182877e792c25243e3634766d6abeb9b5bfbbb7bebab6bcb7b3bbb6b3b9b5b1b7b3afb8b4b0b4b3b0b5b4b1b5b4b1b4b3b1b5b4b2b8b6b4b5b3b0b9b6b4b5b4b1b6b4b27f79762a2322221c1b2d2524221b1a443e3c47413f6f676281766f867971675e5a3e37352a222166605dbab7b3bdb9b5beb9b5bcb7b3bcb7b3b9b4b0bab6b2bab6b2b5b3b0b6b4b2b3b2afb7b6b3b4b4b1b4b3b0b6b4b1b5b4b1b4b3b0b9b6b29a8c8252474230292828201f181212322c2c231e1d1c16162c26252923222d26252d2523332b2a8e8885bcb8b5bcb7b3bbb6b2bcb7b3b9b4b1b9b5b1b7b2afb7b2ae7a838e9b9b9caeadacb3b2b0b3b2afb7b7b4b6b5b3b6b6b3b7b6b3b9ada4a991808e7b6f50453f2b24231a14142923221f19181d17161f18182620201d17162a22215d5654b7b3b0bbb7b3bbb6b2b8b4b0bab5b1bbb6b2bab5b1b8b4b0bab6b22c496b4c5d735f68766e727a828285929090adaba8b7b2aeb6a59ab39682a28470a387748e76674e403a1a14141d1716181211221c1c1f1918221c1b2f2827342d2c8d8884bab6b3b9b5b2bab5b1bab5b1b9b4b0bab6b2b8b4b0b9b4b0b7b2ae325e8b365f8a3a5d833f5b7a545f70646469706b6aa08f84b08e78b18e769f7e689e7f6b9e816d907766584940362d2a1c1615201b1a1a1413201a1a251e1d393331a39e9bbab5b1bcb7b3bab6b2b8b3afb8b4b0b9b4b0b9b4b1bab5b2b5b0ac3d6c9843729d44719c426e98415f805a64716f6a699d8677b1927eb3947faa89749d7a649f7f6ba487749e837186716454463f2c25231e181837302e3a33317a7471beb9b6bcb8b4bbb6b2b6b2aebab5b1b9b5b1b8b3afbab6b2b6b1adb5aeaa4877a14c7aa44e7ba345719a3a5d80586b7f767475927b6eb1927faf8e79b08e78a78169a07861a17f6aa58570a688749b83738270666f66618a8480a49e99b7b2aebab6b2bcb8b4b9b5b1b7b2aebab5b1b9b4b0b6b1aeb6b1adb2aca8b2aca84876a04a78a2517fa74771973a5d80405c7a6161677c695fac8a75b08d77b4917aaf8971ad876fa5816aa6846ea78670a98a76ac9484ab9f96b2aca8bdb8b4bcb7b3bcb8b4bcb8b4b8b3afb7b2aeb9b4b0b8b3afb8b2aeb6afabb3aeaab2aeaa4878a14b7aa34c7ba44a759b3d63873b5f825b67766f5f569c7e6caf8c77b18f79b28f78b5927caf8e78a98872aa8a76a98a76ac917fada199b7b0acb9b3afbfb9b5c1bab6bdb6b2b8b3afbab5b1b9b4b0b6afabb7b1adb3ada9b3aeaab0aba8";
59145
- var WIDTH2 = 32;
59146
- var HEIGHT2 = 32;
59147
- function parseImage() {
59148
- const pixels = [];
59149
- for (let y = 0;y < HEIGHT2; y++) {
59150
- const row = [];
59151
- for (let x = 0;x < WIDTH2; x++) {
59152
- const idx = (y * WIDTH2 + x) * 6;
59153
- const r = parseInt(DAX_HEX.slice(idx, idx + 2), 16);
59154
- const g = parseInt(DAX_HEX.slice(idx + 2, idx + 4), 16);
59155
- const b = parseInt(DAX_HEX.slice(idx + 4, idx + 6), 16);
59156
- row.push([r, g, b]);
59157
- }
59158
- pixels.push(row);
59159
- }
59160
- return pixels;
59161
- }
59162
- function rgb(r, g, b, bg = false) {
59163
- return `\x1B[${bg ? 48 : 38};2;${r};${g};${b}m`;
59164
- }
59165
- var RESET = "\x1B[0m";
59166
- function buildImage() {
59167
- const pixels = parseImage();
59168
- const lines = [];
59169
- for (let row = 0;row < HEIGHT2; row += 2) {
59170
- let line = "";
59171
- for (let x = 0;x < WIDTH2; x++) {
59172
- const top = pixels[row][x];
59173
- const bottom = pixels[row + 1]?.[x] ?? top;
59174
- line += `${rgb(bottom[0], bottom[1], bottom[2])}${rgb(top[0], top[1], top[2], true)}▄`;
59175
- }
59176
- line += RESET;
59177
- lines.push(line);
59178
- }
59179
- return lines;
59180
- }
59181
-
59182
- class DaxnutsComponent {
59183
- ui;
59184
- image;
59185
- interval = null;
59186
- tick = 0;
59187
- maxTicks = 25;
59188
- cachedLines = [];
59189
- cachedWidth = 0;
59190
- cachedTick = -1;
59191
- constructor(ui) {
59192
- this.ui = ui;
59193
- this.image = buildImage();
59194
- this.startAnimation();
59195
- }
59196
- invalidate() {
59197
- this.cachedWidth = 0;
59198
- }
59199
- startAnimation() {
59200
- this.interval = setInterval(() => {
59201
- this.tick++;
59202
- if (this.tick >= this.maxTicks) {
59203
- this.stopAnimation();
59204
- }
59205
- this.cachedWidth = 0;
59206
- this.ui.requestRender();
59207
- }, 80);
59208
- }
59209
- stopAnimation() {
59210
- if (this.interval) {
59211
- clearInterval(this.interval);
59212
- this.interval = null;
59213
- }
59214
- }
59215
- render(width) {
59216
- if (width === this.cachedWidth && this.cachedTick === this.tick) {
59217
- return this.cachedLines;
59218
- }
59219
- const t = theme;
59220
- const lines = [];
59221
- const center = (s) => {
59222
- const visible = s.replace(/\x1b\[[0-9;]*m/g, "").length;
59223
- const left = Math.max(0, Math.floor((width - visible) / 2));
59224
- return " ".repeat(left) + s;
59225
- };
59226
- lines.push("");
59227
- const revealedRows = Math.min(this.image.length, Math.floor(this.tick / this.maxTicks * (this.image.length + 3)));
59228
- for (let i = 0;i < this.image.length; i++) {
59229
- if (i < revealedRows) {
59230
- lines.push(center(this.image[i]));
59231
- } else {
59232
- if (i === revealedRows) {
59233
- const scanline = "▓".repeat(WIDTH2);
59234
- lines.push(center(rgb(100, 200, 255) + scanline + RESET));
59235
- } else {
59236
- lines.push(center(" ".repeat(WIDTH2)));
59237
- }
59238
- }
59239
- }
59240
- lines.push("");
59241
- const textPhase = Math.max(0, this.tick - this.maxTicks * 0.6);
59242
- if (textPhase > 0 || this.tick >= this.maxTicks) {
59243
- lines.push(center(t.fg("accent", "Free Kimi K2.5 via OpenCode Zen")));
59244
- lines.push(center(t.fg("success", '"Powered by daxnuts"')));
59245
- lines.push(center(t.fg("muted", "— @thdxr")));
59246
- } else {
59247
- lines.push("");
59248
- lines.push("");
59249
- lines.push("");
59250
- }
59251
- lines.push("");
59252
- if (textPhase > 2 || this.tick >= this.maxTicks) {
59253
- lines.push(center(t.fg("dim", "Try OpenCode")));
59254
- lines.push(center(t.fg("mdLink", "https://mistral.ai/news/mistral-vibe-2-0")));
59255
- } else {
59256
- lines.push("");
59257
- lines.push("");
59258
- }
59259
- lines.push("");
59260
- this.cachedLines = lines;
59261
- this.cachedWidth = width;
59262
- this.cachedTick = this.tick;
59263
- return lines;
59264
- }
59265
- dispose() {
59266
- this.stopAnimation();
59267
- }
59268
- }
59269
-
59270
58832
  // node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/earendil-announcement.js
59271
58833
  import * as fs4 from "node:fs";
59272
58834
  var BLOG_URL = "https://mariozechner.at/posts/2026-04-08-ive-sold-out/";
@@ -59304,6 +58866,23 @@ class EarendilAnnouncementComponent extends Container {
59304
58866
  }
59305
58867
  }
59306
58868
 
58869
+ // node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/easter-egg-3d.lazy.js
58870
+ function playEasterEgg3d(tui, egg) {
58871
+ if (!(tui instanceof TuiAltScreen))
58872
+ return false;
58873
+ if (tui.hasOverlay())
58874
+ return true;
58875
+ const screen = tui.getScreenLines();
58876
+ import("./easter-egg-3d-3w5c2n4c.js").then((module) => module.playEasterEgg3d(tui, screen, egg), () => {});
58877
+ return true;
58878
+ }
58879
+ function playPiLogo3d(tui, column, row) {
58880
+ playEasterEgg3d(tui, { kind: "pi-logo", column, row });
58881
+ }
58882
+ function playArmin3d(tui) {
58883
+ return playEasterEgg3d(tui, { kind: "armin" });
58884
+ }
58885
+
59307
58886
  // node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/footer.js
59308
58887
  import { isAbsolute as isAbsolute2, relative as relative4, resolve as resolve12, sep as sep7 } from "node:path";
59309
58888
  function sanitizeStatusText(text) {
@@ -59495,6 +59074,7 @@ class LoginDialogComponent extends Container {
59495
59074
  contentContainer;
59496
59075
  input;
59497
59076
  tui;
59077
+ authUrl;
59498
59078
  abortController = new AbortController;
59499
59079
  inputResolver;
59500
59080
  inputRejecter;
@@ -59550,11 +59130,8 @@ class LoginDialogComponent extends Container {
59550
59130
  showAuth(url, instructions) {
59551
59131
  this.contentContainer.clear();
59552
59132
  this.contentContainer.addChild(new Spacer(1));
59553
- const linkedUrl = `\x1B]8;;${url}\x07${url}\x1B]8;;\x07`;
59554
- this.contentContainer.addChild(new Text(theme.fg("accent", linkedUrl), 1, 0));
59555
- const clickHint = process.platform === "darwin" ? "Cmd+click to open" : "Ctrl+click to open";
59556
- const hyperlink2 = `\x1B]8;;${url}\x07${clickHint}\x1B]8;;\x07`;
59557
- this.contentContainer.addChild(new Text(theme.fg("dim", hyperlink2), 1, 0));
59133
+ this.authUrl = new AuthUrlComponent(this.tui, url);
59134
+ this.contentContainer.addChild(this.authUrl);
59558
59135
  if (instructions) {
59559
59136
  this.contentContainer.addChild(new Spacer(1));
59560
59137
  this.contentContainer.addChild(new Text(theme.fg("warning", instructions), 1, 0));
@@ -59563,6 +59140,7 @@ class LoginDialogComponent extends Container {
59563
59140
  this.tui.requestRender();
59564
59141
  }
59565
59142
  showDeviceCode(info) {
59143
+ this.authUrl = undefined;
59566
59144
  this.contentContainer.clear();
59567
59145
  this.contentContainer.addChild(new Spacer(1));
59568
59146
  const linkedUrl = `\x1B]8;;${info.verificationUri}\x07${info.verificationUri}\x1B]8;;\x07`;
@@ -59602,6 +59180,7 @@ class LoginDialogComponent extends Container {
59602
59180
  });
59603
59181
  }
59604
59182
  showDetails(lines) {
59183
+ this.authUrl = undefined;
59605
59184
  this.contentContainer.clear();
59606
59185
  this.contentContainer.addChild(new Spacer(1));
59607
59186
  for (const line of lines) {
@@ -59639,6 +59218,10 @@ class LoginDialogComponent extends Container {
59639
59218
  this.cancel();
59640
59219
  return;
59641
59220
  }
59221
+ if (this.authUrl && kb.matches(data, "app.message.copy")) {
59222
+ this.authUrl.copy();
59223
+ return;
59224
+ }
59642
59225
  this.input.handleInput(data);
59643
59226
  }
59644
59227
  }
@@ -63874,12 +63457,12 @@ class OAuthSelectorComponent extends Container {
63874
63457
  var CORAL = rgbColor(228, 138, 122);
63875
63458
  var BLUE = rgbColor(79, 142, 179);
63876
63459
  var YELLOW = rgbColor(234, 182, 93);
63877
- var RESET2 = "\x1B[0m";
63460
+ var RESET = "\x1B[0m";
63878
63461
  function piLogoLines() {
63879
63462
  const mode = theme.getColorMode();
63880
63463
  const fg = (color) => foregroundAnsi(color, mode);
63881
- const top = `${fg(CORAL)}${backgroundAnsi(BLUE, mode)}▀${RESET2}${fg(CORAL)}▀█${RESET2} `;
63882
- const bottom = `${fg(BLUE)}█▀${RESET2} ${fg(YELLOW)}█${RESET2}`;
63464
+ const top = `${fg(CORAL)}${backgroundAnsi(BLUE, mode)}▀${RESET}${fg(CORAL)}▀█${RESET} `;
63465
+ const bottom = `${fg(BLUE)}█▀${RESET} ${fg(YELLOW)}█${RESET}`;
63883
63466
  return [top, bottom];
63884
63467
  }
63885
63468
  function supportsPiLogo() {
@@ -63887,15 +63470,7 @@ function supportsPiLogo() {
63887
63470
  }
63888
63471
  function piWordmark() {
63889
63472
  const mode = theme.getColorMode();
63890
- return `${foregroundAnsi(CORAL, mode)}P${RESET2}${foregroundAnsi(YELLOW, mode)}i${RESET2}`;
63891
- }
63892
-
63893
- // node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/pi-logo-animation.lazy.js
63894
- function playPiLogoAnimation(tui, logoColumn, logoRow) {
63895
- if (!(tui instanceof TuiAltScreen) || tui.hasOverlay())
63896
- return;
63897
- const screen = tui.getScreenLines();
63898
- import("./pi-logo-animation-e9a0t68z.js").then((module) => module.playPiLogoAnimation(tui, { screen, logoColumn, logoRow }), () => {});
63473
+ return `${foregroundAnsi(CORAL, mode)}P${RESET}${foregroundAnsi(YELLOW, mode)}i${RESET}`;
63899
63474
  }
63900
63475
 
63901
63476
  // node_modules/@earendil-works/pi-coding-agent/dist/modes/interactive/components/radius-login-selector.js
@@ -65347,6 +64922,7 @@ class ToolExecutionComponent extends Container {
65347
64922
  resultRendererComponent;
65348
64923
  rendererState = {};
65349
64924
  imageComponents = [];
64925
+ imageSources = [];
65350
64926
  imageSpacers = [];
65351
64927
  toolName;
65352
64928
  toolCallId;
@@ -65361,7 +64937,6 @@ class ToolExecutionComponent extends Container {
65361
64937
  executionStarted = false;
65362
64938
  argsComplete = false;
65363
64939
  result;
65364
- convertedImages = new Map;
65365
64940
  hideComponent = false;
65366
64941
  constructor(toolName, toolCallId, args, options = {}, toolDefinition, ui, cwd) {
65367
64942
  super();
@@ -65462,40 +65037,6 @@ class ToolExecutionComponent extends Container {
65462
65037
  this.result = result;
65463
65038
  this.isPartial = isPartial;
65464
65039
  this.updateDisplay();
65465
- this.maybeConvertImagesForKitty();
65466
- }
65467
- maybeConvertImagesForKitty() {
65468
- const caps = getCapabilities();
65469
- if (caps.images !== "kitty")
65470
- return;
65471
- if (!this.result)
65472
- return;
65473
- const imageBlocks = this.result.content.filter((c) => c.type === "image");
65474
- for (let i = 0;i < imageBlocks.length; i++) {
65475
- const img = imageBlocks[i];
65476
- if (!img.data || !img.mimeType)
65477
- continue;
65478
- const sourceData = img.data;
65479
- const sourceMimeType = img.mimeType;
65480
- if (sourceMimeType === "image/png")
65481
- continue;
65482
- const cached = this.convertedImages.get(i);
65483
- if (cached?.sourceData === sourceData && cached.sourceMimeType === sourceMimeType)
65484
- continue;
65485
- const index = i;
65486
- convertToPng(sourceData, sourceMimeType).then((converted) => {
65487
- const currentImage = this.result?.content.filter((content) => content.type === "image")[index];
65488
- if (!converted || currentImage?.data !== sourceData || currentImage.mimeType !== sourceMimeType)
65489
- return;
65490
- this.convertedImages.set(index, {
65491
- sourceData,
65492
- sourceMimeType,
65493
- ...converted
65494
- });
65495
- this.updateDisplay();
65496
- this.ui.requestRender();
65497
- });
65498
- }
65499
65040
  }
65500
65041
  setExpanded(expanded) {
65501
65042
  this.expanded = expanded;
@@ -65608,10 +65149,13 @@ class ToolExecutionComponent extends Container {
65608
65149
  this.contentText.setText(this.formatToolExecution());
65609
65150
  hasContent = true;
65610
65151
  }
65152
+ const previousImages = this.imageComponents;
65153
+ const previousSources = this.imageSources;
65611
65154
  for (const img of this.imageComponents) {
65612
65155
  this.removeChild(img);
65613
65156
  }
65614
65157
  this.imageComponents = [];
65158
+ this.imageSources = [];
65615
65159
  for (const spacer of this.imageSpacers) {
65616
65160
  this.removeChild(spacer);
65617
65161
  }
@@ -65619,20 +65163,23 @@ class ToolExecutionComponent extends Container {
65619
65163
  if (this.result) {
65620
65164
  const imageBlocks = this.result.content.filter((c) => c.type === "image");
65621
65165
  const caps = getCapabilities();
65622
- for (let i = 0;i < imageBlocks.length; i++) {
65623
- const img = imageBlocks[i];
65166
+ for (const img of imageBlocks) {
65624
65167
  if (caps.images && this.showImages && img.data && img.mimeType) {
65625
- const cached = this.convertedImages.get(i);
65626
- const converted = cached?.sourceData === img.data && cached.sourceMimeType === img.mimeType ? cached : undefined;
65627
- const imageData = converted?.data ?? img.data;
65628
- const imageMimeType = converted?.mimeType ?? img.mimeType;
65629
- if (caps.images === "kitty" && imageMimeType !== "image/png")
65630
- continue;
65631
65168
  const spacer = new Spacer(1);
65632
65169
  this.addChild(spacer);
65633
65170
  this.imageSpacers.push(spacer);
65634
- const imageComponent = new Image(imageData, imageMimeType, { fallbackColor: (s) => theme.fg("toolOutput", s) }, { maxWidthCells: this.imageWidthCells });
65171
+ const source = { data: img.data, mimeType: img.mimeType, widthCells: this.imageWidthCells };
65172
+ const index = this.imageComponents.length;
65173
+ const previous = previousSources[index];
65174
+ const imageComponent = previous?.data === source.data && previous.mimeType === source.mimeType && previous.widthCells === source.widthCells ? previousImages[index] : new Image(source.data, source.mimeType, { fallbackColor: (s) => theme.fg("toolOutput", s) }, { maxWidthCells: source.widthCells });
65175
+ if (source.mimeType !== "image/png") {
65176
+ ensurePngTranscoder(() => {
65177
+ this.invalidate();
65178
+ this.ui.requestRender();
65179
+ });
65180
+ }
65635
65181
  this.imageComponents.push(imageComponent);
65182
+ this.imageSources.push(source);
65636
65183
  this.addChild(imageComponent);
65637
65184
  }
65638
65185
  }
@@ -67528,6 +67075,7 @@ class InteractiveMode {
67528
67075
  this.ui.setFocus(this.editor);
67529
67076
  this.ui.start();
67530
67077
  this.isInitialized = true;
67078
+ this.ensurePngTranscoder();
67531
67079
  this.themeController.applyFromSettings();
67532
67080
  await this.themeController.waitForTerminalColors();
67533
67081
  if (this.shouldShowStartupHeader()) {
@@ -67580,7 +67128,7 @@ ${onboarding()}`, () => `${withLogo(expandedInstructions())}
67580
67128
 
67581
67129
  ${onboarding()}`, this.getStartupExpansionState(), 1, 0);
67582
67130
  if (showLogo)
67583
- header.onLogoClick = (column, row) => playPiLogoAnimation(this.renderer, column, row);
67131
+ header.onLogoClick = (column, row) => playPiLogo3d(this.renderer, column, row);
67584
67132
  this.builtInHeader = header;
67585
67133
  this.headerContainer.addChild(new Spacer(1));
67586
67134
  this.headerContainer.addChild(this.builtInHeader);
@@ -68302,8 +67850,15 @@ ${warningLines()}`, 0, 0));
68302
67850
  applyFullscreenScrollbarSetting() {
68303
67851
  this.transcriptScrollView?.setScrollbar(this.settingsManager.getFullscreenScrollbar());
68304
67852
  }
67853
+ ensurePngTranscoder() {
67854
+ ensurePngTranscoder(() => {
67855
+ this.ui.invalidate();
67856
+ this.ui.requestRender();
67857
+ });
67858
+ }
68305
67859
  applyRuntimeSettings() {
68306
67860
  setCapabilityOverrides(this.settingsManager.getTerminalCapabilityOverrides());
67861
+ this.ensurePngTranscoder();
68307
67862
  configureHttpDispatcher(this.settingsManager.getHttpIdleTimeoutMs());
68308
67863
  this.applyFullscreenScrollbarSetting();
68309
67864
  if (this.renderer instanceof TuiAltScreen) {
@@ -68413,7 +67968,7 @@ ${warningLines()}`, 0, 0));
68413
67968
  this.renderInitialMessages();
68414
67969
  }
68415
67970
  getRegisteredToolDefinition(toolName) {
68416
- return withBuiltInRenderers(toolName, this.session.getToolDefinition(toolName));
67971
+ return this.session.extensionRunner.resolveToolRenderers(toolName, () => withBuiltInRenderers(toolName, this.session.getToolDefinition(toolName)));
68417
67972
  }
68418
67973
  getMarkdownTransformers() {
68419
67974
  return [this.mermaidMarkdownTransformer, ...this.session.extensionRunner.getMarkdownTransformers()];
@@ -70697,7 +70252,6 @@ ${packageLines}`, 1, 0));
70697
70252
  this.updateEditorBorderColor();
70698
70253
  this.showStatus(`Model: ${model.id}`);
70699
70254
  this.maybeWarnAboutAnthropicSubscriptionAuth(model);
70700
- this.checkDaxnutsEasterEgg(model);
70701
70255
  } catch (error) {
70702
70256
  this.showError(error instanceof Error ? error.message : String(error));
70703
70257
  }
@@ -70815,7 +70369,6 @@ ${packageLines}`, 1, 0));
70815
70369
  done();
70816
70370
  this.showStatus(persist ? `Default model: ${model.provider}/${model.id}` : `Model: ${model.id}`);
70817
70371
  this.maybeWarnAboutAnthropicSubscriptionAuth(model);
70818
- this.checkDaxnutsEasterEgg(model);
70819
70372
  } catch (error) {
70820
70373
  done();
70821
70374
  this.showError(error instanceof Error ? error.message : String(error));
@@ -71381,7 +70934,6 @@ ${packageLines}`, 1, 0));
71381
70934
  if (selectedModel) {
71382
70935
  this.showStatus(`${actionLabel}. Selected ${selectedModel.id}. Credentials saved to ${getAuthPath()}`);
71383
70936
  this.maybeWarnAboutAnthropicSubscriptionAuth(selectedModel);
71384
- this.checkDaxnutsEasterEgg(selectedModel);
71385
70937
  } else {
71386
70938
  this.showStatus(`${actionLabel}. Credentials saved to ${getAuthPath()}`);
71387
70939
  if (selectionError) {
@@ -72087,6 +71639,8 @@ ${theme.fg("muted", debugLogPath)}`, 1, 1));
72087
71639
  this.ui.requestRender();
72088
71640
  }
72089
71641
  handleArminSaysHi() {
71642
+ if (playArmin3d(this.renderer))
71643
+ return;
72090
71644
  this.chatContainer.addChild(new Spacer(1));
72091
71645
  this.chatContainer.addChild(new ArminComponent(this.ui));
72092
71646
  this.ui.requestRender();
@@ -72096,16 +71650,6 @@ ${theme.fg("muted", debugLogPath)}`, 1, 1));
72096
71650
  this.chatContainer.addChild(new EarendilAnnouncementComponent);
72097
71651
  this.ui.requestRender();
72098
71652
  }
72099
- handleDaxnuts() {
72100
- this.chatContainer.addChild(new Spacer(1));
72101
- this.chatContainer.addChild(new DaxnutsComponent(this.ui));
72102
- this.ui.requestRender();
72103
- }
72104
- checkDaxnutsEasterEgg(model) {
72105
- if (model.provider === "opencode" && model.id.toLowerCase().includes("kimi-k2.5")) {
72106
- this.handleDaxnuts();
72107
- }
72108
- }
72109
71653
  async handleBashCommand(command, excludeFromContext = false) {
72110
71654
  const extensionRunner = this.session.extensionRunner;
72111
71655
  let eventResult;
@@ -75080,6 +74624,14 @@ async function handlePackageCommand(args, runtimeOptions = {}) {
75080
74624
  return true;
75081
74625
  }
75082
74626
  console.log(source_default.green(`Updated ${APP_NAME} from ${VERSION} to ${selfUpdatePlan.version}`));
74627
+ if (installMethod === "npm") {
74628
+ const installerCommand = process.platform === "win32" ? 'powershell -c "irm https://pi.dev/install.ps1 | iex"' : "curl -fsSL https://pi.dev/install.sh | sh";
74629
+ console.log();
74630
+ console.log(source_default.yellow(`This npm installation of ${APP_NAME} does not pin its dependencies.`));
74631
+ console.log(source_default.yellow("Run the installer to migrate to a managed installation that does:"));
74632
+ console.log();
74633
+ console.log(` ${source_default.bold(installerCommand)}`);
74634
+ }
75083
74635
  }
75084
74636
  return true;
75085
74637
  }