waterplane 0.1.17 → 0.1.19

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 (280) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/NOTICES.md +18 -7
  3. package/README.md +46 -2
  4. package/SECURITY.md +196 -12
  5. package/node_modules/@waterplane/shared/dist/desktopfiles.d.ts +24 -2
  6. package/node_modules/@waterplane/shared/dist/desktopfiles.js +73 -3
  7. package/node_modules/@waterplane/shared/dist/desktopfiles.js.map +1 -1
  8. package/node_modules/@waterplane/shared/dist/hosts.d.ts +31 -0
  9. package/node_modules/@waterplane/shared/dist/hosts.js +46 -1
  10. package/node_modules/@waterplane/shared/dist/hosts.js.map +1 -1
  11. package/node_modules/@waterplane/shared/dist/hosturl.d.ts +55 -0
  12. package/node_modules/@waterplane/shared/dist/hosturl.js +85 -0
  13. package/node_modules/@waterplane/shared/dist/hosturl.js.map +1 -1
  14. package/node_modules/@waterplane/shared/dist/index.d.ts +4 -0
  15. package/node_modules/@waterplane/shared/dist/index.js +4 -0
  16. package/node_modules/@waterplane/shared/dist/index.js.map +1 -1
  17. package/node_modules/@waterplane/shared/dist/installrow.d.ts +6 -1
  18. package/node_modules/@waterplane/shared/dist/installrow.js +20 -1
  19. package/node_modules/@waterplane/shared/dist/installrow.js.map +1 -1
  20. package/node_modules/@waterplane/shared/dist/lanroute.d.ts +5 -0
  21. package/node_modules/@waterplane/shared/dist/lanroute.js.map +1 -1
  22. package/node_modules/@waterplane/shared/dist/pairing.d.ts +96 -2
  23. package/node_modules/@waterplane/shared/dist/pairing.js +71 -3
  24. package/node_modules/@waterplane/shared/dist/pairing.js.map +1 -1
  25. package/node_modules/@waterplane/shared/dist/pake.d.ts +131 -0
  26. package/node_modules/@waterplane/shared/dist/pake.js +272 -0
  27. package/node_modules/@waterplane/shared/dist/pake.js.map +1 -0
  28. package/node_modules/@waterplane/shared/dist/peer.d.ts +63 -0
  29. package/node_modules/@waterplane/shared/dist/peer.js +41 -0
  30. package/node_modules/@waterplane/shared/dist/peer.js.map +1 -1
  31. package/node_modules/@waterplane/shared/dist/plugin/api.d.ts +15 -0
  32. package/node_modules/@waterplane/shared/dist/plugin/version.d.ts +5 -1
  33. package/node_modules/@waterplane/shared/dist/plugin/version.js +5 -1
  34. package/node_modules/@waterplane/shared/dist/plugin/version.js.map +1 -1
  35. package/node_modules/@waterplane/shared/dist/repotwins.d.ts +47 -0
  36. package/node_modules/@waterplane/shared/dist/repotwins.js +80 -0
  37. package/node_modules/@waterplane/shared/dist/repotwins.js.map +1 -1
  38. package/node_modules/@waterplane/shared/dist/sessioncost/costwords.d.ts +7 -2
  39. package/node_modules/@waterplane/shared/dist/sessioncost/costwords.js +6 -3
  40. package/node_modules/@waterplane/shared/dist/sessioncost/costwords.js.map +1 -1
  41. package/node_modules/@waterplane/shared/dist/waiting.d.ts +64 -0
  42. package/node_modules/@waterplane/shared/dist/waiting.js +86 -0
  43. package/node_modules/@waterplane/shared/dist/waiting.js.map +1 -0
  44. package/node_modules/@waterplane/shared/dist/wire/messages/hostcore.d.ts +3 -0
  45. package/node_modules/@waterplane/shared/dist/wire/notify.d.ts +2 -0
  46. package/node_modules/@waterplane/shared/dist/wire/notify.js +2 -0
  47. package/node_modules/@waterplane/shared/dist/wire/notify.js.map +1 -1
  48. package/node_modules/@waterplane/shared/dist/wire/repo.d.ts +30 -1
  49. package/node_modules/@waterplane/shared/dist/wire/repo.js.map +1 -1
  50. package/node_modules/@waterplane/shared/dist/wire/session/context.d.ts +4 -0
  51. package/node_modules/@waterplane/shared/dist/wire/session/context.js.map +1 -1
  52. package/node_modules/@waterplane/shared/dist/wire/sysstat.d.ts +7 -0
  53. package/node_modules/@waterplane/shared/dist/wire/telemetry.d.ts +3 -0
  54. package/node_modules/@waterplane/shared/package.json +3 -0
  55. package/npm-shrinkwrap.json +30 -2
  56. package/package.json +2 -1
  57. package/packages/extensions/desktop/helper/Capture.swift +245 -0
  58. package/packages/extensions/desktop/helper/H264.swift +226 -0
  59. package/packages/extensions/desktop/helper/Info.plist +20 -0
  60. package/packages/extensions/desktop/helper/Input.swift +195 -0
  61. package/packages/extensions/desktop/helper/Jpeg.swift +81 -0
  62. package/packages/extensions/desktop/helper/PROTOCOL.md +366 -0
  63. package/packages/extensions/desktop/helper/Params.swift +133 -0
  64. package/packages/extensions/desktop/helper/Probe.swift +119 -0
  65. package/packages/extensions/desktop/helper/Protocol.swift +224 -0
  66. package/packages/extensions/desktop/helper/Request.swift +51 -0
  67. package/packages/extensions/desktop/helper/Responsibility.swift +133 -0
  68. package/packages/extensions/desktop/helper/Server.swift +334 -0
  69. package/packages/extensions/desktop/helper/Synthetic.swift +281 -0
  70. package/packages/extensions/desktop/helper/build.sh +53 -0
  71. package/packages/extensions/desktop/helper/main.swift +79 -0
  72. package/packages/extensions/desktop/helper/selftest-driver +626 -0
  73. package/packages/extensions/desktop/helper/selftest.sh +16 -0
  74. package/packages/extensions/desktop/helper-win/Capture.cs +299 -0
  75. package/packages/extensions/desktop/helper-win/H264.cs +340 -0
  76. package/packages/extensions/desktop/helper-win/Input.cs +257 -0
  77. package/packages/extensions/desktop/helper-win/Jpeg.cs +75 -0
  78. package/packages/extensions/desktop/helper-win/Main.cs +118 -0
  79. package/packages/extensions/desktop/helper-win/Native.cs +276 -0
  80. package/packages/extensions/desktop/helper-win/Params.cs +138 -0
  81. package/packages/extensions/desktop/helper-win/Protocol.cs +206 -0
  82. package/packages/extensions/desktop/helper-win/Server.cs +304 -0
  83. package/packages/extensions/desktop/helper-win/Synthetic.cs +88 -0
  84. package/packages/extensions/desktop/helper-win/build.sh +57 -0
  85. package/packages/extensions/desktop/helper-win/selftest.sh +36 -0
  86. package/packages/extensions/desktop/waterplane-plugin.json +24 -0
  87. package/packages/host/dist/agentlogs.d.ts +18 -0
  88. package/packages/host/dist/agentlogs.js +58 -0
  89. package/packages/host/dist/agentlogs.js.map +1 -0
  90. package/packages/host/dist/agents.d.ts +5 -0
  91. package/packages/host/dist/agents.js +3 -2
  92. package/packages/host/dist/agents.js.map +1 -1
  93. package/packages/host/dist/alwayson.js +1 -1
  94. package/packages/host/dist/alwayson.js.map +1 -1
  95. package/packages/host/dist/answergate.js +3 -2
  96. package/packages/host/dist/answergate.js.map +1 -1
  97. package/packages/host/dist/attentionstore.d.ts +4 -0
  98. package/packages/host/dist/attentionstore.js +17 -0
  99. package/packages/host/dist/attentionstore.js.map +1 -1
  100. package/packages/host/dist/auth.d.ts +28 -0
  101. package/packages/host/dist/auth.js +65 -2
  102. package/packages/host/dist/auth.js.map +1 -1
  103. package/packages/host/dist/cli/pair.d.ts +4 -0
  104. package/packages/host/dist/cli/pair.js +18 -5
  105. package/packages/host/dist/cli/pair.js.map +1 -1
  106. package/packages/host/dist/composer.d.ts +6 -0
  107. package/packages/host/dist/composer.js +7 -1
  108. package/packages/host/dist/composer.js.map +1 -1
  109. package/packages/host/dist/ctxlog/ctxagents.d.ts +0 -29
  110. package/packages/host/dist/ctxlog/ctxagents.js +41 -8
  111. package/packages/host/dist/ctxlog/ctxagents.js.map +1 -1
  112. package/packages/host/dist/der.d.ts +19 -0
  113. package/packages/host/dist/der.js +51 -0
  114. package/packages/host/dist/der.js.map +1 -0
  115. package/packages/host/dist/doctor.d.ts +2 -0
  116. package/packages/host/dist/doctor.js +10 -2
  117. package/packages/host/dist/doctor.js.map +1 -1
  118. package/packages/host/dist/extensions/desktop/host/auto.d.mts +71 -0
  119. package/packages/host/dist/extensions/desktop/host/auto.mjs +114 -0
  120. package/packages/host/dist/extensions/desktop/host/auto.mjs.map +1 -0
  121. package/packages/host/dist/extensions/desktop/host/desktop.d.mts +51 -0
  122. package/packages/host/dist/extensions/desktop/host/desktop.mjs +113 -0
  123. package/packages/host/dist/extensions/desktop/host/desktop.mjs.map +1 -0
  124. package/packages/host/dist/extensions/desktop/host/helperbin.d.mts +71 -0
  125. package/packages/host/dist/extensions/desktop/host/helperbin.mjs +160 -0
  126. package/packages/host/dist/extensions/desktop/host/helperbin.mjs.map +1 -0
  127. package/packages/host/dist/extensions/desktop/host/index.d.mts +4 -0
  128. package/packages/host/dist/extensions/desktop/host/index.mjs +88 -0
  129. package/packages/host/dist/extensions/desktop/host/index.mjs.map +1 -0
  130. package/packages/host/dist/extensions/desktop/host/knobs.d.mts +52 -0
  131. package/packages/host/dist/extensions/desktop/host/knobs.mjs +81 -0
  132. package/packages/host/dist/extensions/desktop/host/knobs.mjs.map +1 -0
  133. package/packages/host/dist/extensions/desktop/host/probe.d.mts +57 -0
  134. package/packages/host/dist/extensions/desktop/host/probe.mjs +119 -0
  135. package/packages/host/dist/extensions/desktop/host/probe.mjs.map +1 -0
  136. package/packages/host/dist/extensions/desktop/host/records.d.mts +40 -0
  137. package/packages/host/dist/extensions/desktop/host/records.mjs +101 -0
  138. package/packages/host/dist/extensions/desktop/host/records.mjs.map +1 -0
  139. package/packages/host/dist/extensions/desktop/host/session.d.mts +86 -0
  140. package/packages/host/dist/extensions/desktop/host/session.mjs +318 -0
  141. package/packages/host/dist/extensions/desktop/host/session.mjs.map +1 -0
  142. package/packages/host/dist/extensions/desktop/host/setup.d.mts +28 -0
  143. package/packages/host/dist/extensions/desktop/host/setup.mjs +217 -0
  144. package/packages/host/dist/extensions/desktop/host/setup.mjs.map +1 -0
  145. package/packages/host/dist/extensions/desktop/host/status.d.mts +27 -0
  146. package/packages/host/dist/extensions/desktop/host/status.mjs +62 -0
  147. package/packages/host/dist/extensions/desktop/host/status.mjs.map +1 -0
  148. package/packages/host/dist/extensions/desktop/shared/wire.d.mts +206 -0
  149. package/packages/host/dist/extensions/desktop/shared/wire.mjs +174 -0
  150. package/packages/host/dist/extensions/desktop/shared/wire.mjs.map +1 -0
  151. package/packages/host/dist/git.d.ts +23 -6
  152. package/packages/host/dist/git.js +54 -26
  153. package/packages/host/dist/git.js.map +1 -1
  154. package/packages/host/dist/gitfetchfail.d.ts +24 -0
  155. package/packages/host/dist/gitfetchfail.js +62 -0
  156. package/packages/host/dist/gitfetchfail.js.map +1 -0
  157. package/packages/host/dist/gitlog.d.ts +4 -0
  158. package/packages/host/dist/gitlog.js +8 -3
  159. package/packages/host/dist/gitlog.js.map +1 -1
  160. package/packages/host/dist/gitnotify.d.ts +7 -1
  161. package/packages/host/dist/gitnotify.js +61 -1
  162. package/packages/host/dist/gitnotify.js.map +1 -1
  163. package/packages/host/dist/healthwatch.js +1 -1
  164. package/packages/host/dist/healthwatch.js.map +1 -1
  165. package/packages/host/dist/host.js +5 -1
  166. package/packages/host/dist/host.js.map +1 -1
  167. package/packages/host/dist/hoststore.js +4 -4
  168. package/packages/host/dist/hoststore.js.map +1 -1
  169. package/packages/host/dist/lantls.d.ts +145 -0
  170. package/packages/host/dist/lantls.js +337 -0
  171. package/packages/host/dist/lantls.js.map +1 -0
  172. package/packages/host/dist/main.js +10 -2
  173. package/packages/host/dist/main.js.map +1 -1
  174. package/packages/host/dist/net.d.ts +7 -0
  175. package/packages/host/dist/net.js +9 -0
  176. package/packages/host/dist/net.js.map +1 -1
  177. package/packages/host/dist/origin.d.ts +4 -0
  178. package/packages/host/dist/origin.js +6 -0
  179. package/packages/host/dist/origin.js.map +1 -1
  180. package/packages/host/dist/pair.d.ts +54 -5
  181. package/packages/host/dist/pair.js +139 -34
  182. package/packages/host/dist/pair.js.map +1 -1
  183. package/packages/host/dist/pairpake.d.ts +58 -0
  184. package/packages/host/dist/pairpake.js +208 -0
  185. package/packages/host/dist/pairpake.js.map +1 -0
  186. package/packages/host/dist/passive.d.ts +2 -0
  187. package/packages/host/dist/passive.js +4 -0
  188. package/packages/host/dist/passive.js.map +1 -1
  189. package/packages/host/dist/peers/client.d.ts +3 -1
  190. package/packages/host/dist/peers/client.js +4 -0
  191. package/packages/host/dist/peers/client.js.map +1 -1
  192. package/packages/host/dist/peers/routes.d.ts +6 -1
  193. package/packages/host/dist/peers/routes.js +39 -0
  194. package/packages/host/dist/peers/routes.js.map +1 -1
  195. package/packages/host/dist/permmode.js +3 -3
  196. package/packages/host/dist/plugins/pluginapi.js +13 -0
  197. package/packages/host/dist/plugins/pluginapi.js.map +1 -1
  198. package/packages/host/dist/plugins/pluginregistry.d.ts +6 -0
  199. package/packages/host/dist/plugins/pluginregistry.js.map +1 -1
  200. package/packages/host/dist/prepushcheck.d.ts +34 -0
  201. package/packages/host/dist/prepushcheck.js +157 -0
  202. package/packages/host/dist/prepushcheck.js.map +1 -0
  203. package/packages/host/dist/prs.js +2 -1
  204. package/packages/host/dist/prs.js.map +1 -1
  205. package/packages/host/dist/reponames.d.ts +26 -0
  206. package/packages/host/dist/reponames.js +119 -0
  207. package/packages/host/dist/reponames.js.map +1 -0
  208. package/packages/host/dist/repos.js +13 -0
  209. package/packages/host/dist/repos.js.map +1 -1
  210. package/packages/host/dist/routes/apigitcheck.d.ts +2 -0
  211. package/packages/host/dist/routes/apigitcheck.js +29 -0
  212. package/packages/host/dist/routes/apigitcheck.js.map +1 -0
  213. package/packages/host/dist/routes/apihost.js +28 -1
  214. package/packages/host/dist/routes/apihost.js.map +1 -1
  215. package/packages/host/dist/routes/apiio.js +2 -1
  216. package/packages/host/dist/routes/apiio.js.map +1 -1
  217. package/packages/host/dist/routes/apirepofiles.js +2 -1
  218. package/packages/host/dist/routes/apirepofiles.js.map +1 -1
  219. package/packages/host/dist/routes/apisystem.js +21 -3
  220. package/packages/host/dist/routes/apisystem.js.map +1 -1
  221. package/packages/host/dist/server/http.js +31 -5
  222. package/packages/host/dist/server/http.js.map +1 -1
  223. package/packages/host/dist/server/intentEvents.js +3 -2
  224. package/packages/host/dist/server/intentEvents.js.map +1 -1
  225. package/packages/host/dist/server/plugins.d.ts +13 -0
  226. package/packages/host/dist/server/plugins.js +26 -0
  227. package/packages/host/dist/server/plugins.js.map +1 -1
  228. package/packages/host/dist/server/sessionEvents.js +10 -9
  229. package/packages/host/dist/server/sessionEvents.js.map +1 -1
  230. package/packages/host/dist/server/wsops.js +3 -1
  231. package/packages/host/dist/server/wsops.js.map +1 -1
  232. package/packages/host/dist/sessionSearch.js +3 -1
  233. package/packages/host/dist/sessionSearch.js.map +1 -1
  234. package/packages/host/dist/sessions/apiretry.d.ts +14 -0
  235. package/packages/host/dist/sessions/apiretry.js +28 -2
  236. package/packages/host/dist/sessions/apiretry.js.map +1 -1
  237. package/packages/host/dist/sessions/core.d.ts +5 -0
  238. package/packages/host/dist/sysstat.js +10 -1
  239. package/packages/host/dist/sysstat.js.map +1 -1
  240. package/packages/host/dist/tokenscan.d.ts +4 -2
  241. package/packages/host/dist/tokenscan.js +5 -3
  242. package/packages/host/dist/tokenscan.js.map +1 -1
  243. package/packages/host/dist/transcript/transcriptparse.js +5 -2
  244. package/packages/host/dist/transcript/transcriptparse.js.map +1 -1
  245. package/packages/host/dist/turnagents.d.ts +8 -1
  246. package/packages/host/dist/turnagents.js +49 -16
  247. package/packages/host/dist/turnagents.js.map +1 -1
  248. package/packages/host/dist/updatekey.d.ts +22 -0
  249. package/packages/host/dist/updatekey.js +140 -0
  250. package/packages/host/dist/updatekey.js.map +1 -0
  251. package/packages/host/dist/webbundle.d.ts +15 -6
  252. package/packages/host/dist/webbundle.js +44 -7
  253. package/packages/host/dist/webbundle.js.map +1 -1
  254. package/packages/host/dist/wincpu.d.ts +13 -0
  255. package/packages/host/dist/wincpu.js +101 -0
  256. package/packages/host/dist/wincpu.js.map +1 -0
  257. package/packages/host/package.json +2 -1
  258. package/packages/web/dist/assets/demo-iVbE6mpm.js +26 -0
  259. package/packages/web/dist/assets/icons-D8RlmSLR.js +1 -0
  260. package/packages/web/dist/assets/index-DiZysQBa.css +1 -0
  261. package/packages/web/dist/assets/index-NA--kuEl.js +170 -0
  262. package/packages/web/dist/assets/noble-DV-r0OkE.js +1 -0
  263. package/packages/web/dist/assets/{react-CoSyT_xY.js → react-CjmvHigY.js} +2 -2
  264. package/packages/web/dist/assets/rolldown-runtime-4tVxZq34.js +1 -0
  265. package/packages/web/dist/assets/shared-CsHyApn-.js +51 -0
  266. package/packages/web/dist/assets/sheets-CDv71Sfe.js +256 -0
  267. package/packages/web/dist/assets/xterm-BHsKrDzh.js +16 -0
  268. package/packages/web/dist/build-id.txt +1 -1
  269. package/packages/web/dist/buildstamp.json +1 -1
  270. package/packages/web/dist/index.html +9 -9
  271. package/packages/web/dist/sw.js +2 -2
  272. package/release.json +7 -3
  273. package/packages/web/dist/assets/demo-DkCtg-SJ.js +0 -26
  274. package/packages/web/dist/assets/icons-B48F-4nA.js +0 -1
  275. package/packages/web/dist/assets/index-BYRdfW3T.js +0 -170
  276. package/packages/web/dist/assets/index-DcZrEQNl.css +0 -1
  277. package/packages/web/dist/assets/rolldown-runtime-BpQH8Ho1.js +0 -1
  278. package/packages/web/dist/assets/shared-DjRRLGfw.js +0 -50
  279. package/packages/web/dist/assets/sheets-BGN7Cs73.js +0 -248
  280. package/packages/web/dist/assets/xterm-C8zLTNGk.js +0 -16
@@ -0,0 +1,51 @@
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/noble-DV-r0OkE.js","assets/rolldown-runtime-4tVxZq34.js"])))=>i.map(i=>d[i]);
2
+ var e=[`Sun`,`Mon`,`Tue`,`Wed`,`Thu`,`Fri`,`Sat`];function t(e){return e.kind===`window`?`window`:`clock`}function n(e){return e.kind!==`once`&&e.oneShot!==!0}function r(e,t,n,r,i){let a=n.tz||i,o=n.hours?a?{hours:n.hours,tz:a}:{hours:n.hours}:{};if(e===`clock`&&!t)return{kind:`once`,at:n.kind===`once`?n.at??r+36e5:r+36e5,offsetMin:0,...o};if(e===`clock`){let e=n.kind===`weekly`?n:void 0;return{kind:`weekly`,days:e?.days??[],hour:e?.hour??18,minute:e?.minute??0,tz:e?.tz||i,offsetMin:n.offsetMin??0,...t?{}:{oneShot:!0},...o}}let s=n.kind===`window`?n:void 0;return{kind:`window`,window:s?.window??`session`,...s?.periodId?{periodId:s.periodId}:{},edge:s?.edge??`before`,offsetMin:s?.offsetMin??Math.min(0,n.offsetMin??-60),...s?.minPctLeft==null?{}:{minPctLeft:s.minPctLeft},...s?.guardWindow?{guardWindow:s.guardWindow}:{},...t?{}:{oneShot:!0},...o}}function i(e,t){if(!t)return null;if(e.periodId){let n=t.periodResetAt?.[e.periodId];return typeof n==`number`&&n>0?n:null}let n=e.window===`weekly`?t.weeklyResetAt:t.sessionResetAt;return typeof n==`number`&&n>0?n:null}var a=e=>e.periodId??(e.window===`weekly`?`weekly`:`session`),o=e=>e.window===`weekly`?`weekly`:`session`;function s(e){return e.kind===`build`?`run build ${e.buildId}`:e.text}function c(e,t,n){return e.filter(e=>e.action.kind===`build`&&e.action.repoDir===t&&e.action.buildId===n)}function l(e,t){try{let n=new Intl.DateTimeFormat(`en-US`,{timeZone:e,hourCycle:`h23`,year:`numeric`,month:`2-digit`,day:`2-digit`,hour:`2-digit`,minute:`2-digit`,second:`2-digit`}),r={};for(let e of n.formatToParts(new Date(t)))e.type!==`literal`&&(r[e.type]=Number(e.value));return Date.UTC(r.year,r.month-1,r.day,r.hour,r.minute,r.second)-t}catch{return null}}function u(e,t,n,r,i,a){if(!a)return new Date(e,t,n,r,i,0,0).getTime();let o=Date.UTC(e,t,n,r,i,0),s=l(a,o);return s==null?new Date(e,t,n,r,i,0,0).getTime():(s=l(a,o-s)??s,o-s)}function d(e,t){let n=e?l(e,t):null,r=new Date(n==null?t:t+n);return n==null?{y:r.getFullYear(),mo:r.getMonth(),d:r.getDate()}:{y:r.getUTCFullYear(),mo:r.getUTCMonth(),d:r.getUTCDate()}}function f(e,t){let n=e?l(e,t):null,r=new Date(n==null?t:t+n);return n==null?r.getHours()*60+r.getMinutes():r.getUTCHours()*60+r.getUTCMinutes()}function p(e,t){let n=e.hours;if(!n)return!0;let r=f(e.tz||null,t);return n.from<=n.to?r>=n.from&&r<n.to:r>=n.from||r<n.to}function m(e,t){if(!e.hours||p(e,t))return t;let n=e.tz||null,{y:r,mo:i,d:a}=d(n,t),o=Math.floor(e.hours.from/60),s=e.hours.from%60;for(let e=0;e<=2;e++){let c=u(r,i,a+e,o,s,n);if(c>=t)return c}return null}function h(e){let t=e.hours;if(!t)return null;let n=e=>`${String(Math.floor(e/60)).padStart(2,`0`)}:${String(e%60).padStart(2,`0`)}`;return`${n(t.from)}–${n(t.to)}`}function g(e){return e.tz?` ${e.tz}`:` host clock`}function _(e,t,n){let r=(e.offsetMin??0)*6e4;if(e.kind===`window`){let a=i(e,n);if(a==null)return null;let o=a+(e.edge===`after`?Math.max(0,r):r);return o>t?o:null}if(e.kind===`once`){let n=(e.at??0)+r;return n>t?n:null}let a=e.hour??0,o=e.minute??0,s=e.tz||null,c=e.days?.length?e.days:null,l=d(s,t);for(let e=-2;e<=9;e++){let n=new Date(Date.UTC(l.y,l.mo,l.d+e)).getUTCDay();if(c&&!c.includes(n))continue;let i=u(l.y,l.mo,l.d+e,a,o,s)+r;if(i>t)return i}return null}function ee(e,t){return n(e.rule)||e.nextAt!=null?!1:e.rule.kind===`once`?_(e.rule,t)===null:e.nextAt===void 0||e.enabled===!0?!1:e.lastOccurrence!=null}function te(e,t){return!e.rule||!ee({rule:e.rule,nextAt:e.nextAt,lastOccurrence:e.lastOccurrence,enabled:e.enabled},t)}var ne=`that instant has passed and a one-off cannot be re-armed — run it now, edit it, or post it again`;function re(e,t,n=120){let r=(e??``).trim();if(!r)return null;let i=(t??``).trim();return i&&(i.startsWith(r)||r.startsWith(i.slice(0,n)))?null:r}function ie(e){let t=Math.abs(e),n=Math.floor(t/60),r=t%60;return n&&r?`${n}h ${r}m`:n?`${n}h`:`${r}m`}function ae(e){return`${String(e.hour??0).padStart(2,`0`)}:${String(e.minute??0).padStart(2,`0`)}`}function oe(t){let n=t.offsetMin??0,r=n<0?`, ${ie(n)} before`:n>0?`, ${ie(n)} after`:``,i=h(t),s=i?`, only ${i}`:``;if(t.kind===`once`){let e=t.at??0;return`once · ${new Date(e).toLocaleString(void 0,{weekday:`short`,day:`numeric`,month:`short`,hour:`2-digit`,minute:`2-digit`})}${r}${s}`}let c=t.oneShot===!0?`once · `:``;if(t.kind===`window`){let e=a(t),r=e===`weekly`?`the weekly window`:e===`session`?`the session window`:e===`rolling30d`?`the rolling 30 days`:`the ${e} period`,i=t.guardWindow&&t.guardWindow!==o(t)?t.guardWindow:void 0,l=i===`weekly`?`of the week `:i===`session`?`of the session window `:``,u=t.minPctLeft!=null&&(t.edge!==`after`||i)?`, only if ${t.minPctLeft}% ${l}is left${t.oneShot===!0?` — else the next reset`:``}`:``;return t.edge===`after`?`${c}${n>0?`${ie(n)} after ${r} resets`:`right after ${r} resets`}${u}${s}`:`${c}${n?ie(n):`0m`} before ${r} resets${u}${s}`}let l=t.oneShot===!0?`next`:`every`;return`${c}${t.days?.length?`${l} ${t.days.map(t=>e[t]??`?`).join(` `)}`:`${l} day`} · ${ae(t)}${t.tz?` ${t.tz}`:``}${r}${s}`}var se=e=>typeof e==`number`&&Number.isFinite(e)&&e>=0;function ce(e){if(e===null)return[];if(!e||typeof e!=`object`||Array.isArray(e))return[`the session spend must be an object (or null for cannot say)`];let t=e,n=[];se(t.at)||n.push("the session spend has no `at` (when it was read)");for(let e of[`tok`,`agentTok`,`usd`,`agentUsd`])t[e]!==void 0&&!se(t[e])&&n.push(`spend.${e} is ${JSON.stringify(t[e])}; a stated figure is a finite number ≥ 0, and an unknown one is left out`);if(t.native!==void 0){let e=t.native;!e||typeof e!=`object`||Array.isArray(e)?n.push(`spend.native must be { amount, unit, agentAmount? }`):(se(e.amount)||n.push(`spend.native.amount is ${JSON.stringify(e.amount)}; it must be a finite number ≥ 0`),typeof e.unit!=`string`||!e.unit.trim()?n.push(`spend.native.unit must name the unit (the backend's own word, never converted)`):/^\s*(usd|\$|dollars?)\s*$/i.test(e.unit)&&n.push("spend.native is for a unit that is not dollars; dollars the CLI states go in `usd`"),e.agentAmount!==void 0&&!se(e.agentAmount)&&n.push(`spend.native.agentAmount is ${JSON.stringify(e.agentAmount)}; it must be a finite number ≥ 0`))}return n}function le(e,t){try{let n={};for(let r of new Intl.DateTimeFormat(`en-US`,{timeZone:e,hourCycle:`h23`,year:`numeric`,month:`2-digit`,day:`2-digit`,hour:`2-digit`,minute:`2-digit`,second:`2-digit`}).formatToParts(new Date(t)))r.type!==`literal`&&(n[r.type]=Number(r.value));return Date.UTC(n.year,n.month-1,n.day,n.hour,n.minute,n.second)-t}catch{return null}}function ue(e,t,n,r,i,a){let o=Date.UTC(e,t,n,r,i,0),s=le(a,o);if(s==null)return new Date(e,t,n,r,i,0,0).getTime();let c=o-s,l=o-(le(a,c)??s),u=e=>{let t=le(a,e);return t==null?null:e+t};return u(l)===o?l:u(c)===o?c:Math.max(c,l)}function de(e,t){try{let n={};for(let r of new Intl.DateTimeFormat(`en-US`,{timeZone:e,year:`numeric`,month:`2-digit`,day:`2-digit`}).formatToParts(new Date(t)))r.type!==`literal`&&(n[r.type]=Number(r.value));if(Number.isFinite(n.year)&&Number.isFinite(n.month)&&Number.isFinite(n.day))return{y:n.year,mo:n.month-1,d:n.day}}catch{}let n=new Date(t);return{y:n.getFullYear(),mo:n.getMonth(),d:n.getDate()}}var fe=`session`,pe=`weekly`,me=864e5,he=(e,t)=>new Date(Date.UTC(e,t+1,0)).getUTCDate();function ge(e,t){let n=new Date(Date.UTC(e,t,1));return{y:n.getUTCFullYear(),mo:n.getUTCMonth()}}function _e(e,t,n,r){let i=ge(e,t);return ue(i.y,i.mo,Math.min(n,he(i.y,i.mo)),0,0,r)}function ve(e,t){let{y:n,mo:r,d:i}=de(e.tz,t),a,o=0;if(e.cycle===`month`){let t=Math.min(31,Math.max(1,Math.trunc(e.anchorDay??1)));o=i>=Math.min(t,he(n,r))?0:-1,a=i=>_e(n,r+o+i,t,e.tz)}else if(e.cycle===`week`){let t=(new Date(Date.UTC(n,r,i)).getUTCDay()-Math.min(6,Math.max(0,Math.trunc(e.startDow??0)))+7)%7;a=a=>ue(n,r,i-t+7*a,0,0,e.tz)}else a=t=>ue(n,r,i+t,0,0,e.tz);let s=0;for(let e=0;e<3&&t<a(s);e++)s--;for(let e=0;e<3&&t>=a(s+1);e++)s++;return{start:a(s),resetAt:a(s+1),active:!0}}function ye(e,t,n){if(e.kind===`calendar`)return ve(e,t);if(e.kind===`span`)return t<e.from?{start:e.from,resetAt:e.to,active:!1}:t>=e.to?{start:e.from,resetAt:null,active:!1}:{start:e.from,resetAt:e.to,active:!0};if(!e.scraped)return{start:t-e.lenMs,resetAt:null,active:!0};let r=n?.resetAt,i=typeof r==`number`&&Number.isFinite(r)&&r>t?r:null;return{start:i==null?t-e.lenMs:i-e.lenMs,resetAt:i,active:!0}}function be(e,t,n){return e.map(e=>({period:e,...ye(e,t,n?.[e.id])}))}var v=e=>typeof e==`number`&&Number.isFinite(e);function xe(e,t,n,r){return!v(e)||!v(t)||!v(r)||!v(n)||n<=t?null:e*Math.min(1,Math.max(0,(r-t)/(n-t)))}function Se(e,t,n,r){return!v(e)||!v(t)||!v(n)||!v(r)||n<=r?null:Math.max(0,e-t)/Math.max(1,(n-r)/me)}function Ce(e,t,n,r){if(!v(e)||!v(t)||!v(n)||!v(r)||n<=t)return null;let i=n-t,a=r-t;return a<i*.1||a>i?null:i/a*e}var we=15e5;function Te(e){let t=[{periodId:fe,max:e.sessionMax,unit:`pct`}];e.weeklyMax!=null&&t.push({periodId:pe,max:e.weeklyMax,unit:`pct`});for(let n of e.ceilings??[])n.periodId!==`session`&&n.periodId!==`weekly`&&t.push(n);return t}function Ee(e,t){return Oe(e,[...Te(e).filter(e=>e.periodId!==t.periodId),t])}function De(e,t){let n=Te(e).filter(e=>e.periodId!==t);return Oe(e,t===`session`?[...n,{periodId:t,max:100,unit:`pct`}]:n)}function Oe(e,t){let n=t.find(e=>e.periodId===fe),r=t.find(e=>e.periodId===pe);return{...e,ceilings:t,sessionMax:n?n.max:100,weeklyMax:r?r.max:null}}function ke(e,t,n=!1){return`${n?`timed for right after the weekly reset, so it starts only while the new week is under`:`leftover from a week that has reset — it was let past that week's budget and did not start in time, so it runs only while this week is under`} ${e.max}% (${e.pct}% used)`+Ne(e.resetAt,t).replace(` — resumes`,` — next chance`)}function Ae(e){return e===`rolling30d`?`rolling 30 days`:e===`weekly`?`weekly window`:!e||e===`session`?`session window`:e}var je=e=>e==null?`?`:`$${e>=100?Math.round(e):e.toFixed(2).replace(/\.00$/,``)}`;function Me(e){if(e.unit===`usd`){let t=Ae(e.which);if(e.state===`ok`)return e.pct==null?`under the usage budget`:`${je(e.pct)} spent this ${t} (budget ${je(e.max)})`;if(e.state===`over`)return`paused - ${je(e.pct)} spent this ${t}, over the ${je(e.max)} budget`}let t=e.which===`weekly`?`weekly`:`session`;switch(e.state){case`off`:return`usage budget is off`;case`unset`:return`usage budget is on, but no ceiling is set`;case`unknown`:return`${e.why??`usage could not be read`} — the budget is not holding anything back`;case`ok`:return e.pct==null?`under the usage budget`:`${e.pct}% of the ${t} window used (budget ${e.max}%)`;case`over`:return`paused — ${e.pct}% of the ${t} window used, over the ${e.max}% budget`;default:return`the usage budget is in a state this app version cannot name`}}function Ne(e,t){if(e==null||!Number.isFinite(e))return``;let n=new Date(e),r=n.toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`});return n.toDateString()===new Date(t).toDateString()?` — resumes ${r}`:` — resumes ${n.toLocaleDateString([],{weekday:`short`})} ${r}`}var Pe=e=>({blocked:!0,state:`over`,which:e.which,pct:e.pct,max:e.max,resumeAt:e.resetAt,...e.unit?{unit:e.unit}:{}});function Fe(e,t){return Me(Pe(e))+Ne(e.resetAt,t)}function Ie(e,t,n=e.which){return`lifted for this row at its time — it is timed before ${n===e.which?`that window`:`the ${n} window`} resets, and a ceiling only saves allowance for later in the window; there is no later · held only until then: ${Me(Pe(e)).replace(/^paused — /,``)}`}function Le(e,t,n){return`${Fe(e,n)} · exempt from the ${t} ceiling, not from this one`}var Re=54e5;function ze(e,t,n){return n||e==null||!(e>0)||!Number.isFinite(t)?null:t-e>=Re}var Be=`2026-10-09`,Ve=.1,He=1.25,Ue={"claude-fable-5-1":{input:10,output:50,cacheRead:.25},"claude-mythos-5-1":{input:10,output:50},"claude-fable-5":{input:10,output:50},"claude-mythos-5":{input:10,output:50},"claude-opus-5-5":{input:4,output:20,cacheRead:.2},"claude-opus-5":{input:5,output:25},"claude-opus-4-8":{input:5,output:25},"claude-opus-4-7":{input:5,output:25},"claude-opus-4-6":{input:5,output:25},"claude-opus-4-5":{input:5,output:25},"claude-sonnet-5-5":{input:2,output:10},"claude-sonnet-5":{input:2,output:10},"claude-sonnet-4-6":{input:3,output:15},"claude-sonnet-4-5":{input:3,output:15},"claude-haiku-5-5":{input:.1,output:.5},"claude-haiku-4-5":{input:1,output:5}};function We(e){if(!e)return null;let t=e.trim().toLowerCase();return!t||!t.startsWith(`claude-`)?null:(t=t.replace(/(\[1m\]|-1m)$/,``),t=t.replace(/-\d{8}$/,``),t)}function Ge(e,t){let n=We(e);if(!n)return null;let r=Ue[n];if(!r)return null;let i=r.intro&&t&&t<=r.intro.until?r.intro:r;return i.cacheRead==null?{input:i.input,output:i.output}:{input:i.input,output:i.output,cacheRead:i.cacheRead}}function Ke(e){return Ge(e)!=null}function y(){return{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}}function b(e,t){return e.input+=t.input,e.output+=t.output,e.cacheRead+=t.cacheRead,e.cacheWrite+=t.cacheWrite,e.total+=t.total,e}function qe(e,t,n){let r=Ge(t,n);if(!r)return null;let i=(e,t)=>e/1e6*t,a=Math.max(0,Math.min(e.cacheWrite1h,e.cacheWrite)),o=Math.max(0,e.cacheWrite-a),s=r.cacheRead??r.input*.1,c={input:i(e.input,r.input),output:i(e.output,r.output),cacheRead:i(e.cacheRead,s),cacheWrite:i(o,r.input*He)+i(a,r.input*2),total:0};return c.total=c.input+c.output+c.cacheRead+c.cacheWrite,c}function x(e){if(!Number.isFinite(e))return`—`;if(e===0)return`$0`;let t=Math.abs(e);return t<.01?`$${e.toFixed(4)}`:t<1e3?`$${e.toFixed(2)}`:`$${Math.round(e).toLocaleString()}`}function Je(e){if(!Number.isFinite(e))return`—`;let t=Math.abs(e);return t>=1e3?`$${(e/1e3).toFixed(t>=1e4?0:1).replace(/\.0$/,``)}k`:t>=10?`$${Math.round(e)}`:t===0?`$0`:t<.01?`<$0.01`:`$${e.toFixed(2)}`}function Ye(e,t){if(t===`USD`)return x(e);if(!Number.isFinite(e))return`—`;if(e===0)return`0 ${t}`;let n=Math.abs(e);return`${n<.01?e.toFixed(4):n<1e3?e.toFixed(2):Math.round(e).toLocaleString()} ${t}`}function Xe(e){if(!e)return!1;let t=e.trim().toLowerCase();return t===`<synthetic>`||/(^|[./:@])(anthropic\.)?claude-/.test(t)}function Ze(e){return e>=10?`${Math.round(e)}×`:`${(Math.round(e*10)/10).toFixed(1)}×`}function S(e){return e>=1e6?`${(e/1e6).toFixed(e>=1e7?0:1)}M`:e>=1e3?`${Math.round(e/1e3)}k`:String(Math.round(e))}function Qe(e,t){let n=t!=null&&t>0?` — ${S(t)} of it in subagents`:``;return`This session has used ${S(e)} tokens so far${n}.`}function $e(e){return e!=null&&e>0?S(e):null}function et(e){return e!=null&&Number.isFinite(e)&&e>0?Je(e):null}function tt(e,t){return e==null||t==null||!Number.isFinite(e)||!(e>0)||!Number.isFinite(t)||t<5||t>100?null:e/t}function nt(e,t){if(e==null||t==null||!(e>0)||!(t>0))return null;let n=e/t;return Number.isFinite(n)?n<.001?`<0.001% of week`:`≈${n<1?String(Number(n.toPrecision(1))):n<10?n.toFixed(1):String(Math.round(n))}% of week`:null}function rt(e){let t=e=>e!=null&&Number.isFinite(e)&&e>0,n=t(e.agentsRunning)?e.agentsRunning:0,r=t(e.agentCostUsd)?e.agentCostUsd:0,i=t=>{let n=nt(t,e.usdPerWeekPct);return n?` (${n})`:``},a=t(e.costUsd)?`${x(e.costUsd+r)} this prompt${n?` so far`:``}${i(e.costUsd+r)}`:null,o=n?`${n} subagent${n===1?``:`s`} still running`:null,s=a&&r?`${x(r)} of it in subagents${o?` · ${o}`:``}`:o,c=e.cumAgentCostUsd!=null&&Number.isFinite(e.cumAgentCostUsd),l=t(e.cumCostUsd)?e.cumCostUsd+(c?e.cumAgentCostUsd:0):0,u=l>0?`${x(l)} session so far${i(l)}`:null,d=t(e.ctxTok)?`${S(e.ctxTok)} context`:null;if(!a&&!u&&!d&&!s)return null;let f=!!e.agents&&a!=null&&!r&&!n,p=!!e.agentsSoFar&&u!=null&&!c,m=t(e.agentUnpricedTok)?`, ${S(e.agentUnpricedTok)} subagent tokens have no published rate`:``,h=typeof e.weekIncl==`string`&&e.weekIncl.trim()?` (${e.weekIncl.trim()})`:``,g=(a||u)&&nt(1,e.usdPerWeekPct)?`; % of week estimated from this desktop's spend${h} against the weekly limit reading`:(a||u)&&typeof e.weekRefused==`string`&&e.weekRefused.trim()?`; ${e.weekRefused.trim()}`:``;return{turn:a,agents:s,total:u,ctx:d,note:a||u?`API list price${f||p?`, subagents not included`:``}${m}${g}`:null}}function it(e){if(!e)return null;let t=e=>typeof e==`number`&&Number.isFinite(e)&&e>0?e:0,n=[[t(e.input),`in`],[t(e.output),`out`],[t(e.cacheRead),`cache read`],[t(e.cacheWrite),`cache write`]],r=n.reduce((e,[t])=>e+t,0);if(!(r>0))return null;let i=n.filter(([e])=>e>0).map(([e,t])=>`${S(e)} ${t}`).join(` · `);return`${S(r)} tokens — ${i}`}function at(e){if(!e||!(e.tok>0))return null;let t=`Next prompt re-reads ${S(e.tok)} of context`;return e.multiple==null||e.baseTok==null?`${t}.`:e.multiple<1.15?`${t} — about what a fresh session here starts with (${S(e.baseTok)}).`:`${t} — ${Ze(e.multiple)} what a fresh session here starts with (${S(e.baseTok)}).`}var ot=`Why dollars on a subscription?`,st=`Your plan's session and weekly limits don't count every token the same: on one model a cache read costs a hundredth of an output token. Adding tokens up treats them as equal, so the total says little about how much of your limit a prompt used. Pricing each kind at Anthropic's API list price weighs it by its own rate — the one number you can compare across prompts, sessions and models. It is not a bill.`,ct=`Why only the last prompt in the CLI view?`,lt=`The reader folds this card under every prompt — tap a line to open it, and scroll up for older ones. The CLI view has no scroll-back of its own to hang a card on, so it keeps only the last prompt's, pinned under the terminal at a fixed height: opening or updating it never resizes the screen, which would make the CLI redraw. Same figures, same card; the newest one remembers open or folded in both.`;function ut(e,t,n){let r=t!=null&&t>0?` — ${x(t)} of it in subagents`:``,i=n!=null&&n>0?` ${S(n)} tokens ran on a model with no published rate and are not in it.`:``;return`At list prices that is ${x(e)} so far${r} — an estimate of what the API would have charged, not what a subscription costs.${i}`}function dt(e,t,n=2){if(t==null||t<=0)return null;let r=e-t;if(r<=0)return null;let i=t*(n-Ve)/(Ve*r);if(!Number.isFinite(i))return null;let a=Math.max(1,Math.ceil(i));return a>24?null:a}function ft(e,t){return e==null||t!=null&&t<6?`fresh`:e>=9?`steep`:e>=5?`heavy`:e>=2.5?`warm`:`fresh`}function pt(e,t){return e==null||t==null||e<=0||t*2<=e?null:`Most of what this session spent — ${S(t)} of ${S(e)} — was its subagents, and compacting or a new session lowers only what the next turn here costs. Each agent re-reads its own growing window on every step, so agents with a narrower task that finish sooner are what brings that down.`}var mt=5e5;function ht(e,t,n,r=mt){return e==null||!(e>=r)||t!=null&&n!=null&&n-t>6e5?null:`A subagent is re-reading ${S(e)} on every step — agents with a narrower task that finish sooner cost less.`}function gt(e,t){return`A subagent${t?` (${t})`:``} was re-reading ${S(e)} of context on every step. If it is still running, stop it with TaskStop, keep what it already returned, and re-spawn the rest as narrower tasks: one work package per agent, model set explicitly, each briefed to return before about 200k of context. If it already finished, apply that to the next agents you spawn.`}function _t(e){let{tok:t,baseTok:n,turns:r,spentTok:i}=e,a=e.cacheCold??null,o=e.usageTok??null,s=e.agentTok??null,c=n!=null&&n>0&&t>0?t/n:null,l=ft(c,r),u=l===`fresh`?null:dt(t,n),d=o!=null&&o>0?` ${Qe(o,s)}`:i!=null&&i>0?` This conversation has carried ${S(i)} tokens in total.`:``,f=a?` Nothing has run here for hours: the cached prefix has very likely expired, so the next turn re-WRITES these ${S(t)} rather than re-reading them, which is the expensive direction by an order of magnitude.`:``,p=a?` Even a quick question pays that re-write first, so there is no cheap turn left here.`:` A quick question is still cheaper here.`;if(l===`fresh`){let e=n==null?`Each turn re-reads ${S(t)} of context. How that compares with a fresh session here is not known — this conversation's log is longer than the host reads in one go, so there is no first reading to measure against.`:`Each turn re-reads ${S(t)} of context — about what a fresh session in this repo costs.${d}`,a=n==null?f:``;return{level:l,tok:t,baseTok:n,multiple:c,breakEven:u,spentTok:i,usageTok:o,agentTok:s,turns:r,chip:null,note:e+a,advice:vt(a?`New work belongs in a fresh session; this window has to be paid for again before it can answer anything.`:null,pt(o,s))}}let m=Ze(c);return{level:l,tok:t,baseTok:n,multiple:c,breakEven:u,spentTok:i,usageTok:o,agentTok:s,turns:r,chip:m,note:`Each turn re-reads ${S(t)} of context — ${m} what a fresh session in this repo costs (${S(n)}).${d}${f}`,advice:vt(u==null?l===`steep`?`New work that does not need what is already in this window would be markedly cheaper in a new session.${p}`:a?`New work that does not need what is already in this window would be cheaper in a new session.${p}`:null:`More than ${u} ${u===1?`turn`:`turns`} of work that does not need what is already in this window would be cheaper in a new session.${p}`,pt(o,s))}}function vt(e,t){return e&&t?`${e} ${t}`:e??t}function yt(e){return e?`Compacting is the other door: it keeps this conversation and re-reads a summary of it instead of all of it, so work that still needs what is here stays here. A new session keeps nothing.`:null}function bt(e,t,n){return{baseTok:t?void 0:e[0]?.tok,...n==null?null:{turns:n},spentTok:e.reduce((e,t)=>e+t.tok,0)}}function xt(e,t,n,r,i){if(!e.length)return null;let a=e[e.length-1].tok;if(!(a>0))return null;let o=bt(e,t,n);return _t({tok:a,baseTok:o.baseTok??null,turns:o.turns??null,spentTok:o.spentTok,usageTok:r?.usageTok??null,agentTok:r?.agentTok??null,cacheCold:St(i)})}function St(e){return e?ze(e.lastTurnAt,e.now,e.turnActive):null}function Ct(e,t){if(!e||!e.pts.length)return null;let n=e.pts[e.pts.length-1];return n>0?_t({tok:n,baseTok:e.baseTok??null,turns:e.turns??null,spentTok:e.spentTok??null,usageTok:e.usageTok??null,agentTok:e.agentTok??null,cacheCold:St(t)}):null}function wt(e){let t=(e,t)=>{let n=(e??0)+(t??0);return n>0?n:null};return{count:e.auto.count+e.manual.count,manual:e.manual.count,unmeasured:e.unmeasured,shedTok:e.auto.shedTok+e.manual.shedTok,savedTok:e.auto.savedTok+e.manual.savedTok,savedUsd:t(e.auto.savedUsd,e.manual.savedUsd),rebuildTok:e.auto.rebuildTok+e.manual.rebuildTok,rebuildUsd:t(e.auto.rebuildUsd,e.manual.rebuildUsd)}}function Tt(e){let t=e.count;return t<=0?null:(t===1?e.manual===1?`One compaction, and you asked for it.`:`One compaction, the CLI's own.`:e.manual===0?`${t} compactions, none of them yours.`:e.manual===t?`${t} compactions, all of them yours.`:`${t} compactions — ${e.manual} you asked for, ${t-e.manual} the CLI's own.`)+(e.shedTok>0?` ${t===1?`It took`:`Together they took`} ${S(e.shedTok)} out of the window.`:``)}function Et(e){return e.unmeasured<=0?null:`${e.unmeasured===1?`One more compaction is`:`${e.unmeasured} more compactions are`} in none of these figures — the log did not record both sides of the drop, so there is nothing to measure them from.`}function Dt(e){let t=[];return e.savedTok>0&&t.push(`saved ${S(e.savedTok)}${e.savedUsd==null?``:` · ${x(e.savedUsd)}`}`),e.rebuildTok>0&&t.push(`cost ${S(e.rebuildTok)}${e.rebuildUsd==null?``:` · ${x(e.rebuildUsd)}`}`),t.length?t:[`nothing back yet`]}function Ot(e){if(e.savedTok<=0)return null;let t=e.savedUsd==null?``:`, worth ${x(e.savedUsd)} at list prices — the one figure here that was never actually spent`;return`Every request since has carried that much less: ${S(e.savedTok)} tokens not re-sent${t}.`}function kt(e){return e.count<=0||e.savedTok>0?null:`No turn has run since, so nothing has been saved back yet — the saving is what the next requests will not have to carry.`}function At(e){if(e.rebuildTok<=0)return null;let t=e.rebuildUsd==null?``:` (${x(e.rebuildUsd)})`;return`Rebuilding the window afterwards wrote ${S(e.rebuildTok)} tokens${t} — real spend, already counted in this session's total. The summarising request itself is not in the CLI's log, so it is in neither figure.`}function jt(e){if(e.savedUsd==null||e.rebuildUsd==null||e.rebuildUsd<=0)return null;let t=e.savedUsd/e.rebuildUsd;return t>=1?`${Ze(t)} what it cost.`:`That is ${x(e.rebuildUsd-e.savedUsd)} more than it has saved back so far.`}function Mt(e,t,n){if(!(e.savedTok>0)||!(e.shedTok>0)||!(n&&n>0)||!(t&&t>0))return null;let r=t+e.shedTok;return r<=n?null:`Uncompacted it would be carrying ${S(r)} — past the ${S(n)} window, so those turns could not have run at all.`}function Nt(){return`The saving prices those tokens as cache reads — the cheapest they could have been; a conversation resumed after the cache expired re-writes its window at up to twenty times that rate. The cost counts the whole first write after each boundary, part of which the next turn would have paid anyway. Both err against compacting looking worthwhile.`}function Pt(e,t){return e===`manual`?t===1?`you typed /compact`:`you typed /compact ${t}×`:t===1?`the CLI compacted`:`the CLI compacted ${t}×`}function Ft(e,t){if(!e||e.count<=0||e.tok<=0)return null;let n=e.count,r=t===`session`?`${n===1?`One turn`:`${n} turns`} here `:`${n===1?`One request`:`${n} requests`} across this desktop `,i=e.premiumUsd!=null&&e.premiumUsd>0?` That is ${x(e.premiumUsd)} more than re-reading them would have cost at list prices${e.usd!=null&&e.usd>0?`, out of ${x(e.usd)} for the writes themselves`:``}.`:``;return`${r}came back to a cache that had expired and re-WROTE ${S(e.tok)} tokens instead of re-reading them.${i}`}function C(){return{input:0,output:0,cacheRead:0,cacheWrite:0,cacheWrite1h:0,turns:0}}function w(e,t){return e.input+=t.input??0,e.output+=t.output??0,e.cacheRead+=t.cacheRead??0,e.cacheWrite+=t.cacheWrite??0,e.cacheWrite1h+=t.cacheWrite1h??0,e.turns+=t.turns??0,e}function T(e){return e.input+e.output+e.cacheRead+e.cacheWrite}var It=[{id:`input`,slot:0,name:`Input`,what:`Fresh prompt tokens — the part of each request that was not already in the cache. The smallest of the four by a wide margin, and the one closest to “what I typed”.`},{id:`output`,slot:1,name:`Output`,what:`Everything the model generated: replies, tool calls, thinking. The number that tracks how much work came back.`},{id:`cacheRead`,slot:2,name:`Cache read`,what:`Context served out of the prompt cache. Usually the overwhelming majority — every turn re-reads the whole conversation — which is why a single “tokens used” figure is mostly this.`},{id:`cacheWrite`,slot:3,name:`Cache write`,what:`Context written into the cache so later turns can read it back. Rises when a conversation grows or is compacted.`}];function Lt(e){return{input:e[0],output:e[1],cacheRead:e[2],cacheWrite:e[3],cacheWrite1h:0,turns:1}}function Rt(e){let t=e.cacheRead+e.cacheWrite+e.input;return t>0?e.cacheRead/t*100:null}function zt(e){return e.turns>0?T(e)/e.turns:null}var Bt=2e5;function Vt(e){if(e.cacheWrite<=0)return null;let t=Math.min(e.cacheWrite1h,e.cacheWrite);return((e.cacheWrite-t)*He+t*2)/e.cacheWrite/(1-Ve)}function Ht(e,t=`corpus`){let n=Rt(e);if(n==null)return null;let r=Vt(e),i=e.cacheWrite>0?e.cacheRead/e.cacheWrite:null,a=e.cacheRead+e.cacheWrite+e.input,o=e.turns>0?a/e.turns:null,s=o==null?null:o>=2e5?`heavy`:o>=1e5?`ordinary`:`lean`,c=i!=null&&r!=null&&i<r,l=c?`Cache reads are ${Math.round(n)}% of everything sent in, but each token written into the cache was read back only ${i.toFixed(1)}× — under the ${r.toFixed(1)}× a write has to earn back before it beats paying full input price. That is sessions ending or being invalidated before their context is re-read, not a context that is too big.`:i==null?`Cache reads are ${Math.round(n)}% of everything sent in. A cache read bills at a tenth of the input rate, so a high share is the cheap shape of the same traffic rather than a symptom.`:`Cache reads are ${Math.round(n)}% of everything sent in, and each token written into the cache was read back ${i>=10?Math.round(i):i.toFixed(1)}× — well past the ${r.toFixed(1)}× that makes a write worth writing. A high share is the cheap shape of this traffic, not a symptom: a cache read bills at a tenth of the input rate, and the only way to lower the share is to re-send the same context at full price.`,u=`the ~${E(Bt)} mark where this desktop's own logs found the spend concentrating (the conversations past 200k were 1.4% of them and 76% of every token)`,d=t===`session`?`A mean is not a ceiling: this is every request this conversation logged, the small early ones averaged in with whatever the window grew to. The curve above is where it actually went.`:`A mean is not a ceiling: the long conversations are averaged in with the short ones, and only the per-session reading on the context screen can name one.`;return{sharePct:n,reuse:i,payback:r,perTurnCtx:o,posture:s,cacheNote:l,contextNote:o==null?null:s===`heavy`?`The mean turn carried ${E(o)} of context — past ${u}. What makes a turn expensive is the size of the window, not the share of it served from cache. ${d}`:s===`ordinary`?`The mean turn carried ${E(o)} of context, just under ${u}. ${d}`:`The mean turn carried ${E(o)} of context, well under ${u}${t===`session`?``:` — long sessions are not the norm here`}. ${d}`,advice:t===`session`?null:c?`Worth a look at what ends sessions after a turn or two, or at anything rewriting the start of the prompt between turns.`:s===`heavy`?`The lever is the length of a conversation, not the cache: work that does not need what is already in the window is cheaper in a new session. The per-session reading on the context screen names the ones that grew.`:null}}function Ut(e,t,n=`repos`){let r=[...e].sort((e,t)=>T(t)-T(e));if(r.length<=t+1)return r;let i=r.slice(0,t),a=r.slice(t),o=n.replace(/s$/,``),s={key:`__other__`,label:`Other (${a.length} ${a.length===1?o:n})`,...C(),cost:y()};for(let e of a)w(s,e),b(s.cost,e.cost);return[...i,s]}function Wt(e){if(!Number.isFinite(e)||e<=0)return`0%`;let t=e*100;return t<1?`<1%`:t<100&&Math.round(t)===100?`>99%`:`${Math.round(t)}%`}function Gt(e){let t=0;return e.map(e=>(t+=e.total,{...e,sum:t}))}function Kt(e){let[t,n,r]=e.split(`-`).map(Number);return new Date(t,(n||1)-1,r||1).getTime()}function E(e){if(!Number.isFinite(e))return`?`;let t=Math.abs(e),n=t>=1e9?[`B`,1e9]:t>=1e6?[`M`,1e6]:t>=1e3?[`k`,1e3]:null;if(!n)return String(Math.round(e));let r=e/n[1];return`${r.toFixed(+(Math.abs(r)<100)).replace(/\.0$/,``)}${n[0]}`}function qt(e){if(Number.isInteger(e))return E(e);let t=Math.round(e*10)/10;return e>0&&t===0?`<0.1`:String(t)}function Jt(e){return Math.round(e).toLocaleString()}var Yt=18e4;function Xt(e,t){return e==null||t==null||Math.abs(e-t)<=Yt}function Zt(e,t,n=27e5){let r=e=>t===`session`?e.s:e.w,i=e=>t===`session`?e.sr:e.wr,a=[],o=null,s=null,c=null,l=null;for(let t of e){let e=r(t);if(e==null)continue;let u=i(t),d=l!=null&&u!=null&&!Xt(l,u),f=c!=null&&e<c-2,p=!!s&&(d||f),m=!!s&&t.t-s.t>n;!o||p||m?(o={pts:[],rolled:p},a.push(o),l=u):l??=u,o.pts.push({t:t.t,v:e,r:u}),s=t,c=e}return a}function Qt(e,t){return Zt(e,t,1/0)}var $t=36e5;function en(e){let t=new Date(e),n=e=>String(e).padStart(2,`0`);return`${t.getFullYear()}-${n(t.getMonth()+1)}-${n(t.getDate())}T${n(t.getHours())}`}function tn(e){let[t,n,r]=e.slice(0,10).split(`-`).map(Number),i=Number(e.slice(11,13));return new Date(t,(n||1)-1,r||1,Number.isFinite(i)?i:0).getTime()}function nn(e){return tn(en(e))}function rn(e){return nn(e+$t/2)}var an=(e,t)=>t.cost.total-e.cost.total||T(t.totals)-T(e.totals);function on(e){let t=new Map;for(let n of e)for(let e of n??[]){let n=t.get(e.model)??{model:e.model,totals:C(),cost:y()};w(n.totals,e.totals),b(n.cost,e.cost),t.set(e.model,n)}return[...t.values()].sort((e,t)=>T(t.totals)-T(e.totals)||e.model.localeCompare(t.model))}function sn(e,t){return(e.byHour??[]).some(e=>e.hour===t&&(e.tok>0||e.usd>0))}var cn=[`Sun`,`Mon`,`Tue`,`Wed`,`Thu`,`Fri`,`Sat`],ln=e=>`${String(new Date(e).getHours()).padStart(2,`0`)}:00`;function un(e){let t=e.convos??[],n=new Map;for(let t of e.hours??[])n.set(t.hour,{hour:t.hour,t:t.t,usd:t.cost.total,tok:T(t.totals),byRepo:t.byRepo??[],convoIds:[],restConvos:Number.isFinite(t.restConvos)&&t.restConvos>0?t.restConvos:0});for(let e of t)for(let t of e.byHour??[])!n.has(t.hour)&&(t.tok>0||t.usd>0)&&n.set(t.hour,{hour:t.hour,t:tn(t.hour),usd:0,tok:0,byRepo:[],convoIds:[],restConvos:0});let r=new Set((e.hours??[]).map(e=>e.hour));for(let e of n.values())for(let n of t)if(sn(n,e.hour)&&(e.convoIds.push(n.id),!r.has(e.hour)))for(let t of n.byHour)t.hour===e.hour&&(e.usd+=t.usd,e.tok+=t.tok);let i=[...n.values()].filter(e=>e.tok>0||e.usd>0||e.convoIds.length>0).sort((e,t)=>e.t-t.t||e.hour.localeCompare(t.hour)),a=e.rest??[],o=a.reduce((e,t)=>e+(t.count>0?t.count:0),0),s=Math.max(t.length+o,Number.isFinite(e.convosTotal)?e.convosTotal:0),c=e=>e==null?t.slice():t.filter(t=>sn(t,e));return{buckets:i,convosIn:c,filterText:e=>{if(e==null)return null;let t=`${c(e).length} of ${s} ${s===1?`session`:`sessions`}`,r=n.get(e)?.t;return r==null?t:`${t} · ${cn[new Date(r).getDay()]} ${ln(r)}–${ln(r+$t)}`},total:s,restText:e=>{if(e==null){if(o<=0)return null;let e=a.reduce((e,t)=>e+(Number.isFinite(t.cost?.total)?t.cost.total:0),0);return`${o} cheaper ${o===1?`session`:`sessions`} not listed${e>0?` · ${x(e)}`:``}`}let t=n.get(e)?.restConvos??0;return t>0?`${t} more ${t===1?`session`:`sessions`} in this hour ${t===1?`is`:`are`} not listed`:null}}}var dn={fanout:`fan-out`,backlog:`backlog item`,schedule:`schedule`,agent:`agent`,resurrect:`resumed at reset`,hand:`by hand`,fork:`fork`,unrecorded:`no launch record`},fn=e=>e.launch?.runId||e.launch?.itemId||`c:${e.id}`,pn=e=>e.launch?.runId||e.launch?.itemId||`rest:${e.repo}:${e.launch?.kind??`unrecorded`}`;function mn(e,t){let n=e.trim().split(/\s+/).filter(Boolean);return n.length>t?`${n.slice(0,t).join(` `)}…`:n.join(` `)}var hn=e=>e.title||`${e.label} · ${e.id.slice(0,8)}`,gn=e=>`${e} ${e===1?`repo`:`repos`}`;function _n(e,t=[]){let n=e.convos[0],r=e.convos.find(e=>e.launch?.label)?.launch?.label??t.find(e=>e.launch?.label)?.launch?.label;if(!n&&!r){let n=e.more,r=t[0]?.label;return`${n} more ${n===1?`session`:`sessions`}${r?` · ${r}`:``}`}return e.kind===`fanout`?`${r||mn(e.convos.find(e=>e.title)?.title??``,6)||`fan-out`} · ${gn(e.repos)}`:r&&(e.kind===`backlog`||e.kind===`schedule`||e.kind===`agent`)?e.repos>1?`${r} · ${gn(e.repos)}`:r:n?hn(n):r}function vn(e,t){if(t.some(t=>t?.runId&&t.runId===e))return`fanout`;let n=t.map(e=>e?.kind).filter(e=>!!e);return n.find(e=>e!==`resurrect`)??n[0]??`unrecorded`}function yn(e,t=[]){let n=new Map,r=e=>n.get(e)??n.set(e,{convos:[],rest:[]}).get(e);for(let t of e)r(fn(t)).convos.push(t);for(let e of t)e.count>0&&r(pn(e)).rest.push(e);let i=[];for(let[e,t]of n){let n=t.convos.slice().sort(an),r=t.rest.slice().sort(an),a=C(),o=y(),s=C(),c=y(),l=null,u=null;for(let e of[...n,...r])w(a,e.totals),b(o,e.cost),w(s,e.agentTotals),b(c,e.agentCost),e.firstAt!=null&&(l=l==null?e.firstAt:Math.min(l,e.firstAt)),e.lastAt!=null&&(u=u==null?e.lastAt:Math.max(u,e.lastAt));let d={key:e,kind:vn(e,[...n.map(e=>e.launch),...r.map(e=>e.launch)]),repos:new Set([...n.map(e=>e.repo),...r.map(e=>e.repo)]).size,convos:n,more:r.reduce((e,t)=>e+t.count,0),totals:a,cost:o,agentTotals:s,agentCost:c,firstAt:l,lastAt:u};i.push({...d,label:_n(d,r)})}return i.sort((e,t)=>an(e,t)||e.key.localeCompare(t.key))}function bn(e,t=[]){let n=new Map,r=e=>n.get(e)??n.set(e,{convos:[],rest:[]}).get(e);for(let t of e)r(t.repo).convos.push(t);for(let e of t)e.count>0&&r(e.repo).rest.push(e);let i=[];for(let[e,t]of n){let n=t.convos.slice().sort(an),r=C(),a=y(),o=y();for(let e of[...n,...t.rest])w(r,e.totals),b(a,e.cost),b(o,e.agentCost);let s=n[0]?.label??t.rest[0]?.label??e,c=t.rest.reduce((e,t)=>e+t.count,0);i.push({repo:e,label:s,totals:r,cost:a,agentCost:o,convos:n,more:c,byModel:on([...n,...t.rest].map(e=>e.byModel))})}return i.sort((e,t)=>an(e,t)||e.repo.localeCompare(t.repo))}function xn(e){return{key:e.repo,label:e.label,...e.totals,cost:{...e.cost},byModel:e.byModel}}var Sn=6*$t,Cn=.35,wn=.4;function Tn(e){return!!e&&typeof e.usdPerPt==`number`}function En(e,t,n){let r=Qt(e??[],`week`).filter(e=>e.pts.length>=2);if(!r.length)return{why:`noSamples`};let i=r.filter(e=>e.pts[e.pts.length-1].t-e.pts[0].t>=Sn);if(!i.length)return{why:`shortStretches`};let a=i.filter(e=>e.pts[e.pts.length-1].v-e.pts[0].v>=5);if(!a.length)return{why:`smallDelta`};let o=a.map(e=>{let n=e.pts[0],r=e.pts[e.pts.length-1],i=nn(n.t),a=nn(r.t),o=0;for(let e of t??[])e.t>=i&&e.t<a&&Number.isFinite(e.cost?.total)&&(o+=e.cost.total);return{usd:o,dPts:r.v-n.v}}).filter(e=>e.usd>0);if(!o.length)return{why:`noCost`};if(o.length===1&&o[0].dPts<10)return{why:`smallDelta`};let s=o.reduce((e,t)=>e+t.usd,0),c=o.reduce((e,t)=>e+t.dPts,0),l=s/c;if(!(l>0)||!Number.isFinite(l))return{why:`noCost`};if(o.some(e=>Math.abs(e.usd/e.dPts/l-1)>.35))return{why:`unstable`};let u=n!=null&&Number.isFinite(n)&&n>0?n:null;return u!=null&&Math.abs(l/u-1)>.4?{why:`disagreesWithLevel`}:{usdPerPt:l,usd:s,dPts:c,stretches:o.length,levelUsdPerPt:u}}function Dn(e,t){if(!Tn(t)||e==null||!Number.isFinite(e)||!(e>0)||!(t.usdPerPt>0)||!Number.isFinite(t.usdPerPt))return null;let n=e/t.usdPerPt;if(!Number.isFinite(n))return null;if(n<.05)return`<0.1 pt`;let r=Number(n.toPrecision(2));return r===1?`≈ 1 pt`:`≈ ${r} pts`}function On(e){switch(e.why){case`noSamples`:return`Points can't be calibrated yet — there are not two weekly readings in this span to compare.`;case`shortStretches`:return`Points can't be calibrated yet — no run of weekly readings without a reset spans ${Sn/$t} hours.`;case`smallDelta`:return`Points can't be calibrated yet — the week has not climbed 5 points inside one stretch of readings (10 when there is only one).`;case`noCost`:return`Points can't be calibrated — this desktop's logs have no cost in the hours the weekly figure climbed.`;case`unstable`:return`Points are not shown — the dollars per point moved by more than ${Math.round(Cn*100)}% between stretches of readings, so no one figure is right.`;case`disagreesWithLevel`:return`Points are not shown — the climb-based rate and the per-reading rate disagree by more than ${Math.round(wn*100)}%.`}}function kn(e){let t=We(e)?.split(`-`)[1];return t?t.charAt(0).toUpperCase()+t.slice(1):null}function An(e){let t=e.cost?.total;if(!(t>0)||!Number.isFinite(t)||!e.agentByModel?.length)return null;let n=new Map,r=0;for(let t of e.agentByModel){let e=t.cost?.total;if(!Number.isFinite(e)||e<=0)continue;r+=e;let i=kn(t.model);i&&n.set(i,(n.get(i)??0)+e)}if(r>t*1.001)return null;let i=null;for(let e of n)(!i||e[1]>i[1])&&(i=e);if(!i)return null;let a=i[1]/t*100;return a<15?null:`${i[0]} subagents: ${Math.round(a)}% of this session's cost`}function jn(e){return(e??``).replace(/\s+/g,` `).trim().toLowerCase()}function Mn(e,t){let n=e.filter(e=>e.finishedAt!=null).sort((e,t)=>t.startedAt-e.startedAt),r=jn(t);if(r){let e=n.find(e=>jn(e.text)===r);if(e)return e}return n[0]??null}function Nn(e){return e<1?String(Number(e.toPrecision(1))):e<10?e.toFixed(1):String(Math.round(e))}function Pn(e){let{same:t,usd:n,weekPct:r,agentPct:i,repos:a}=e,o=a>0?gn(a):null,s=t?`last similar run${o?` (${o})`:``}`:`last run (different prompt${o?`, ${o}`:``})`,c=r!=null&&Number.isFinite(r)&&r>0?` ≈ ${Nn(r)}% of week`:``,l=Number.isFinite(i)&&i>=0?`, ${Math.round(Math.min(100,i))}% subagents`:``;return`${s}: ${x(n)}${c}${l}`}var D=e=>typeof e==`number`&&Number.isFinite(e);function Fn(e){return e==null?null:!D(e)||e<0?`its ledger holds a figure that is not a count`:e===0?null:`holds ${E(e)} record${e===1?``:`s`} it could not date that could fall in this span, so the figure could be missing ${e===1?`it`:`them`}`}function In(e,t){let n=e?.undated;if(!D(n)||n<=0)return n;let r=e?.undatedLogs;if(Array.isArray(r)&&D(t)){let e=0,i=0,a=!0;for(let n of r){if(!Array.isArray(n)||!D(n[0])||!D(n[1])||n[1]<0){a=!1;break}e+=n[1],n[0]<t&&(i+=n[1])}if(a&&e<=n)return n-i}let i=e?.undatedUntil;return D(i)&&D(t)&&i<t?0:n}var Ln=`Claude Code`;function Rn(e){let t=Fn(e);return t?`${Ln}'s ledger ${t.replace(/^its ledger /,``)}`:null}function zn(e,t=Ln){let n=Fn(e);return n?`${t}: ${n}.`:null}function Bn(e){if(e.unit)return`${qt(e.unit.amount)} ${e.unit.name}`;let t=Object.entries(e.kinds).filter(([,e])=>e>0).sort((e,t)=>t[1]-e[1]);return t.length?`${t.map(([e,t])=>`${E(t)} ${e}`).join(`, `)} tokens`:`nothing counted`}var Vn=`Also on this desktop over this span — each its own account, not in the figure above`,Hn=[`tok`,`usd`,`sessionPct`,`weeklyPct`,`native`],Un=e=>e===`sessionPct`||e===`weeklyPct`;function Wn(e){if(!e||typeof e!=`object`)return null;let t=e;if(typeof t.unit!=`string`||!Hn.includes(t.unit))return null;let n=t.unit,r=t.max;if(typeof r!=`number`||!Number.isFinite(r)||!(r>0)||(n===`sessionPct`||n===`weeklyPct`)&&r>100)return null;let i={};if(n===`native`){let e=typeof t.nativeUnit==`string`?t.nativeUnit.trim():``;if(!e||e.length>32)return null;i={nativeUnit:e}}return t.hard===!0?{unit:n,max:r,interrupt:!0,hard:!0,...i}:{unit:n,max:r,interrupt:t.interrupt!==!1,...i}}function Gn(e){let t={source:!0};return!e||ce(e).length||(e.tok!=null&&(t.usageTok=e.tok+(e.agentTok??0),e.agentTok!=null&&(t.agentTok=e.agentTok)),e.usd!=null&&(t.costUsd=e.usd+(e.agentUsd??0),e.agentUsd!=null&&(t.agentCostUsd=e.agentUsd)),e.native&&(t.native={amount:e.native.amount,unit:e.native.unit,...e.native.agentAmount==null?{}:{agentAmount:e.native.agentAmount}})),t}function Kn(e){return e.sourceSpend?Gn(e.sourceSpend):e.contextSpark??null}function qn(e,t,n,r,i){let a=e=>({value:null,agent:null,why:e});if(!t)return a(`noSpark`);if(e===`native`){let e=t.native;return!e||!i||e.unit.trim()!==i?a(`unstated`):{value:e.amount+(e.agentAmount??0),agent:e.agentAmount??null}}if(t.source&&Un(e))return a(`notClaude`);if(e===`tok`)return t.usageTok==null?a(t.source?`unstated`:`noSpark`):{value:t.usageTok,agent:t.agentTok??null};if(t.costUsd==null)return a(t.source?`unstated`:`unpriced`);if(e===`usd`)return{value:t.costUsd,agent:t.agentCostUsd??null};if(!n)return a(`noReading`);if(r-n.checkedAt>15e5)return a(`stale`);let o=e===`sessionPct`?n.sessionUsdPerPct:n.weeklyUsdPerPct;if(o==null||!(o>0)){let t=e===`sessionPct`?n.sessionUndated:n.weeklyUndated;return t!=null&&t>0?{...a(`undated`),undated:t}:a(`noCalibration`)}return{value:t.costUsd/o,agent:t.agentCostUsd==null?null:t.agentCostUsd/o}}function Jn(e,t,n,r,i=!0){let a=qn(e.unit,t,n,r,e.nativeUnit),o={unit:e.unit,max:e.max,spent:a.value,agentShare:a.agent,...e.nativeUnit?{nativeUnit:e.nativeUnit}:{}};return a.value==null?{...o,state:`unknown`,why:a.why,...a.undated==null?{}:{undated:a.undated}}:i?{...o,state:a.value>=e.max?`over`:`ok`}:{...o,state:`unknown`,why:`notRunning`}}function Yn(e){return e.budget?.verdict.state===`over`}function Xn(e){return e<10?e.toFixed(1).replace(/\.0$/,``):String(Math.round(e))}function Zn(e,t,n){switch(e){case`tok`:return`${E(t)} tokens`;case`usd`:return x(t);case`native`:return`${qt(t)} ${n??`of the backend's own unit`}`;default:return`≈${Xn(t)}% of ${e===`sessionPct`?`the 5-hour window`:`the week`}`}}function Qn(e){switch(e.unit){case`tok`:return`≤ ${E(e.max)} tokens`;case`usd`:return`≤ ${x(e.max)}`;case`sessionPct`:return`≤ ${Xn(e.max)}% of this 5-hour window`;case`weeklyPct`:return`≤ ${Xn(e.max)}% of this week`;case`native`:return`≤ ${Zn(`native`,e.max,e.nativeUnit)}`;default:return`a budget this app version cannot read`}}function $n(e,t,n,r,i){let a=` — nothing is held`;switch(e){case`noSpark`:return`can't tell: this session has not logged a turn yet${a}`;case`unpriced`:return`can't tell: no list price covers this session's model${a}`;case`noReading`:return`can't tell: there is no usage reading to convert dollars into window percent${a}`;case`stale`:return t!=null&&t>0?`can't tell: the usage reading is ${Math.round(t/6e4)} min old${a}`:`can't tell: the usage reading is too old${a}`;case`noCalibration`:return`can't tell: this window has not run enough here to say what one percent costs${a}`;case`notRunning`:return`can't tell: the session is not running${a}`;case`unstated`:return`can't tell: this session's backend has not stated what it spent${n===`tok`?` in tokens`:n===`usd`?` in dollars`:n===`native`?` in ${r??`its own unit`}`:``}${a}`;case`notClaude`:return`can't tell: ${er}, which this session's backend does not spend from${a}`;case`undated`:return`can't tell: ${Rn(i)??`Claude Code's ledger holds records it could not date, which this window could be missing`}${a}`;default:return`can't tell: this budget could not be checked${a}`}}var er=`the 5-hour and weekly windows are claude's account`;function tr(e){return`No ≈% of a window here: ${er}, and ${e} does not spend from it.`}var nr=`≈, from this desktop's spend — other use of the account makes it read high`;function rr(e){if(e.state===`unknown`||e.spent==null)return $n(e.why??`noSpark`,void 0,e.unit,e.nativeUnit,e.undated);let t=e.agentShare!=null&&e.agentShare>0?`, ${Zn(e.unit,e.agentShare,e.nativeUnit)} of it in subagents`:``,n=Un(e.unit)?Zn(e.unit,e.max).replace(`≈`,``):Zn(e.unit,e.max,e.nativeUnit),r=Un(e.unit)?` (${nr})`:``;return`${Zn(e.unit,e.spent,e.nativeUnit)} so far${t} — ${e.state===`over`?`over`:`within`} the ${n} budget${r}`}function ir(e){return e.hard?`Hard budget: queued and scheduled sends to this session are held, a send you make yourself asks you first, and every turn you did not send yourself is stopped with one Esc — until you raise or clear the budget.`:`Sends to this session are held until you raise or clear the budget — an explicit send, an answer to a question and an upload still go.`}function ar(e){let t=t=>{switch(e.unit){case`tok`:return E(t);case`usd`:return x(t);case`native`:return qt(t);default:return`${Un(e.unit)?`≈`:``}${Xn(t)}%`}},n=e.unit===`native`&&e.nativeUnit?` ${e.nativeUnit}`:``;return`${e.spent==null?`?`:t(e.spent)} / ${Un(e.unit)?t(e.max).replace(`≈`,``):t(e.max)}${n}`}var or=216e5,sr=[`low`,`medium`,`high`,`xhigh`,`max`],cr=[`default`,`plan`,`acceptEdits`,`auto`,`dontAsk`,`bypassPermissions`],lr=/^[\w.:/@[\]+-]{1,120}$/,ur=/^[\w.-]{1,64}$/;function dr(e){if(!e||typeof e!=`object`||Array.isArray(e))return;let t=e,n={},r=typeof t.model==`string`?t.model.trim():``;lr.test(r)&&(n.model=r),sr.includes(t.effort)&&(n.effort=t.effort),cr.includes(t.permissionMode)&&(n.permissionMode=t.permissionMode),t.remoteControlled===!0&&(n.remoteControlled=!0);let i=typeof t.backend==`string`?t.backend.trim():``;return ur.test(i)&&(n.backend=i),Object.keys(n).length?n:void 0}function fr(e){let t=e.trim();return!t||t.startsWith(`/`)||t.includes(`\\`)||t.includes(`\0`)?!1:!t.split(`/`).some(e=>e===`..`||e===`.`)}function pr(e){let t=(e.missing?.length?e.missing:e.needs).map(e=>e.split(`/`).pop()||e);switch(e.state){case`waiting`:return t.length===1?`waiting for ${t[0]} to finish uploading`:`waiting for ${t.length} files to finish uploading`;case`opening`:return`opening the session…`;case`done`:return`opened`;case`canceled`:return e.reason||`called off`;default:return e.reason||`did not open`}}var O={name:`waterplane`,displayName:`waterplane`,slug:`waterplane`,envPrefix:`WATERPLANE_`,configDirName:`waterplane`,stateDirName:`.waterplane`,sharedDirName:`.waterplane-shared`,storagePrefix:`waterplane.`,cacheName:`waterplane-cache`,wsProtocol:`waterplane`,cookie:`waterplane_auth`,pairScheme:`waterplane`,launchdLabel:`dev.waterplane.host`,appId:`dev.waterplane.app`,tmuxServer:`waterplane`,pluginManifest:`waterplane-plugin.json`,skillName:`waterplane`,tagline:`The CLI wasn't built for your phone. waterplane lands it anyway.`,domain:`waterplane.dev`,githubOrg:`waterplane-dev`,promptAliases:[`WP`,`wp`],dictationTerms:[`waterplane`]},k=[{name:`USMC`,slug:`usmc`,envPrefix:`USMC_`,configDirName:`usmc`,stateDirName:`.usmc`,storagePrefix:`usmc.`,cacheName:`usmc-cache`,wsProtocol:`usmc`,cookie:`usmc_auth`,pairScheme:`usmc`,launchdLabel:`com.usmc.host`,appId:`dev.unsuck.amc`,tmuxServer:`usmc`,pluginManifest:`usmc-plugin.json`,skillName:`usmc`,words:[`usmc`,`unsuck`,`un-suck`]}];[...new Set([O.name.toLowerCase(),O.slug.toLowerCase(),...k.flatMap(e=>e.words)])];var A=e=>`${O.storagePrefix}${e}`,mr=e=>k.map(t=>`${t.storagePrefix}${e}`),hr=e=>`${O.envPrefix}${e}`,gr=`[${O.slug}]`,_r=k.map(e=>e.stateDirName),vr=e=>`${O.stateDirName}/${e}`,yr=e=>`${O.sharedDirName}/${e}`,br=/^[A-Za-z][A-Za-z0-9_]{0,31}$/,xr=/\{\{\s*([A-Za-z][A-Za-z0-9_]{0,31})\s*\}\}/g,j=e=>typeof e==`string`?e:``;function M(e){return j(e).replace(/[\x00-\x1f\x7f]/g,` `).trim().slice(0,512)}function Sr(e){let t=e&&typeof e==`object`?e:{},n=j(t.id).trim();if(!br.test(n))return null;let r=Array.isArray(t.options)?t.options.map(M).filter(e=>!!e).slice(0,200):[],i=j(t.optionsCmd).trim().slice(0,500),a=t.kind===`choice`&&(r.length||i)?`choice`:`text`,o={id:n,kind:a},s=j(t.label).trim().slice(0,60);s&&(o.label=s),a===`choice`&&(r.length&&(o.options=r),i&&(o.optionsCmd=i));let c=M(t.default);c&&(o.default=c);let l=j(t.hint).trim().slice(0,200);return l&&(o.hint=l),o}function Cr(e){if(!Array.isArray(e))return;let t=[],n=new Set;for(let r of e){if(t.length>=8)break;let e=Sr(r);e&&!n.has(e.id)&&(n.add(e.id),t.push(e))}return t.length?t:void 0}var wr=/[;&|`$()<>\\"'\n\r]/;function Tr(e,t){return Dr(e).filter(e=>typeof t[e]==`string`&&wr.test(t[e]))}function Er(e){return e.length?`the value for ${e.map(e=>`“${e}”`).join(`, `)} contains a shell character (; & | \` $ ( ) < > \\ quotes) and would be run as part of the command — change it, or have the command read $${kr(e[0])} instead`:``}function Dr(e){let t=[];for(let n of j(e).matchAll(xr))t.includes(n[1])||t.push(n[1]);return t}function Or(e){let t=new Set((e.params??[]).map(e=>e.id));return[...Dr(e.cmd??``),...Dr(e.dir??``)].filter((e,n,r)=>r.indexOf(e)===n&&!t.has(e))}function kr(e){return hr(`PARAM_${e.toUpperCase()}`)}function Ar(e){return e.label||e.id}function jr(e,t){let n={},r=[];for(let i of e??[]){let e=M(t?.[i.id])||M(i.default);e?n[i.id]=e:r.push(i)}return{values:n,missing:r}}function Mr(e){let t=e.map(Ar);return t.length?`needs a value for ${t.length===1?`“${t[0]}”`:t.map(e=>`“${e}”`).join(`, `)}`:``}function Nr(e){return Object.entries(e??{}).filter(([,e])=>!!e).map(([e,t])=>`${e}=${t}`).join(` · `)}function Pr(e,t){let n=Nr(t);return n?`${e} · ${n}`:e}var Fr=(e,t,n,r)=>{let i=Math.round(Number(e));return Number.isFinite(i)?Math.min(n,Math.max(t,i)):r};function Ir(e){if(!e||typeof e!=`object`)return;let t=e=>{let t=Math.round(Number(e));return Number.isFinite(t)&&t>=0&&t<=1439?t:-1},n=t(e.from),r=t(e.to);if(!(n<0||r<0||n===r))return{from:n,to:r}}function Lr(e){let t=e&&typeof e==`object`?e:{},n=Fr(t.offsetMin??0,-1440,1440,0),r=Ir(t.hours),i=typeof t.tz==`string`&&t.tz.trim()&&l(t.tz.trim(),Date.now())!=null?t.tz.trim():void 0,a=r?i?{hours:r,tz:i}:{hours:r}:{};if(t.kind===`window`){let e=t.edge===`after`?`after`:`before`,r=t.minPctLeft,i=r==null||r===``?void 0:Fr(r,0,100,0),o=t.window===`weekly`?`weekly`:`session`,s=(t.guardWindow===`weekly`||t.guardWindow===`session`)&&t.guardWindow!==o?t.guardWindow:void 0,c=i!=null&&(e===`before`||s!=null);return{kind:`window`,window:o,...typeof t.periodId==`string`&&t.periodId&&t.periodId!==`session`&&t.periodId!==`weekly`?{periodId:t.periodId}:{},edge:e,offsetMin:e===`before`?Math.min(0,n):Math.max(0,n),...c?{minPctLeft:i}:{},...s?{guardWindow:s}:{},...t.oneShot===!0?{oneShot:!0}:{},...a}}if(t.kind===`once`){let e=Number(t.at);return{kind:`once`,at:Number.isFinite(e)?e:0,offsetMin:n,...a}}let o=Array.isArray(t.days)?t.days.map(e=>Fr(e,0,6,0)):[];return{kind:`weekly`,days:[...new Set(o)].sort((e,t)=>e-t),hour:Fr(t.hour??9,0,23,9),minute:Fr(t.minute??0,0,59,0),tz:i,offsetMin:n,...t.oneShot===!0?{oneShot:!0}:{},...a}}var Rr=36e5,zr={soon:`within the hour`,day:`in 24h`,twoDay:`in 2d`,week:`this week`,later:`later`,unarmed:`not armed`};function Br(e,t){if(e==null)return`unarmed`;let n=e-t;return n<=Rr?`soon`:n<=24*Rr?`day`:n<=48*Rr?`twoDay`:n<=168*Rr?`week`:`later`}var Vr=[`soon`,`day`,`twoDay`,`week`,`later`,`unarmed`];function Hr(e){return Vr.find(t=>e[t]>0)??null}function Ur(e){let t=Vr.filter(e=>e!==`unarmed`).map(t=>({n:e[t],label:zr[t]})).filter(e=>e.n>0);if(!t.length)return e.unarmed>0?`${e.unarmed} ${zr.unarmed}`:null;let[n,r]=t;return r?`${n.n} ${n.label} · ${r.n} more ${r.label}`:`${n.n} ${n.label}`}var Wr=e=>new Date(e).toLocaleString(void 0,{weekday:`short`,day:`numeric`,month:`short`,hour:`2-digit`,minute:`2-digit`});function Gr(e,t=Date.now()){let n=e-t;if(n<=0)return`due now`;let r=Math.round(n/6e4);if(r<60)return`in ${r}m`;let i=Math.floor(r/60),a=r%60;if(i<24)return`in ${i}h${a?` ${a}m`:``}`;let o=Math.floor(i/24),s=i%24;return`in ${o}d${s?` ${s}h`:``}`}function Kr(e,t){let n=e?`after “${e}”`:`after the item before it`;return t?`${n}, only if it worked`:n}function qr(e,t){return e.kind===`now`?`now`:e.kind===`idle`?`when it's free`:e.kind===`after`?Kr(e.title,e.onlyIfOk):t==null?e.rule.kind===`window`?`${oe(e.rule)} — armed once the host reads the window`:`never — the time it resolves to has passed`:`${Wr(t)} · ${Gr(t)}`}var Jr=6e4,Yr=864e5,Xr=2e3,Zr=6e4;function Qr(e){return Math.min(Zr,Xr*2**Math.max(0,e-1))}var $r=6e4,ei=3e5,ti=18e5;function ni(e){return Math.min(ti,ei*2**Math.max(0,e-1))}function ri(e){return!!e.stalled||!e.responded||!e.socketOpen}function ii(e,t,n){return e.map(e=>e.mode===`upload`&&e.status!==`failed`&&e.sessionId!==n&&e.upload&&t.includes(e.upload.relPath)?{...e,sessionId:n}:e)}function ai(e,t){return e.filter(e=>e.mode===`upload`&&e.status===`failed`&&e.upload&&t.includes(e.upload.relPath)).map(e=>e.upload.relPath)}function oi(e,t){let n=e.findIndex(e=>e.sessionId===t&&e.status===`queued`&&!e.answer);return n<0?e.length:n}function si(e){return ci(e)!==null}function ci(e){if(e.limitBlocked)return`limit`;if(e.block===`auth`)return`auth`;if(e.block===`net`)return`net`;let t=e.promptKind===`trust`&&e.trustAutoAccepted!==!1;return e.awaitingInput||e.promptKind&&!t?`awaitingAnswer`:e.turnActive?`sessionBusy`:null}function li(e,t){let n=new Set(t.inflight??[]),r=new Set(t.busyLanes??[]),i=new Set(t.busySerial??[]),a=new Set(t.goneLanes??[]),o=[],s=[],c=[],l=[],u=(e,t)=>{l.push({ackId:e.ackId,sessionId:e.sessionId,reason:t})},d=new Set;for(let t of e)(t.status===`pending`||n.has(t.ackId))&&(d.add(t.sessionId),t.serial&&i.add(t.serial));for(let l of e){if(l.status!==`queued`)continue;if(n.has(l.ackId)){u(l,`inflight`);continue}if(l.pendingCreate){d.add(l.sessionId),u(l,`pendingCreate`);continue}if((l.mode??`input`)===`input`&&a.has(l.sessionId)&&!l.cwd){u(l,`sessionGone`);continue}if(l.holdUntilIdle&&r.has(l.sessionId)){d.add(l.sessionId),u(l,`held`);continue}let e=!!t.budgetBlocked&&!l.armed&&!l.answer&&l.mode!==`upload`,f=!!t.budgetHeldLanes?.has(l.sessionId)&&!l.armed&&!l.answer&&l.mode!==`upload`,p=!!l.serial&&i.has(l.serial);if(l.retryAt!=null&&l.retryAt>t.now){d.add(l.sessionId),u(l,`backoff`);continue}let m=l.firstTryAt==null?1/0:t.now-l.firstTryAt;(l.attempts??0)>=t.maxAttempts&&m>=(t.minTryMs??0)?c.push({ackId:l.ackId,reason:`delivery kept failing`}):e?(d.add(l.sessionId),u(l,`budget`)):f?(d.add(l.sessionId),u(l,`sessionBudget`)):p?(d.add(l.sessionId),u(l,`serial`)):d.has(l.sessionId)?u(l,`lane`):(d.add(l.sessionId),l.serial&&i.add(l.serial),l.holdUntilIdle&&s.push(l),o.push(l))}return{send:o,expire:c,release:s,blocked:l}}function ui(e,t,n,r,i){return e.map(e=>e.pendingCreate&&e.sessionId===t&&di(e,i)?{...e,sessionId:n,pendingCreate:void 0,createAck:void 0,ts:r}:e)}function di(e,t){return!t||!e.createAck||e.createAck===t}function fi(e,t,n){return e.filter(e=>e.pendingCreate&&e.sessionId===t&&e.status===`queued`&&di(e,n))}function pi(e,t){if(!t.length)return e.slice();let n=new Set(t.map(e=>e.ackId));return e.map(e=>n.has(e.ackId)?{...e,holdUntilIdle:void 0}:e)}function N(e){return`repo:${e}`}function mi(e,t,n){let r=new Set;for(let t of e)t.running!==!1&&si(t)&&r.add(N(t.cwd));let i=[];for(let a of t){let t=e.find(e=>e.id===a.sessionId);t&&t.turnStartedAt||n-a.at>=6e4||(r.add(a.group),i.push(a))}return{busy:r,watches:i}}function hi(e,t){return(e.attempts??0)>0||e.armed?!0:t.autoSend&&!t.hold}function gi(e,t,n={}){let r=new Map,i=(e,t)=>{let n=r.get(e);n?t.sessionId&&n.some(e=>e.sessionId===t.sessionId)||n.push(t):r.set(e,[t])};for(let t of e){if(t.running===!1||n.automaticOnly&&!t.automatic)continue;let e=ci(t)??(n.automaticOnly&&t.asking?`awaitingAnswer`:null);e&&i(N(t.cwd),{sessionId:t.id,wall:(e===`sessionBusy`||e===`net`)&&t.netStalled?`netStalled`:e,...t.name?{name:t.name}:{}})}for(let n of t){let t=n.sessionId?e.find(e=>e.id===n.sessionId):void 0,r=t?.name||n.name;i(N(n.cwd),{...n.sessionId?{sessionId:n.sessionId}:{},wall:t?.netStalled?`netStalled`:`starting`,...r?{name:r}:{}})}return r}var _i=`one at a time in this repo — waiting for the session before it`,vi={sessionBusy:`working`,limit:`on a usage limit`,auth:`signed out`,net:`retrying a network error`,starting:`starting a queued job`},yi=48,bi={awaitingAnswer:0,netStalled:0,auth:0,limit:1,net:1,sessionBusy:1,starting:2};function xi(e){if(e&&e.length)return[...e].sort((e,t)=>bi[e.wall]-bi[t.wall])[0]}function Si(e){let t=xi(e);if(!e||!t)return _i;let n=e.length>1?` +${e.length-1} more`:``;if(t.wall===`starting`&&!t.name&&!t.sessionId)return`one at a time in this repo — an automatic job is starting here${n}`;let r=(t.name??``).trim(),i=r.length>yi?`${r.slice(0,47)}…`:r;return t.wall===`netStalled`?`one at a time in this repo — waiting behind a stalled item: API unreachable${i?` ('${i}')`:``}${n}`:t.wall===`awaitingAnswer`?`one at a time in this repo — waiting for your answer in ${i?`'${i}'`:`the session before it`}${n}`:`one at a time in this repo — waiting for ${i?`'${i}'`:`another session`} (${vi[t.wall]})${n}`}function Ci(e){switch(e){case`budget`:return`paused — the account is past your usage budget; it resumes when the window resets`;case`sessionBudget`:return`held — this session is over its own budget; raise or clear it to send`;case`sessionGone`:return`that session is gone — aim it at another session or at the repo's backlog`;case`gate`:return`queued — auto-send is off, tap Send now`;case`backoff`:return`a send just failed — retrying in a moment`;case`held`:return`held until the agent finishes this turn`;case`serial`:return _i;case`pendingCreate`:return`waiting for its session to open`;case`lane`:return`another message for that session is going out first`;case`inflight`:return`a delivery for that session is already in flight`}}function wi(e,t){if(!t.online)return`still offline — staying queued`;if(!t.queued||!e.length)return null;for(let n of[`gate`,`budget`,`sessionBudget`,`sessionGone`,`backoff`,`serial`,`held`,`pendingCreate`,`lane`,`inflight`])if(e.some(e=>e.reason===n))return n===`serial`&&t.serialText?t.serialText:Ci(n);return null}function Ti(e){return e.status===`queued`&&e.mode!==`op`&&e.mode!==`upload`&&!e.answer}function Ei(e,t,n){return e.map(e=>{if(e.ackId!==t||!Ti(e))return e;let r=n.mode??(e.mode===`backlog`?`backlog`:`input`),i={...e,ackId:n.ackId,sessionId:n.sessionId,cwd:n.cwd,mode:r,attempts:0};return delete i.firstTryAt,r===`backlog`?(i.label=(e.text??``).slice(0,40),n.targetSessionId?i.targetSessionId=n.targetSessionId:delete i.targetSessionId):(delete i.label,delete i.fire,delete i.autoFire,delete i.targetSessionId),i})}function Di(e,t,n){let r=e.findIndex(e=>e.ackId===t);if(r<0)return e.slice();let i=e[r],a=-1;for(let t=r+n;t>=0&&t<e.length;t+=n)if(e[t].sessionId===i.sessionId){a=t;break}if(a<0)return e.slice();let o=e.slice();return o[r]=o[a],o[a]=i,o}function P(e,t){return{kind:`wait`,reason:e,detail:Oi(e,t)}}function Oi(e,t){let n=t?.trim();if(n)return n;switch(e){case`offline`:return`still on this phone — it goes to the desktop the moment the link is back, in full, and nothing expires while it waits`;case`gate`:return`auto is off — run it by hand, or turn auto on`;case`budget`:return`paused — the account is past your usage budget; it resumes when the window resets`;case`sessionBudget`:return`held — this session is over its own budget; raise or clear it to let this go`;case`sessionBusy`:return`waiting — the session is working`;case`sessionGone`:return ji;case`awaitingAnswer`:return`waiting — the session is waiting for an answer`;case`limit`:return`the session is blocked on a usage limit — waiting for it to reopen`;case`auth`:return`the session is signed out — send /login there to sign in, and this goes once it is`;case`net`:return`the session's last turn hit a network error — waiting for the host's retry to get through`;case`filesMissing`:return`waiting for its files to finish uploading`;case`notYet`:return`not due yet`;case`serial`:return _i;case`hostBusy`:return`waiting for the desktop to be free — something else is starting or running`;case`noSlot`:return`waiting for a free slot — every automatic session this desktop runs at a time is working`;case`localModel`:return`waiting for the local model — another local session is working, or the model is still loading`;default:return`waiting — the desktop is holding this for a reason this app version cannot name yet`}}function ki(e){return e.open.filter(e=>e.busy!==!1)}var Ai=[`offline`,`gate`,`budget`,`sessionBudget`,`sessionGone`,`auth`,`limit`,`net`,`awaitingAnswer`,`notYet`,`filesMissing`,`serial`,`hostBusy`,`localModel`,`noSlot`,`sessionBusy`],ji=`that session is gone — aim it at another session, or at this repo's backlog`,Mi=`every session this was aimed at is gone — aim it at this repo's backlog instead`,Ni=`another item is running in that session`,Pi=e=>e.map(e=>e.split(`/`).pop()||e);function Fi(e){let t=Pi(e);return t.length===1?`waiting for ${t[0]} to finish uploading`:`waiting for ${t.length} files to finish uploading`}function Ii(e){let t=Pi(e);return t.length===1?`${t[0]} never arrived — the words are still here; re-attach it and send again`:`${t.length} files never arrived (${t.slice(0,3).join(`, `)}${t.length>3?`, …`:``}) — the words are still here; re-attach and send again`}function Li(e){return`not due yet — it fires at the time on this row`}function Ri(e,t){return`missed — more than ${t} min past its time, and it could not start in time`}function zi(e,t){return`missed — it was due and cleared to start, then waited ${Math.round(t/36e5)} h without ever getting a free moment (the grace you set was ${e} min)`}function Bi(e){let t=h(e);return t?`outside its hours (${t}${g(e)}) — runs when they open`:`outside the hours it may run — runs when they open`}function Vi(e,t,n,r){if(t===e)return!0;if(!n)return!1;let i=new Set([e]),a=t;for(;a;){if(i.has(a))return!0;if(r?.has(a))return!1;i.add(a),a=n.get(a)}return!1}var Hi=e=>e?`waits for “${e}” to finish`:`waits for the item before it to finish`,Ui=e=>e?`the item this waited for is gone (“${e}”) — nothing is going to release it; give it a time, or chain it to another`:`the item this waited for is gone — nothing is going to release it; give it a time, or chain it to another`,Wi=`the item it waited for failed, and this one was set to run only if that one succeeded`,Gi=`the item it waited for was called off — nothing is going to release this; give it a time, or chain it to another`,Ki=`these items are waiting on each other in a circle, so none of them can ever start — give one of them a time instead`,qi=e=>`missed — more than ${e} min since the item it waited for finished, and it could not start in time`,Ji=e=>(e?`the item this waits for (“${e}”) is archived, so nothing is going to start it`:`the item this waits for is archived, so nothing is going to start it`)+` — bring it back to release this, or give this one a time`,Yi=e=>(e?`the item this waited for (“${e}”) is a repeating rule, so it never finishes`:`the item this waited for is a repeating rule, so it never finishes`)+` — nothing is going to release this; give it a time, or chain it to one run of that work`;function Xi(e,t){if(e.kind!==`window`||e.edge===`after`)return null;let n=(e.offsetMin??0)*6e4;return!(n<0)||!Number.isFinite(t)?null:{window:e.periodId??(e.window===`weekly`?`weekly`:`session`),from:t,until:t-n}}function Zi(e){return e.trigger.kind===`at`?typeof e.nextAt==`number`?Xi(e.trigger.rule,e.nextAt):null:e.budgetPass??null}function Qi(e,t,n){if($i(e,n))return null;if(!t.budgetOver?.length)return t.budgetDetail??``;let r=Zi(e),i=r?t.budgetOver.find(e=>e.which===r.window):void 0,a=r!=null&&(!i||i.resetAt!=null&&Math.abs(i.resetAt-r.until)<=3e5),o=a?Math.max(r.until,i?.resetAt??r.until):0;for(let e of t.budgetOver){let t=a&&(e.which===r.window||r.window===`weekly`&&e.which===`session`);if(!(t&&n>=r.from&&n<o))return t&&n<r.from?Ie(e,n,r.window):r&&e.which!==r.window&&!t?Le(e,r.window,n):Fe(e,n)}return null}function $i(e,t){return e.pastBudget!=null&&t<e.pastBudget.until}function ea(e){if(!e||typeof e!=`object`)return;let t=e,n=t.until;if(typeof n!=`number`||!Number.isFinite(n))return;let r=typeof t.periodId==`string`&&t.periodId.trim()?t.periodId:void 0;return{until:n,...t.weekly===!0?{weekly:!0}:{},...r?{periodId:r}:{}}}function ta(e,t){if(typeof e.leftoverOf==`number`)return e.leftoverOf;let n=Zi(e);return n&&n.window===`weekly`&&t>=n.until?n.until:na(e,t)}function na(e,t){if(e.trigger.kind!==`at`||typeof e.nextAt!=`number`)return null;let n=e.trigger.rule;if(n.kind!==`window`||n.window!==`weekly`)return null;let r=(n.offsetMin??0)*6e4;if(n.edge!==`after`&&r<0)return null;let i=Math.max(0,r);if(i>18e6)return null;let a=e.nextAt-i;return t>=a?a:null}var ra=`fanout`,ia=`fanout:fu:`,aa=`agent`,oa=e=>e.origin===aa,sa=e=>!!e.origin?.startsWith(`peer:`)&&e.origin.length>5,ca=e=>{if(e?.startsWith(`peer:`))return e.slice(5)||void 0},la=`posted by an agent — edit or delete it like any other`,ua=`waits for your tap — nothing starts it by itself`,da=new Set([`work`,`sweep`,`build`]);function fa(e){if(!e?.startsWith(`schedule:`))return;let t=e.slice(9);return t&&!da.has(t)?t:void 0}var pa=e=>e.trigger.kind===`files`,ma=e=>!!e.groupId&&(e.origin===`fanout`||e.origin===`fanout:run`||(e.origin?.startsWith(`fanout:fu:`)??!1)),ha=e=>e.trigger.kind===`at`&&!n(e.trigger.rule)&&e.payload.kind===`prompt`&&(e.target.kind===`repo`||e.target.kind===`session`)&&!ma(e),ga=e=>e.trigger.kind===`at`&&!ha(e),_a=e=>e.trigger.kind===`at`&&e.trigger.paused===!0,va=`schedule:work`,ya=e=>e.origin===`schedule:work`&&ga(e),ba=(e,t,n)=>JSON.stringify([e,t,+!!n]),xa=e=>e.payload.kind===`build`&&!ga(e),Sa=e=>e.payload.kind===`prompt`&&(e.trigger.kind===`now`||e.trigger.kind===`idle`||e.trigger.kind===`budget`||e.trigger.kind===`after`||ha(e))&&(e.target.kind===`repo`||e.target.kind===`session`)&&!ma(e),Ca=e=>e.payload.kind===`assess`,wa=e=>e.payload.kind===`capture`;function Ta(e){return pa(e)?`launch`:ga(e)?`schedule`:ma(e)?`fanout`:xa(e)?`build`:Ca(e)?`assess`:wa(e)?`capture`:Sa(e)?`work`:`other`}var Ea=e=>e.target.kind===`repo`&&e.target.fresh===!0||Da(e),Da=e=>e.target.kind===`session`&&!!e.target.resumeConvId&&e.trigger.kind===`at`;function Oa(e,t){if(!Da(e)||e.target.kind!==`session`)return null;let n=e.target.resumeConvId;return t.find(t=>t.running!==!1&&t.convId===n&&t.id!==e.target.sessionId)?.id??null}function ka(e,t,n,r){let i=e=>({kind:`go`,sessionId:e,occurrence:n,late:r});switch(e.target.kind){case`shell`:return i();case`repos`:return e.target.dirs.filter(e=>t.knownDirs.has(e)).length?i():{kind:`fail`,detail:`none of the repos this was aimed at are still there — re-aim it at one that is`};case`sessions`:{let n=e.target.sessionIds.filter(e=>ja(t,e));if(!n.length)return P(`sessionGone`,Mi);for(let r of n){let n=Aa(e,t,r);if(n)return n}return i()}case`session`:if(Da(e)&&!ja(t,e.target.sessionId)){let n=Oa(e,t.sessions);return n?Aa(e,t,n)??i(n):i()}return Aa(e,t,e.target.sessionId)??i(e.target.sessionId);case`repo`:return i()}}function Aa(e,t,n){let r=ja(t,n);if(!r)return P(`sessionGone`,ji);if(t.busySessions?.has(n)&&!e.interject&&e.state!==`starting`&&e.state!==`running`)return P(`sessionBusy`,Ni);if(t.budgetHeldSessions?.has(n))return P(`sessionBudget`);let i=ci(r);return i?P(i):null}function ja(e,t){let n=e.sessions.find(e=>e.id===t);return n&&n.running!==!1?n:void 0}function Ma(e,t,r){if(e.archived)return P(`gate`,`set aside — bring it back to let it run`);if(e.manual)return P(`gate`,ua);if(e.auto&&!e.pinned&&!t.autoFire)return P(`gate`);if(_a(e))return P(`gate`,`this schedule is switched off — turn it back on and the next occurrence arms itself`);if(t.budgetBlocked&&e.auto){let n=Qi(e,t,r);if(n!==null)return P(`budget`,n)}if(t.leftoverOver&&e.auto&&!$i(e,r)&&ta(e,r)!==null){let n=typeof e.leftoverOf!=`number`&&na(e,r)!==null;return P(`budget`,ke(t.leftoverOver,r,n))}let i,a,o;switch(e.trigger.kind){case`now`:case`idle`:break;case`budget`:if(t.budgetBlocked&&!$i(e,r))return P(`budget`,t.budgetDetail);break;case`files`:{let n=e.trigger.needs.filter(e=>!t.present.has(e));if(!n.length)break;return r>=e.trigger.deadlineAt?{kind:`fail`,detail:Ii(n),missing:n}:{...P(`filesMissing`,Fi(n)),missing:n}}case`at`:{let t=e.trigger;if(t.rule.kind===`window`&&e.nextAt==null&&(n(t.rule)||e.lastOccurrence==null||e.nextAt===void 0))return P(`notYet`,`waiting for the first usage reading — the reset this tracks has not been read yet`);let s=typeof e.nextAt==`number`?e.nextAt:e.nextAt===null?null:_(t.rule,e.lastOccurrence??e.createdAt-1);if(s==null)return{kind:`fail`,detail:`that instant has passed and this was a one-off — post it again if you still want it`};if(s>r)return P(`notYet`,Li(s));if(!p(t.rule,r))return P(`notYet`,Bi(t.rule));let c=r-(m(t.rule,s)??s),l=Math.max(Math.max(0,t.graceMin)*6e4,Jr),u=e.clearedOccurrence===s,d=u?Math.max(l,Yr):l;if(c>d){let e=u?zi(t.graceMin,d):Ri(s,t.graceMin);return n(t.rule)?{...P(`notYet`,e),missedOccurrence:s}:{kind:`fail`,detail:e}}i=s,o=s,a=c>6e4||void 0;break}case`after`:{let n=e.trigger;if(Vi(e.id,n.id,t.chainWaits,t.settled))return{kind:`fail`,detail:Ki};if(t.neverSettles?.has(n.id))return{kind:`fail`,detail:Yi(n.title)};let i=t.settled?.get(n.id);if(!i)return t.setAside?.has(n.id)?P(`notYet`,Ji(n.title)):t.knownIntents&&!t.knownIntents.has(n.id)?{kind:`fail`,detail:Ui(n.title)}:P(`notYet`,Hi(n.title));if(i.canceled)return{kind:`fail`,detail:Gi};if(!i.ok&&n.onlyIfOk)return{kind:`fail`,detail:Wi};if(n.graceMin!=null){let t=r-i.at,a=Math.max(Math.max(0,n.graceMin)*6e4,Jr),o=e.clearedOccurrence===i.at,s=o?Math.max(a,Yr):a;if(t>s)return{kind:`fail`,detail:o?zi(n.graceMin,s):qi(n.graceMin)}}o=i.at;break}}let s=e=>e.kind===`wait`&&o!=null?{...e,clearedOccurrence:o}:e;if(e.serial&&t.busyCwds.has(N(e.cwd))){let n=t.serialHolders?.get(N(e.cwd)),r=xi(n),i=P(`serial`,n?.length?Si(n):void 0);return s(r?.sessionId?{...i,holderSessionId:r.sessionId}:i)}return e.holdForHost&&t.hostBusy?s(P(`hostBusy`)):t.local&&t.local.rows.has(e.id)&&t.local.free<=0&&!(e.target.kind===`session`&&t.local.busy.has(e.target.sessionId))?s(P(`localModel`)):e.auto&&Ea(e)&&t.autoSlotsFree<=0?s(P(`noSlot`)):s(ka(e,t,i,a))}var Na=[`web`,`android`,`garmin`,`window`],Pa={w:390,h:844},Fa=e=>e.split(/[/\\]+/).filter(Boolean);function Ia(e){let t=new Map,n=new Map;for(let t of e){let e=n.get(t.name)??[];e.includes(t.dir)||e.push(t.dir),n.set(t.name,e)}for(let e of n.values()){if(e.length<2)continue;let n=e.map(e=>Fa(e).slice(0,-1));n.forEach((r,i)=>{for(let a=1;a<=r.length;a++){let o=r.slice(-a).join(`/`);if(n.every((e,t)=>t===i||e.slice(-a).join(`/`)!==o)){t.set(e[i],`${o}/`);return}}t.set(e[i],`/${r.join(`/`)}${r.length?`/`:``}`)})}return t}function La(e){return e.where?`${e.repoName} · ${e.where}`:e.repoName}function Ra(e){if(e==null)return{ok:!0,value:null};if(typeof e!=`string`)return{ok:!1,error:`A display name is text.`};let t={ok:!1,error:`A display name is one line of plain text.`},n=e.normalize(`NFC`).trim();if(/[\p{Cc}\p{Zl}\p{Zp}]|(?![\u200c\u200d])\p{Cf}/u.test(n))return t;let r=n.replace(/[\s\p{Zs}]+/gu,` `);return r?/[^\p{Z}\p{C}]/u.test(r)?[...r].length>40?{ok:!1,error:`A display name is at most 40 characters.`}:{ok:!0,value:r}:t:{ok:!0,value:null}}function za(e){return La({repoName:e.displayName||e.repoName,where:e.where})}function Ba(e){return e.displayName?{...e,repoName:e.displayName}:e}function Va(e,t,n){return!n||n===t||!t?e:e===t?n:e.startsWith(`${t} · `)?`${n}${e.slice(t.length)}`:e}function Ha(e,t){return e?.displayName?Va(t,e.repoName,e.displayName):t}function Ua(e,t){let n=null;for(let r of e)r.displayName&&(t===r.repoName||t.startsWith(`${r.repoName} · `))&&(!n||r.repoName.length>n.repoName.length)&&(n=r);return Ha(n,t)}var Wa=[`bug`,`feature`,`enhancement`,`chore`],Ga=[`hand`,`assess`,`name`],Ka=`no kind`,qa=[[`"`,`"`],[`'`,`'`],[`“`,`”`],[`‘`,`’`],["`","`"]];function Ja(e,t){if(typeof e!=`string`)return;let n=e.trim().replace(/\s+/g,` `);for(let[e,t]of qa)if(n.length>=2&&n.startsWith(e)&&n.endsWith(t)){n=n.slice(1,-1).trim();break}if(n.endsWith(`.`)&&!n.endsWith(`..`)&&(n=n.slice(0,-1).trim()),!n)return;n.length>80&&(n=n.slice(0,80).trim());let r=(t??``).trim().replace(/\s+/g,` `);if(!(r&&r.startsWith(n)))return n}function Ya(e){if(typeof e!=`string`)return;let t=e.trim().toLowerCase();return Wa.find(e=>e===t)}function Xa(e){if(typeof e!=`string`)return;let t=e.trim().toLowerCase();return Ga.find(e=>e===t)}function Za(e){return re(e.label,e.text,40)||(e.headline??``).trim()||null}function Qa(e){switch(e){case`bug`:return`bug`;case`feature`:return`feature`;case`enhancement`:return`enhancement`;case`chore`:return`chore`}}function $a(e){if(typeof e!=`string`)return;let t=e.trim().replace(/\s+/g,` `);for(let[e,n]of qa)if(t.length>=2&&t.startsWith(e)&&t.endsWith(n)){t=t.slice(1,-1).trim();break}if(t.endsWith(`.`)&&!t.endsWith(`..`)&&(t=t.slice(0,-1).trim()),!t||/[…]|\.\.\./.test(t))return;let n=t.split(` `).filter(Boolean).slice(0,4);for(;n.length>1&&n.join(` `).length>30;)n.pop();if(t=n.join(` `),!(!t||t.length>30))return t}var eo=[`main`,`master`];function to(e){return typeof e==`string`&&eo.includes(e.trim().toLowerCase())}function no(e){let t=(e.branch??``).trim();if(t&&!(e.isPrimary&&to(t)))return t}function ro(e){let t=no(e);return t?`${La(e)} · ${t}`:La(e)}function io(e){let t=typeof e==`string`?e.trim():``,n=t.lastIndexOf(` · `);return n<=0?t:to(t.slice(n+3))?t.slice(0,n):t}function ao(e){return(e.tabTitle??``).trim()}function oo(e,t){let n=e=>(e??``).split(`
3
+ `)[0].trim();return ao(e)||n(t)||n(e.firstPrompt)||io(e.title)||void 0}function so(e){let t=ao(e);return t?`${e.title} · ${t}`:e.title}var co=[`done`,`obsolete`,`superseded`,`merged`,`wanted`,`unclear`];vr(`assess-in.json`),vr(`assess-out.json`),vr(`plan.md`);function lo(e){if(!e||typeof e!=`object`)return;let t=e;if(!(t.kind!==`slot`||typeof t.key!=`string`||!t.key.trim()||t.key.length>200))return{kind:`slot`,key:t.key.trim()}}function uo(e,t){let n=e.length;for(;n>0&&t.includes(e[n-1]);)n--;return n===e.length?e:e.slice(0,n)}var fo=e=>uo(e.replace(/^[([{'"`*]+/,``),`)]}.,;:'"\`*`),po=/\.(?:png|jpe?g|gif|webp|bmp|heic|heif|svg)\b/gi;function mo(e){let t=[];for(let n of e.split(/\s+/)){let e=-1,r=-1;po.lastIndex=0;for(let t;t=po.exec(n);)r=t.index,e=t.index+t[0].length;r>0&&t.push(n.slice(0,e))}return t}function ho(e){let t=typeof e==`string`?mo(e):[];return[...new Set(t.map(fo))]}function go(e){switch(e){case`done`:return`already done`;case`obsolete`:return`no longer applies`;case`superseded`:return`covered by another item`;case`merged`:return`merged with others`;case`wanted`:return`still wanted`;case`unclear`:return`could not tell`;default:return`a verdict this app version cannot name`}}function _o(e){switch(e){case`no-evidence`:return`left undecided: nothing was cited to back that up`;case`unknown-verdict`:return`left undecided: the verdict was not one this app knows`;case`duplicate`:return`left undecided: it was given more than one verdict`;case`unmentioned`:return`left undecided: the assessment did not mention it`;case`supersede-unknown`:return`left undecided: it points at an item that was not in the list`;case`supersede-self`:return`left undecided: it points at itself`;case`supersede-cycle`:return`left undecided: the chain of items it points at comes back round`;case`merge-conflict`:return`left undecided: more than one outcome claimed it`;case`merge-dropped`:return`left undecided: the merge it was part of did not stand`;case`merge-unknown`:return`left undecided: it names a merge that does not exist`;default:return`left undecided: for a reason this app version cannot name`}}function vo(e){let t=e.evidence?` — ${e.evidence}`:``;return e.downgraded?`${_o(e.downgraded)}${t}`:e.verdict===`superseded`&&e.supersededBy?`${go(`superseded`)} (${e.supersededBy})${t}`:`${go(e.verdict)}${t}`}function yo(e){let t={done:0,obsolete:0,superseded:0,merged:0,wanted:0,unclear:0};for(let n of e.rows)t[n.verdict]++;return t}function bo(e){let t=e=>!!e.headline||!!e.category;return e.rows.filter(t).length+e.merges.filter(t).length+e.news.filter(t).length}function xo(e){return`${e.ids.length===2?`these two`:`these ${e.ids.length}`} contradict each other — ${e.why}`}function So(e){return`two jobs in one item: split into two, on the same clock${e.rationale?` — ${e.rationale}`:``}`}function Co(e){return`This applies an order to ${e===1?`1 item`:`${e} items`}. Should it stay as you approved it?`}var wo=`keep this order`,To=`leave it unmarked`;function Eo(e){return e?`Marked as placed by you, the way a drag is — each row says so.`:`The order is written either way; these rows just do not say “placed by you”. Nothing re-sorts them on its own.`}function Do(e){return`This run wrote a title or a kind for ${e===1?`1 item`:`${e} items`}. Should they go on the rows?`}var Oo=`write them`,ko=`leave the rows as they are`;function Ao(e){return e?`Written as the run's — a title or kind you typed yourself is never replaced, and you can edit or clear any of them on the row.`:`Nothing is titled. The suggestions stay on this sheet only.`}var F=e=>typeof e==`string`?e.trim():``,I=e=>{let t=Number(e);return Number.isFinite(t)&&t!==0?t:void 0},jo=e=>{let t=Number(e);return e!=null&&e!==``&&Number.isFinite(t)?t:void 0};function Mo(e){if(!e||typeof e!=`object`)return;let t=e;if(typeof t.window!=`string`||!t.window.trim())return;let n=Number(t.from),r=Number(t.until);if(typeof t.from==`number`&&typeof t.until==`number`&&Number.isFinite(n)&&Number.isFinite(r)&&n<r)return{window:t.window,from:n,until:r}}var No=[`queued`,`blocked`,`starting`,`running`,`done`,`failed`,`canceled`],Po=new Set(Ai);function Fo(e,t){let n=e&&typeof e==`object`?e:{},r=F(n.id),i=F(n.cwd);if(!r||!i)return null;let a=Ro(n.payload);if(!a)return null;let o=Ho(n.trigger,Number(n.createdAt)||t);if(!o)return null;let s=o,c=o.kind===`at`&&o.paused===!0,l=zo(n.target);if(!l)return null;let u=Number(n.createdAt)||t,d=No.includes(n.state)?n.state:`queued`,f=d===`blocked`&&Po.has(n.blockReason)?n.blockReason:void 0,p=a.kind===`prompt`?a.steps[0]??``:``,m=Xa(n.headlineBy),h=m?Ja(n.headline,p):void 0,g=Xa(n.categoryBy),_=g?Ya(n.category):void 0;return{id:r.slice(0,64),cwd:i,payload:a,target:l,trigger:s,serial:n.serial===!0||void 0,holdForHost:n.holdForHost===!0||void 0,pastBudget:ea(n.pastBudget),budgetPass:Mo(n.budgetPass),leftoverOf:typeof n.leftoverOf==`number`&&Number.isFinite(n.leftoverOf)?n.leftoverOf:void 0,auto:n.auto===!0||void 0,pinned:n.pinned===!0||void 0,interject:n.interject===!0||void 0,resume:n.resume===!0||void 0,closeWhenDone:typeof n.closeWhenDone==`boolean`?n.closeWhenDone:void 0,flagWhenDone:n.flagWhenDone===!0||void 0,budget:Wn(n.budget)??void 0,archived:n.archived===!0||void 0,manual:n.manual===!0||void 0,order:jo(n.order),handOrdered:n.handOrdered===!0||void 0,attempts:I(n.attempts),label:F(n.label).slice(0,80)||void 0,title:F(n.title).slice(0,200)||void 0,headline:h,headlineBy:h?m:void 0,category:_,categoryBy:_?g:void 0,cols:I(n.cols),rows:I(n.rows),launch:dr(n.launch),replaceSessionId:F(n.replaceSessionId)||void 0,state:d,blockReason:f,blockDetail:f?F(n.blockDetail)||Oi(f):void 0,blockSessionId:f===`serial`&&F(n.blockSessionId).slice(0,128)||void 0,createdAt:u,startedAt:I(n.startedAt),settledAt:I(n.settledAt),sessionId:F(n.sessionId)||void 0,result:n.result&&typeof n.result==`object`?n.result:void 0,requeues:Io(n.requeues),requeueCount:Lo(n.requeueCount),nextAt:n.nextAt===null||c?null:I(n.nextAt),lastOccurrence:I(n.lastOccurrence),clearedOccurrence:I(n.clearedOccurrence),missing:Array.isArray(n.missing)?n.missing.filter(e=>typeof e==`string`):void 0,dismissedAt:I(n.dismissedAt),followed:n.followed===!0||void 0,origin:F(n.origin).slice(0,40)||void 0,groupId:F(n.groupId).slice(0,64)||void 0}}function Io(e){if(!Array.isArray(e))return;let t=[];for(let n of e){if(!n||typeof n!=`object`)continue;let e=n,r=Number(e.at);!Number.isFinite(r)||r<=0||(e.by===`assess`||e.by===`hand`||e.by===`run`)&&t.push({at:r,by:e.by,runId:F(e.runId).slice(0,64)||void 0,result:e.result&&typeof e.result==`object`?e.result:void 0,clockDropped:e.clockDropped===!0||void 0})}if(t.length)return t.length>5?t.slice(-5):t}function Lo(e){let t=typeof e==`number`?e:NaN;return Number.isInteger(t)&&t>0?t:void 0}function Ro(e){let t=e&&typeof e==`object`?e:{};if(t.kind===`capture`){let e=F(t.targetId);if(!e)return null;let n=Na.includes(t.backend)?t.backend:void 0;return{kind:`capture`,targetId:e.slice(0,64),name:F(t.name).slice(0,120)||void 0,backend:n,watch:t.watch===!0||void 0}}if(t.kind===`build`){let e=F(t.buildId);if(!e)return null;let n;if(t.params&&typeof t.params==`object`){let e={};for(let[n,r]of Object.entries(t.params)){if(!/^[A-Za-z][A-Za-z0-9_]{0,31}$/.test(n))continue;let t=M(r);t&&(e[n]=t)}Object.keys(e).length&&(n=e)}return{kind:`build`,buildId:e.slice(0,64),name:F(t.name).slice(0,120)||void 0,cmd:typeof t.cmd==`string`?t.cmd:void 0,cwd:F(t.cwd)||void 0,params:n}}if(t.kind===`assess`){let e=Array.isArray(t.ids)?t.ids.filter(e=>typeof e==`string`&&!!e.trim()):[];if(!e.length)return{kind:`assess`};let n=lo(t.scope);return n?{kind:`assess`,ids:e,scope:n}:{kind:`assess`,ids:e}}if(t.kind!==`prompt`)return null;let n=Array.isArray(t.steps)?t.steps.filter(e=>typeof e==`string`&&!!e.trim()).slice(0,40):[];return n.length?{kind:`prompt`,steps:n}:null}function zo(e){if(e==null)return Bo();if(typeof e!=`object`)return null;let t=e;switch(t.kind){case`session`:{let e=F(t.sessionId);if(!e)return null;let n=F(t.resumeConvId);return n?{kind:`session`,sessionId:e,resumeConvId:n}:{kind:`session`,sessionId:e}}case`repos`:{let e=[...new Set((Array.isArray(t.dirs)?t.dirs:[]).filter(e=>typeof e==`string`&&!!e.trim()).map(e=>e.trim()))].slice(0,60);return e.length?{kind:`repos`,dirs:e}:null}case`sessions`:{let e=[...new Set((Array.isArray(t.sessionIds)?t.sessionIds:[]).filter(e=>typeof e==`string`&&!!e.trim()).map(e=>e.trim()))].slice(0,60);return e.length?{kind:`sessions`,sessionIds:e}:null}case`shell`:return{kind:`shell`};case`repo`:return Bo();default:return t.kind===void 0?Bo():null}}var Bo=()=>({kind:`repo`,fresh:!0}),Vo=e=>e==null||e===``?NaN:Math.round(Number(e));function Ho(e,t){let n=e&&typeof e==`object`?e:{};switch(n.kind){case`now`:return{kind:`now`};case`idle`:return{kind:`idle`};case`budget`:return{kind:`budget`};case`at`:{let e=Lr(n.rule),t=Vo(n.graceMin);return{kind:`at`,rule:e,graceMin:Number.isFinite(t)?Math.min(10080,Math.max(0,t)):120,keepAfterRun:n.keepAfterRun===!0||void 0,paused:n.paused===!0||void 0}}case`after`:{let e=F(n.id).slice(0,64);if(!e)return null;let t=Vo(n.graceMin);return{kind:`after`,id:e,onlyIfOk:n.onlyIfOk===!0||void 0,graceMin:Number.isFinite(t)?Math.min(10080,Math.max(0,t)):void 0,title:F(n.title).slice(0,200)||void 0}}case`files`:{let e=(Array.isArray(n.needs)?n.needs:[]).filter(e=>typeof e==`string`&&!!e.trim()&&fr(e)).map(e=>e.trim()).slice(0,20),r=Number(n.deadlineAt);return{kind:`files`,needs:e,deadlineAt:Number.isFinite(r)&&r>0?r:t+or}}default:return null}}function Uo(e){return e.at?{id:e.id,rule:e.at.rule,nextAt:e.at.nextAt,waiting:!e.archived&&e.status===`queued`}:null}function Wo(e){if(!e||!e.waiting||!e.rule||n(e.rule))return null;let t=e.nextAt;if(typeof t!=`number`||!Number.isFinite(t))return null;if(e.rule.kind!==`window`)return{row:e,fire:t};let r=(e.rule.offsetMin??0)*6e4;return{row:e,fire:t,reset:t-(e.rule.edge===`after`?Math.max(0,r):r),period:e.rule.periodId??(e.rule.window===`weekly`?`weekly`:`session`)}}var Go=(e,t,n,r)=>e-t||(n<r?-1:+(n>r));function Ko(e){let t=new Map,n=[];e.forEach((e,r)=>{let i=Wo(e);i&&!t.has(e.id)&&(t.set(e.id,r),n.push(i))});let r=[],i=n.filter(e=>e.reset!=null).sort((e,t)=>Go(e.reset,t.reset,e.row.id,t.row.id)),a=[...new Set(i.map(e=>e.period))].sort();for(let e of a){let t=null;for(let n of i)n.period===e&&((!t||n.reset-t.slot.at>3e5)&&(t={slot:{key:`reset:${e}:${n.reset}`,kind:`reset`,period:e,at:n.reset,ids:[]},fires:[]},r.push(t)),t.slot.ids.push(n.row.id),t.fires.push(n.fire))}let o=[],s=n.filter(e=>e.reset==null).sort((e,t)=>Go(e.fire,t.fire,e.row.id,t.row.id));for(let e of s){let t=null,n=1/0;for(let i of r){let r=Math.min(Math.abs(e.fire-i.slot.at),...i.fires.map(t=>Math.abs(e.fire-t)));r<=3e5&&(r<n||r===n&&t&&Go(i.slot.at,t.slot.at,i.slot.key,t.slot.key)<0)&&(t=i,n=r)}t?t.slot.ids.push(e.row.id):o.push(e)}let c=r.map(e=>e.slot),l=null;for(let e of o)(!l||e.fire-l.at>3e5)&&(l={key:`at:${e.fire}`,kind:`instant`,at:e.fire,ids:[]},c.push(l)),l.ids.push(e.row.id);for(let e of c)e.ids.sort((e,n)=>t.get(e)-t.get(n));return c.sort((e,t)=>Go(e.at,t.at,e.key,t.key))}function qo(e,t){return Ko(e).find(e=>e.ids.includes(t))??null}function Jo(e,t){return qo(e,t)?.ids.filter(e=>e!==t)??[]}function Yo(e){if(typeof e!=`string`)return null;let t=e.lastIndexOf(`:`),n=Number(e.slice(t+1));return t<0||!Number.isFinite(n)||!/^\d+$/.test(e.slice(t+1))?null:e.startsWith(`at:`)&&t===2?{kind:`instant`,at:n}:e.startsWith(`reset:`)&&t>6?{kind:`reset`,period:e.slice(6,t),at:n}:null}function Xo(e,t){let n=t===`reset`?`at this reset`:`at this time`;return e===1?`1 other runs ${n}`:`${e} others run ${n}`}function Zo(e){return e===`hand`?`flagged by you`:e===`launch`?`flagged when done, as you asked`:e===`host`?`flagged by the desktop`:`flagged by the session`}function Qo(e){let t=Zo(e.by);return(e.by===`agent`||e.by===`host`)&&e.reason?`${t}: ${e.reason}`:e.by===`launch`&&e.item?`${t} (${e.item})`:t}var $o={on:!1,since:null,receipt:null},es=(e,t,n=`${t}s`)=>`${e} ${e===1?t:n}`;function ts(e){let t=[es(e.sessions,`session`)];e.sidecars&&t.push(es(e.sidecars,`background model run`));let n=e.processes?` (${es(e.processes,`process`,`processes`)}${e.forced?`, ${e.forced} forced`:``})`:``,r=e.held?` ${es(e.held,`waiting item`)} held.`:``;return`Stopped ${t.join(` and `)}${n}.${r} AI started outside ${O.displayName} and cloud sessions are not reached.`}O.pluginManifest.replace(/\.json$/,``);var ns=[`stable`,`preview`,`experimental`],rs={stable:{label:`Stable`,meaning:`The author considers it ready for daily use`},preview:{label:`Preview`,meaning:`May break between versions`},experimental:{label:`Experimental`,meaning:`May not work`},unrated:{label:`Unrated`,meaning:`The plugin does not say`}};function is(e){let t=e?.maturity,n=ns.includes(t)?t:`unrated`;return{level:n,...rs[n]}}var as=O.pluginManifest;k.map(e=>e.pluginManifest);function os(e,t){switch(e.kind){case`switch`:return typeof t==`boolean`?t:void 0;case`choice`:return typeof t==`string`&&e.options.some(e=>e.value===t)?t:void 0;case`number`:return typeof t==`number`&&Number.isFinite(t)&&t>=e.min&&t<=e.max?t:void 0;case`text`:return typeof t==`string`&&t.length<=2e4?t:void 0}}function ss(e){let t=/^v?(\d+)\.(\d+)\.(\d+)/.exec(e??``);return t?[+t[1],+t[2],+t[3]]:null}function cs(e,t){let n=ss(e),r=ss(t);if(!n||!r)return!1;for(let e=0;e<3;e++)if(n[e]!==r[e])return r[e]>n[e];return!1}function ls(e){let t=[];if(!e)return t;let n=e.self;n.latest&&cs(n.current,n.latest)&&(n.canApply||n.command)&&t.push({kind:`self`,current:n.current,latest:n.latest});for(let n of e.catalog){let e=n.installed,r=n.latest;if(!e||!r||e.source!==`manager`||n.problems.length>0)continue;let i;if(r.kind===`tag`){let t=ss(e.ref),n=ss(r.ref);i=!!e.ref&&r.ref!==e.ref&&(t&&n?cs(e.ref,r.ref):!0)}else i=!!r.commit&&!!e.commit&&r.commit!==e.commit;i&&t.push({kind:`plugin`,id:e.id,repo:n.repo,from:e.ref,to:r.ref})}return t}var us=8192,ds=4096;function fs(e){let t=e instanceof Uint8Array?e:new Uint8Array(e);if(t.byteLength<12)return null;let n=new DataView(t.buffer,t.byteOffset,t.byteLength);if(n.getUint8(0)!==87||n.getUint8(1)!==1)return null;let r=n.getUint16(2,!0);return r===0?null:{streamId:r,seq:n.getUint32(4,!0),kind:n.getUint8(8),flags:n.getUint8(9),payload:t.subarray(12)}}function ps(e){try{let t=JSON.stringify(e??null);return typeof t==`string`?new TextEncoder().encode(t).byteLength:-1}catch{return-1}}var ms=e=>typeof e==`number`&&Number.isFinite(e)&&e>=0&&e<=100;function hs(e){if(!e||!e.ok)return null;let t=[];if(ms(e.sessionPct)&&t.push({id:`session`,unit:`5h`,pct:e.sessionPct,resetAt:e.sessionResetAt??null}),ms(e.weeklyPct)&&t.push({id:`week`,unit:`wk`,pct:e.weeklyPct,resetAt:e.weeklyResetAt??null}),!t.length)return null;let n={source:`claude`,label:`Claude`,backend:`claude`,checkedAt:e.checkedAt,windows:t};return e.remembered&&(n.remembered=!0),n}function L(e){return ms(e.pct)?e.pct:typeof e.used==`number`&&typeof e.limit==`number`&&Number.isFinite(e.used)&&Number.isFinite(e.limit)&&e.limit>0&&e.used>=0?Math.min(100,Math.round(e.used/e.limit*100)):null}var gs=e=>!!e.usd&&typeof e.usd.spentUsd==`number`&&Number.isFinite(e.usd.spentUsd);function _s(e,t=Date.now()){let n=e=>e!=null&&e<=t,r=e.windows.some(e=>n(e.resetAt)),i=!!e.usd&&n(e.usd.resetAt);if(!r&&!i)return e.windows.some(e=>L(e)!=null)||gs(e)?e:null;let a={...e,windows:e.windows.filter(e=>!n(e.resetAt))};return i&&delete a.usd,a.windows.some(e=>L(e)!=null)||gs(a)?a:null}function vs(e){let t=null,n=-1;for(let r of e.windows){let e=L(r);e!=null&&e>n&&(t=r,n=e)}return t}function ys(e){return!gs(e)||!e.usd||e.usd.capUsd==null||!(e.usd.capUsd>0)?null:Math.min(100,Math.round(e.usd.spentUsd/e.usd.capUsd*100))}function bs(e){let t=vs(e),n=t?L(t):null,r=ys(e);return n==null?r:r==null?n:Math.max(n,r)}function xs(e,t=80){let n=bs(e);return n!=null&&n>=t}var Ss=e=>`$${e>=100?Math.round(e):e.toFixed(2)}`;function Cs(e,t){let n=vs(e),r=n?L(n):null;if(n&&r!=null)return{source:e.source,label:e.label,text:`${r}%`,unit:n.unit,hot:xs(e,t),reading:e};if(gs(e)&&e.usd){let n=ys(e);return{source:e.source,label:e.label,text:n==null?Ss(e.usd.spentUsd):`${n}%`,unit:``,hot:xs(e,t),reading:e}}return null}function ws(e,t=3,n=80){let r=new Set,i=[];for(let t of e??[]){if(!t||r.has(t.source))continue;let e=Cs(t,n);e&&(r.add(t.source),i.push(e))}let a=e=>bs(e.reading)??-1;i.sort((e,t)=>e.source===`claude`?t.source===`claude`?0:-1:t.source===`claude`?1:a(t)-a(e)||e.label.localeCompare(t.label));let o=Math.max(1,Math.floor(t)),s=i.slice(0,o),c=i.slice(o).map(e=>e.label);return c.length&&(s[s.length-1]={...s[s.length-1],hidden:c}),{segments:s,hidden:c,total:i.length}}var Ts=e=>String(e).padStart(2,`0`);function Es(e){let t=Math.max(0,Math.round(e/6e4));if(t<1)return`now`;if(t<60)return`${t}m`;let n=Math.floor(t/60);return n<24?t%60?`${n}h ${t%60}m`:`${n}h`:`${Math.floor(n/24)}d`}function Ds(e){let t=Math.max(0,Math.round(e/1e3));if(t<60)return`${t}s ago`;let n=Math.round(t/60);if(n<60)return`${n}m ago`;let r=Math.round(n/60);return r<24?`${r}h ago`:`${Math.round(r/24)}d ago`}function Os(e,t){let n=new Date(e);return e-t<=72e6?`${Ts(n.getHours())}:${Ts(n.getMinutes())}`:n.toLocaleDateString(`en-US`,{month:`short`,day:`numeric`})}var ks={session:`5-hour session`,week:`week`};function As(e,t=Date.now()){let n=[];for(let r of e.windows){let i=L(r);if(i==null)continue;let a=e.source===`claude`?ks[r.id]??r.id:r.id,o=typeof r.used==`number`&&typeof r.limit==`number`?` (${r.used} / ${r.limit}${r.unitName?` ${r.unitName}`:``})`:``,s=r.resetAt!=null&&r.resetAt>t?` · resets ${Os(r.resetAt,t)} (in ${Es(r.resetAt-t)})`:``;n.push(`${a} ${i}%${o}${s}`)}if(gs(e)&&e.usd){let r=e.usd.capUsd!=null&&e.usd.capUsd>0?` of ${Ss(e.usd.capUsd)}`:``,i=e.usd.resetAt!=null&&e.usd.resetAt>t?` · resets ${Os(e.usd.resetAt,t)} (in ${Es(e.usd.resetAt-t)})`:``;n.push(`${e.usd.label} ${Ss(e.usd.spentUsd)}${r}${i}`)}let r=`${e.label} usage`,i=Number.isFinite(e.checkedAt)&&e.checkedAt>0?` · checked ${Ds(t-e.checkedAt)}${e.remembered?` (kept from before a restart)`:``}`:``;return`${r}${n.length?` — ${n.join(` · `)}`:``}${i}`}function js(){return`No 5-hour window on this plan: claude's /usage shows only the weekly limit. The 5-hour figure comes back by itself if /usage shows it again.`}var Ms=[`prompt`,`approval`,`limit`,`signin`,`burn`,`cli`,`disk`,`undelivered`,`backlog`,`followup`,`health`,`agent`,`artifact`,`image`,`plugin`,`autofire`,`idle`,`info`,`weekburn`,`git`,`exposure`],Ns=[`idle`];function Ps(e,t){let n=e?.[t];return typeof n==`boolean`?n:!Ns.includes(t)}var Fs=[`prompt`,`approval`,`signin`,`cli`,`disk`,`undelivered`,`followup`];function Is(e,t,n){return n===`attention`||n===`info`?n:t===`failed`?`attention`:t===`ok`?`info`:Fs.includes(e)?`attention`:`info`}function Ls(e){return e.level===`attention`||e.level===`info`?e.level:Is(e.kind)}function Rs(e){return Ls(e)===`attention`&&!e.handled}function zs(e){return e?.kind===`git`||e?.kind===`build`}function Bs(e){if(typeof e!=`string`)return null;let t=/^(git|build|pr):(.+):([^:]+)$/.exec(e);return t?t[1]===`build`?{kind:`build`,repoId:t[2],buildId:t[3]}:t[1]===`pr`?/^[1-9]\d*$/.test(t[3])?{kind:`pr`,repoId:t[2],number:Number(t[3])}:null:t[3]===`pull`||t[3]===`push`?{kind:`git`,repoId:t[2],verb:t[3]}:null:null}function Vs(e,t){return e===`push`&&t?`push of ${t}`:e}var Hs=`view:notifications`;function Us(e){if(!e.startsWith(`notif:`))return null;try{let t=JSON.parse(e.slice(6));return!t||typeof t!=`object`||typeof t.id!=`string`||typeof t.title!=`string`||typeof t.kind!=`string`?null:{...t,body:typeof t.body==`string`?t.body:``,ts:typeof t.ts==`number`?t.ts:Date.now()}}catch{return null}}var Ws={enabled:!1,scope:`outbox`,match:[],maxBytes:268435456,builds:!0,supersede:!0},Gs=e=>(/^\d{4}-\d{2}-\d{2}/.exec(String(e))??[String(e)])[0],Ks=e=>e.by?.kind===`agent`?`agent session${e.by.repo?` in ${e.by.repo}`:``}`:`you`;function qs(e){return e.state===`fixed`?`fixed${e.fixedIn?` in ${e.fixedIn}`:``}${e.commit?` (commit ${e.commit})`:``}, ${Ks(e)}, ${Gs(e.at)}${e.note?`: ${e.note}`:``}`:`${e.state} \u2014 ${Ks(e)}, ${Gs(e.at)}${e.note?`: ${e.note}`:``}`}var Js=`exposure`,Ys=`era-seen`,Xs=e=>e.watch===!0||!!e.exposure||e.id===`exposure`;function Zs(e){return e.scope!==`host`&&e.status!==`pass`&&!e.advisory&&!e.ignored&&!e.accepted}function Qs(e){return e.scope!==`host`&&e.status!==`pass`&&!!e.advisory&&!e.ignored&&!e.accepted}var $s=[`instructions`,`skill_listing`,`mcp_instructions`,`deferred_tools`,`agent_listing`,`hook_context`,`system_prompt`,`tool_schemas`];function ec(e){let t=e=>e.split(`
4
+ `).map(e=>` ${e}`).join(`
5
+ `),n=e=>e?new Date(e).toLocaleTimeString([],{hour:`2-digit`,minute:`2-digit`}):``,r=[];for(let i of e.turns){let e=n(i.sentAt);r.push(`\u2500\u2500 #${i.n}${e?` \u00b7 ${e}`:``} \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500`),i.prompt.trim()&&r.push(i.prompt.trim().split(`
6
+ `).map(e=>`> ${e}`).join(`
7
+ `));for(let e of i.blocks)if(e.kind===`screen`){if(!e.text.trim())continue;r.push(``,t(e.text.trimEnd()))}else if(e.kind===`text`||e.kind===`thinking`){if(!e.text.trim())continue;r.push(``,e.kind===`thinking`?`[thinking]\n${t(e.text.trim())}`:e.text.trim())}else r.push(``,`[${e.name}]${e.label?` ${e.label}`:``}${e.ok===!1?` — FAILED`:``}`),e.input&&r.push(t(e.input)),e.result?r.push(t(e.result+(e.resultTruncated?`
8
+ …(truncated)`:``))):e.omitted&&r.push(` (input and result not loaded — open the call in the reader first)`);r.push(``)}let i=r.join(`
9
+ `).replace(/\n{3,}/g,`
10
+
11
+ `).trim();return/[^\s\u2500]/.test(i)?i:``}function tc(e){return JSON.stringify(e)}function nc(e){return JSON.parse(e)}var rc={on:!0,warnPct:2,highPct:5,warnUsd:30,highUsd:75},ic=(e,t)=>typeof e==`number`&&Number.isFinite(e)&&e>0&&e<=t?e:null;function ac(e){let t=e&&typeof e==`object`?e:{},n=rc,r=ic(t.warnPct,100)??n.warnPct,i=ic(t.highPct,100)??n.highPct;i>r||(r=n.warnPct,i=n.highPct);let a=ic(t.warnUsd,1e6)??n.warnUsd,o=ic(t.highUsd,1e6)??n.highUsd;return o>a||(a=n.warnUsd,o=n.highUsd),{on:t.on!==!1,warnPct:r,highPct:i,warnUsd:a,highUsd:o}}var oc=e=>`${Number(e.toPrecision(2))}%`;function sc(e,t,n){if(!n.on||e==null||!Number.isFinite(e)||!(e>0))return null;if(t!=null&&Number.isFinite(t)&&t>0){let r=e/t,i=r>=n.highPct?`high`:r>=n.warnPct?`warn`:null;if(!i)return null;let a=i===`high`?n.highPct:n.warnPct;return{level:i,by:`week`,at:a,text:`This session has spent ≈${oc(r)} of the week (${x(e)} at list prices) — past your ${i===`high`?`red`:`orange`} mark at ${oc(a)}.`}}let r=e>=n.highUsd?`high`:e>=n.warnUsd?`warn`:null;if(!r)return null;let i=r===`high`?n.highUsd:n.warnUsd;return{level:r,by:`usd`,at:i,text:`This session has spent ${x(e)} at list prices — past your ${r===`high`?`red`:`orange`} mark at ${Je(i)} (no weekly limit reading to measure it against).`}}var cc=e=>typeof e==`number`&&Number.isFinite(e);function lc(e,t){let n=e.firstSentAt;return cc(n)?{...e,sentAt:t}:e}function uc(e,t){let n=e;return typeof n.ackId!=`string`||cc(n.firstSentAt)?e:{...e,firstSentAt:t}}var dc=[`/api`,`/ws`],fc=`Not protected: nothing proves this address is your desktop, so someone on this network could read what you send and could take over your desktop. Use it only on a network you trust, or reach the desktop over the tailnet.`,pc=`This Wi-Fi route is not protected: fingerprint approvals and app updates are off until you are back on the tailnet.`,mc=`Fingerprint approvals are off on this route: nothing proves it reaches your desktop, so someone on this network could fake what you approve. Reach the desktop over the tailnet (Network health › change LAN settings), then approve.`,hc=`App updates wait for the tailnet: nothing proves this route reaches your desktop, so someone on this network could swap the update.`,gc=`Apps do not download or install on this route: nothing proves it reaches your desktop, so someone on this network could swap the app. Reach the desktop over the tailnet, then try again.`,_c=`The reader's files do not download on this route: nothing proves it reaches your desktop, so someone on this network could swap them. Reach the desktop over the tailnet, then try again.`;function vc(e){return e===`localhost`||e.endsWith(`.localhost`)||e===`::1`||/^127\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(e)}function yc(e){if(e.startsWith(`fd7a:115c:a1e0:`))return!0;let t=/^100\.(\d{1,3})\.\d{1,3}\.\d{1,3}$/.exec(e);return!!t&&Number(t[1])>=64&&Number(t[1])<=127}function R(e,t={}){if(!e)return!1;let n;try{n=new URL(e)}catch{return!0}let r=n.protocol===`https:`||n.protocol===`wss:`;if(!r&&n.protocol!==`http:`&&n.protocol!==`ws:`)return!0;let i=n.hostname.toLowerCase().replace(/^\[|\]$/g,``);return vc(i)||r&&t.trusted?!1:t.tailnet===!1||!(i.endsWith(`.ts.net`)||!r&&yc(i))}function bc(e){return e.startsWith(`https:`)&&R(e)}function xc(e){return!R(e)&&R(e,{tailnet:!1})}function Sc(e,t){if(!t||!Number.isInteger(t.port)||t.port<1||t.port>65535)return e;let n;try{n=new URL(e)}catch{return e}return n.protocol!==`http:`||!R(e)?e:z(`https://${n.hostname}:${t.port}`)??e}function z(e){let t=(e||``).trim();if(!t)return null;let n=/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(t)?t:`http://${t.replace(/^\/+/,``)}`,r;try{r=new URL(n)}catch{return null}if(r.protocol!==`http:`&&r.protocol!==`https:`||!r.hostname)return null;let i=r.hostname.toLowerCase(),a=i.includes(`:`)?`[${i.replace(/^\[|\]$/g,``)}]`:i,o=r.port||(r.protocol===`http:`?`8770`:``);return`${r.protocol}//${a}${o?`:${o}`:``}`}function Cc(e){return!e.startsWith(`/`)||e.startsWith(`//`)?!1:dc.some(t=>e===t||e.startsWith(`${t}/`)||e.startsWith(`${t}?`))}function wc(e,t){return!e||!Cc(t)?t:`${uo(e,`/`)}${t}`}function Tc(e,t=`/ws`){if(!e)return null;let n=uo(e,`/`);return n.startsWith(`https://`)?`wss://${n.slice(8)}${t}`:n.startsWith(`http://`)?`ws://${n.slice(7)}${t}`:null}var Ec=`legacy`,Dc=`abcdefghijklmnopqrstuvwxyz0123456789`,Oc=`${O.storagePrefix}h.`,kc=O.storagePrefix,Ac=k.map(e=>e.storagePrefix),B=e=>{let t=globalThis.crypto;if(!t?.getRandomValues)throw Error(`no crypto.getRandomValues in this runtime`);return t.getRandomValues(new Uint8Array(e))};function jc(e,t,n=B){let r=256-256%e.length,i=``;for(;i.length<t;)for(let a of n(t*2))if(!(a>=r)&&(i+=e[a%e.length],i.length===t))break;return i}function Mc(e){return typeof e==`string`&&/^[a-z0-9]{4,16}$/.test(e)}function Nc(e=[],t=B){let n=new Set(e);for(;;){let e=jc(Dc,8,t);if(!n.has(e)&&e!==`legacy`)return e}}function Pc(e,t){if(typeof e!=`string`)return null;let n=e.replace(/[\u0000-\u001f\u007f]/g,` `).replace(/\s+/g,` `).trim();return n?[...n].slice(0,t).join(``).trim():null}function Fc(e){return Pc(e,40)}function Ic(e){let t=e;try{t=new URL(e).hostname}catch{}return t=t.replace(/^\[|\]$/g,``),/^[0-9.]+$/.test(t)||t.includes(`:`)?t:t.split(`.`)[0]||t}function Lc(e){if(typeof e!=`string`)return null;let t=e.trim();return t.length>=2&&t.startsWith(`"`)&&t.endsWith(`"`)&&(t=t.slice(1,-1)),!t||t===`<unknown ssid>`||/[\u0000-\u001f]/.test(t)?null:[...t].slice(0,64).join(``)}function Rc(e){if(!Array.isArray(e))return[];let t=[];for(let n of e){let e=Lc(n);if(e&&!t.includes(e)&&t.push(e),t.length>=16)break}return t}function zc(e){if(!e||typeof e!=`object`)return null;let t=e,n=typeof t.base==`string`?z(t.base):null;return n?{base:n,ssids:Rc(t.ssids),auto:t.auto===!0}:null}function Bc(e){if(!e||typeof e!=`object`)return null;let{port:t,spki:n}=e;return typeof t!=`number`||!Number.isInteger(t)||t<1||t>65535?null:typeof n==`string`&&/^[0-9a-f]{64}$/.test(n)?{port:t,spki:n}:null}function Vc(e){if(!e||typeof e!=`object`)return null;let{key:t,gen:n}=e;return typeof t!=`string`||!/^[A-Za-z0-9+/]{16,1024}={0,2}$/.test(t)?null:typeof n==`number`&&Number.isSafeInteger(n)&&n>=0?{key:t,gen:n}:null}function Hc(e,t,n){return n===void 0||!t.startsWith(`https:`)?!1:z(n)!==t||e?.vouched===!0&&e.base===t}function Uc(e){return e.base.startsWith(`https:`)&&!e.vouched&&R(e.base)}function Wc(e){if(!e||typeof e!=`object`)return null;let t=e;if(!Mc(t.id))return null;let n=typeof t.base==`string`?z(t.base):null;if(!n)return null;let r={id:t.id,name:Fc(t.name)??Ic(n),base:n};t.legacy===!0&&(r.legacy=!0);let i=zc(t.lan);i&&(r.lan=i),Mc(t.hostId)&&(r.hostId=t.hostId);let a=t.tlsOff===!0?null:Bc(t.tls);a&&(r.tls=a),t.tlsOff===!0&&(r.tlsOff=!0),t.vouched===!0&&n.startsWith(`https:`)&&(r.vouched=!0);let o=Vc(t.updateKey);return o&&(r.updateKey=o),r}function Gc(e){if(!Array.isArray(e))return[];let t=[],n=!1;for(let r of e){let e=Wc(r);if(e&&!t.some(t=>t.id===e.id)&&(e.legacy&&(n&&delete e.legacy,n=!0),t.push(e),t.length>=32))break}return t}function Kc(e){if(e==null)return null;try{let t=JSON.parse(e);return Array.isArray(t)?Gc(t):null}catch{return null}}function qc(e){return JSON.stringify(e)}function Jc(e){return!e||e.legacy?O.cacheName:`${O.cacheName}.${e.id}`}function Yc(e){return k.map(t=>!e||e.legacy?t.cacheName:`${t.cacheName}.${e.id}`)}function Xc(e){let t={},n=Kc(e.hosts);if(!n||n.length===0){let r=e.hostBase?z(e.hostBase):null;if(!r)return{hosts:n??[],activeId:null,writes:t};n=[{id:Ec,name:Ic(r),base:r,legacy:!0}],t.hosts=qc(n)}let r=n.find(t=>t.id===e.active)??n[0];return e.active!==r.id&&(t.active=r.id),e.hostBase!==r.base&&(t.hostBase=r.base),{hosts:n,activeId:r.id,writes:t}}function Zc(e){return`${Oc}${e}.`}function Qc(e){return e.startsWith(Oc)}function $c(e,t){return Zc(t)+e.slice(kc.length)}function el(e,t){let n=Zc(t);return e.startsWith(n)&&e.length>n.length?kc+e.slice(n.length):null}function tl(e,t){return e.startsWith(kc)&&!Qc(e)&&!t(e)}function nl(e,t,n,r){let i=[],a=e.filter(e=>tl(e,t)),o=new Set(a),s=Zc(n);for(let e of a)i.push({op:`copy`,from:e,to:$c(e,n)});if(n!==r&&a.length>0)for(let t of e){if(!t.startsWith(s))continue;let e=el(t,n);e&&!o.has(e)&&i.push({op:`remove`,key:t})}if(n===r)return i;for(let e of a)i.push({op:`remove`,key:e});for(let n of e){let e=el(n,r);e&&!t(e)&&i.push({op:`copy`,from:n,to:e})}return i}var rl=1500;function V(e,t,n=null){return{route:`tailnet`,reason:e,sentence:t,next:n}}function il(e,t){return!!t&&!!e.lan&&e.lan.ssids.includes(t)}function al(e){let{host:t,net:n,probe:r,macVerified:i,lastFailure:a}=e,o=t.lan;if(!o)return V(`no-lan`,`Using the tailnet: no LAN address saved for this desktop.`);if(!o.auto)return V(`auto-off`,`Using the tailnet: switching to LAN automatically is off.`);if(!n)return V(`no-net`,`Using the tailnet: this phone did not report which network it is on.`);if(n.transport!==`wifi`)return V(`not-wifi`,`Using the tailnet: the phone is ${n.transport===`cellular`?`on mobile data`:n.transport===`none`?`offline`:`not on Wi-Fi`}.`);if(n.permission!==`granted`)return V(`no-permission`,`Using the tailnet: reading the Wi-Fi name needs the location permission.`);if(!n.ssid)return V(`no-ssid`,`Using the tailnet: the Wi-Fi name could not be read.`);if(!il(t,n.ssid))return V(`ssid-mismatch`,`Using the tailnet: "${n.ssid}" is not one of this desktop's saved networks.`);if(a&&(!r||r.at<=a.at))return V(`failed-recently`,`Using the tailnet: the LAN connection failed${a.reason?` (${a.reason})`:``}; it is tried again on the next network change or reconnect.`,`probe`);if(!r)return V(`probe-pending`,`Using the tailnet while ${o.base} is checked.`,`probe`);if(!r.ok)return V(`probe-failed`,`Using the tailnet: ${o.base} did not answer on "${n.ssid}".`);if(r.ms!=null&&r.ms>1500)return V(`probe-slow`,`Using the tailnet: ${o.base} took ${Math.round(r.ms)} ms, over the ${rl} ms limit.`);if(i===null)return V(`mac-pending`,`Using the tailnet while ${o.base} proves it is this desktop.`,`verify`);if(!i)return V(`mac-failed`,`Using the tailnet: whatever answers at ${o.base} could not prove it is this desktop.`);let s=r.ms==null?``:` in ${Math.round(r.ms)} ms`;return{route:`lan`,reason:`lan-ok`,sentence:`Using LAN: on "${n.ssid}", ${o.base} answered${s} and proved it is this desktop.`,next:null}}function ol(e,t){return`${e}\n${t}`}var sl=`modulepreload`,cl=function(e){return`/`+e},ll={},ul=function(e){return e.pathname.endsWith(`.css`)},dl=function(e,t,n){if(t in e)return e[t];let r=n();if(!r){e[t]=void 0;return}let i=r.then(()=>{e[t]=void 0},n=>{throw e[t]=void 0,n});return e[t]=i,i},fl=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e,i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}function s(e){return import.meta.resolve?new URL(import.meta.resolve(e)):new URL(e,import.meta.url)}r=o(t.map(t=>{t=cl(t,n);let r=s(t),i=ul(r);return dl(ll,r.href,()=>{if(e===void 0){e={all:new Set,styles:new Set};let t=document.getElementsByTagName(`link`);for(let n=t.length-1;n>=0;n--){let r=t[n];e.all.add(r.href),r.rel===`stylesheet`&&e.styles.add(r.href)}}if((i?e.styles:e.all).has(r.href))return;let t=document.createElement(`link`);if(t.rel=i?`stylesheet`:sl,i||(t.as=`script`),t.crossOrigin=``,t.href=r.href,a&&t.setAttribute(`nonce`,a),document.head.appendChild(t),i)return new Promise((e,n)=>{t.addEventListener(`load`,e),t.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${r}`)))})})}).filter(e=>e!==void 0))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})},pl=`waterplane-cpace-v1`,ml=12,H=class extends Error{},hl=new TextEncoder;function U(){let e=globalThis.crypto?.subtle;if(!e)throw new H(`This page has no WebCrypto, so it cannot pair securely. Open it over https or use the app.`);return e}var W=e=>new Uint8Array(e);function G(e){let t=new Uint8Array(4+e.length);return new DataView(t.buffer).setUint32(0,e.length),t.set(e,4),t}function gl(...e){let t=new Uint8Array(e.reduce((e,t)=>e+t.length,0)),n=0;for(let r of e)t.set(r,n),n+=r.length;return t}function K(e){let t=``;for(let n of e)t+=String.fromCharCode(n);return btoa(t)}function _l(e,t){if(typeof e!=`string`||!/^[A-Za-z0-9+/]*={0,2}$/.test(e))return null;let n;try{n=atob(e)}catch{return null}let r=new Uint8Array(n.length);for(let e=0;e<n.length;e++)r[e]=n.charCodeAt(e);return K(r)===e&&(t===void 0||r.length===t)?r:null}async function vl(e){return new Uint8Array(await U().digest(`SHA-256`,W(e)))}async function yl(e){return new Uint8Array(await U().digest(`SHA-512`,W(e)))}var bl=null;function xl(){return bl??=fl(async()=>{let{ristretto255:e,ristretto255_hasher:t}=await import(`./noble-DV-r0OkE.js`).then(e=>e.t);return{ristretto255:e,ristretto255_hasher:t}},__vite__mapDeps([0,1])).then(({ristretto255:e,ristretto255_hasher:t})=>({fromBytes:t=>e.Point.fromBytes(t),hash:e=>t.hashToCurve(e,{DST:hl.encode(pl)}),order:e.Point.Fn.ORDER})),bl}async function Sl(e){if(e.length!==32)throw new H(`A key share is the wrong length.`);let t=await xl(),n;try{n=t.fromBytes(e)}catch{throw new H(`A key share is not a canonical group element.`)}if(n.is0())throw new H(`A key share is the identity element.`);return n}function Cl(e){return vl(hl.encode(e))}async function wl(e){let{order:t}=await xl();for(;;){let n=0n;for(let t of e(64))n=n<<8n|BigInt(t);let r=n%t;if(r!==0n)return r}}async function Tl(e,t,n=B){let r=await xl(),i=await wl(n);return{scalar:i,share:r.hash(gl(G(e),G(t))).multiply(i).toBytes()}}function El(e,t,n,r){return yl(gl(G(hl.encode(pl)),G(e),G(t),G(n),G(r)))}async function Dl(e,t){let n=(await Sl(t)).multiply(e);if(n.is0())throw new H(`The shared point is the identity element.`);return n.toBytes()}async function Ol(e,t,n){let r=U(),i=await r.importKey(`raw`,W(e),`HKDF`,!1,[`deriveBits`]);return new Uint8Array(await r.deriveBits({name:`HKDF`,hash:`SHA-256`,salt:W(t),info:hl.encode(n)},i,256))}async function kl(e,t){let[n,r,i]=await Promise.all([Ol(e,t,`K_phone`),Ol(e,t,`K_box`),Ol(e,t,`K_seal`)]);return{kPhone:n,kBox:r,kSeal:i}}async function Al(e,t){let n=U(),r=await n.importKey(`raw`,W(e),{name:`HMAC`,hash:`SHA-256`},!1,[`sign`]);return new Uint8Array(await n.sign(`HMAC`,r,W(t)))}async function jl(e,t,n,r){let i=U(),a=await i.importKey(`raw`,W(e),`AES-GCM`,!1,[`encrypt`]),o=W(r(ml)),s=await i.encrypt({name:`AES-GCM`,iv:o,additionalData:W(t)},a,W(hl.encode(JSON.stringify(n))));return K(gl(o,new Uint8Array(s)))}async function Ml(e,t,n){let r=_l(n);if(!r||r.length<=ml)return null;let i=U(),a=await i.importKey(`raw`,W(e),`AES-GCM`,!1,[`decrypt`]);try{let e=await i.decrypt({name:`AES-GCM`,iv:W(r.subarray(0,ml)),additionalData:W(t)},a,W(r.subarray(ml)));return JSON.parse(new TextDecoder().decode(e))}catch{return null}}var Nl=(e,t,n,r=B)=>jl(e,t,n,r),Pl=(e,t,n)=>Ml(e,t,n);async function Fl(e,t=B){let n=t(16),{scalar:r,share:i}=await Tl(await Cl(e),n,t);return{state:{sidP:n,ya:i,scalar:r},request:{sidP:K(n),ya:K(i)}}}async function Il(e,t,n,r=B){let i=_l(t.nh,16);if(!i)throw new H(`The desktop's reply is malformed.`);if(!Array.isArray(t.yb)||t.yb.length===0||t.yb.length>5)throw new H(`The desktop offered the wrong number of key shares.`);let a=[],o=[],s=[];for(let c of t.yb){let t=_l(c,32);if(!t)throw new H(`A key share is malformed.`);let l=await Dl(e.scalar,t),u=await El(e.sidP,i,e.ya,t),{kPhone:d,kBox:f,kSeal:p}=await kl(l,u);a.push(K(await Al(d,u))),o.push(await Nl(f,u,n,r)),s.push({kSeal:p,th:u})}return{request:{sidP:K(e.sidP),confirm:a,box:o},candidates:s}}async function Ll(e,t){for(let n of e){let e=await Pl(n.kSeal,n.th,t);if(e!==null)return e}return null}var Rl=6e5,zl=O.pairScheme,Bl=k.map(e=>e.pairScheme);function Vl(e){if(typeof e!=`string`)return null;let t=e.replace(/[\s-]/g,``).toUpperCase();if(t.length!==8)return null;for(let e of t)if(!`23456789ABCDEFGHJKLMNPQRSTUVWXYZ`.includes(e))return null;return t}function Hl(e){return e.length===8?`${e.slice(0,4)}-${e.slice(4)}`:e}var Ul=32,Wl=e=>Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``);function Gl(e){return e.length%2!=0||!/^[0-9a-f]*$/.test(e)?null:Uint8Array.from(e.match(/../g)??[],e=>parseInt(e,16))}async function Kl(e,t){let n=_l(e),r=t===void 0?new Uint8Array:typeof t==`string`?Gl(t):null;if(!n||n.length===0||!r||t!==void 0&&r.length!==32)return null;let i=new Uint8Array(n.length+r.length);return i.set(n),i.set(r,n.length),Wl(await vl(i)).slice(0,Ul)}function ql(e){if(typeof e!=`string`)return null;let t=[zl,...Bl].map(e=>e.replace(/[^a-z0-9+.-]/gi,``)).join(`|`),n=RegExp(`^(?:${t})://pair/?\\?(.*)$`,`i`).exec(e.trim());if(!n)return null;let r;try{r=new URLSearchParams(n[1])}catch{return null}let i=z(r.get(`u`)??``),a=Vl(r.get(`c`));if(!i||!a)return null;let o=r.get(`k`);if(o!==null&&!RegExp(`^[0-9a-f]{${Ul}}$`).test(o))return null;let s=z(r.get(`l`)??``);return{base:i,code:a,...r.get(`s`)===`1`?{secure:!0}:{},...o===null?{}:{commit:o},...s?{lan:s}:{}}}function Jl(e){let t=/^\/pair\/([^/]+)(\/apk)?\/?$/.exec(e);if(!t)return null;let n;try{n=decodeURIComponent(t[1])}catch{return null}let r=Vl(n);return r?{code:r,apk:!!t[2]}:null}function Yl(e){if(typeof e!=`string`)return null;let t;try{t=new URL(e.trim())}catch{return null}if(t.protocol!==`http:`&&t.protocol!==`https:`)return null;let n=Jl(t.pathname);if(!n||n.apk)return null;let r=z(`${t.protocol}//${t.host}`);return r?{base:r,code:n.code}:null}function Xl(e){return ql(e)??Yl(e)}function Zl(e){switch(e){case`closed`:return`Too many wrong attempts closed encrypted pairing for this code. Show a new code on the desktop.`;case`no-codes`:return`The desktop has no pairing code showing. Show a new code and try again.`;case`no-session`:return`That pairing attempt ran out of time. Try again.`;default:return Ql(e)}}function Ql(e){switch(e){case`bad-request`:return`That is not a pairing code — it is 8 letters and digits.`;case`unknown`:return`The desktop does not know that code. Check it, or show a new QR.`;case`expired`:return`That code has expired (they last 10 minutes). Show a new QR on the paired phone.`;case`used`:return`That code was already used. Show a new QR on the paired phone.`;case`rate-limited`:return`Too many attempts. Wait a minute and try again.`;case`no-password`:return`This desktop has no password set, so it refuses pairing over the Wi-Fi. Pair over Tailscale instead.`;default:return`The desktop refused that code for a reason this app version cannot name. Show a new QR and try again.`}}function $l(e){return typeof e==`string`&&/^[A-Za-z0-9_-]{6,64}$/.test(e)}function eu(e){return Pc(e,40)}var tu=[`loopback`,`tailscale`,`lan`,`public`,`unknown`];function nu(e){return typeof e==`number`&&Number.isFinite(e)&&e>0?e:null}function ru(e){if(!e||typeof e!=`object`)return null;let t=e;if(!$l(t.id))return null;let n=eu(t.name),r=nu(t.createdAt);if(!n||r==null)return null;let i=nu(t.lastSeenAt)??r,a=tu.includes(t.lastKind)?t.lastKind:null,o={id:t.id,name:n,createdAt:r,lastSeenAt:i,lastKind:a};return t.current===!0&&(o.current=!0),t.scope===`passive`&&(o.scope=`passive`),o}function iu(e){return[...e].sort((e,t)=>Number(!!t.current)-Number(!!e.current)||t.lastSeenAt-e.lastSeenAt)}function au(e){if(typeof e!=`string`)return null;let t=e.trim();return RegExp(`^[0-9]{4,12}$`).test(t)?t:null}function ou(e,t=0){switch(e){case`not-passive`:return`This device is not a passive device, so there is nothing to unlock.`;case`no-pin`:return`No unlock PIN is set on the desktop. Set one from a trusted phone: Settings › Connection › Passive devices.`;case`wrong-pin`:return`Wrong PIN.`;case`rate-limited`:return`Too many tries. Try again in ${Math.max(1,Math.ceil(t/60))} min.`;case`bad-request`:return`A PIN is 4–12 digits.`;default:return`The desktop refused the unlock for a reason this app version cannot name.`}}function su(e){return/\.apk$/i.test(e.name)||/\.apk$/i.test(e.relPath)}function cu(e,t=Date.now()){if(!(e>t))return null;let n=new Date(e),r=e=>String(e).padStart(2,`0`);return`Unlocked until ${r(n.getHours())}:${r(n.getMinutes())}`}var lu=`Pairing a passive device switches on "require the password over Tailscale", so every device needs its own token on Tailscale too — sign in again on any browser that has none.`,uu=[`Bash(git push --force*)`,`Bash(git push -f*)`,`Bash(git push * --force*)`,`Bash(git push * -f*)`,`Bash(git push * main)`,`Bash(git push * main *)`,`Bash(git push * master)`,`Bash(git push * master *)`,`Bash(gcloud run deploy *)`,`Bash(gcloud app deploy *)`,`Bash(vercel --prod*)`,`Bash(vercel * --prod*)`,`Bash(fly deploy*)`,`Bash(gh release create*)`,`Bash(gh pr merge*)`,`Bash(npm publish*)`,`Bash(terraform apply*)`,`Bash(kubectl apply*)`],du=[`claude`,`claude-local`,`claude-endpoint`],fu=/[\u0000-\u001f\u007f]/,pu=/^[A-Za-z][A-Za-z0-9_-]*(?:\(.+\))?$/;function mu(e){if(typeof e!=`string`)return null;let t=e.trim();return!t||t.length>200||fu.test(t)||!pu.test(t)?null:t}function hu(e){let t=2166136261;for(let n=0;n<e.length;n++)t^=e.charCodeAt(n),t=Math.imul(t,16777619)>>>0;return`r${t.toString(36)}`}var gu=e=>e.replace(/\s+/g,` `).trim();function _u(e){return vu([e.kind,e.multi?`multi`:`single`,gu(e.question),...e.options.map(e=>`${e.index}\u0000${gu(e.label)}`),...e.nav?[`nav`]:[],...e.freeText?[`text`]:[]].join(``))}function vu(e){let t=2166136261;for(let n=0;n<e.length;n++)t^=e.charCodeAt(n),t=t+((t<<1)+(t<<4)+(t<<7)+(t<<8)+(t<<24))>>>0;return t.toString(16).padStart(8,`0`)}var yu=1e3;function bu(e){if(typeof e!=`string`||!e.trim())return`the answer has no words in it`;if(e.length>1e3)return`the answer is ${e.length} characters, and a typed answer is at most ${yu}`;for(let t=0;t<e.length;t++){let n=e.charCodeAt(t);if(n<32||n>=127&&n<160)return`the answer holds a control character (0x${n.toString(16).padStart(2,`0`)}) — a typed answer is one line of words`}return null}function xu(e,t){return!!e&&_u(e)===t}var Su=[A(`snippets`),A(`headerCmds`),A(`fanout.presets`),A(`toolbar`),A(`launch`),A(`launchAsk`),A(`spendWarn`),A(`pad`),A(`hiddenRepos`),A(`enterSends`),A(`dictate.terms`),A(`autoSend`),A(`updates.autoCheck`),A(`serialSessions`),A(`confirmQueue`),A(`confirmClose`),A(`readerTools`),A(`annKnobs`),A(`annTools`),A(`hints`),A(`repoColors`),A(`installAllow`),A(`backlog.closeWhenDone`),A(`local.maxSessions`),A(`agentWarn`),A(`agentWindowWarn`),A(`tabsShared.order`),A(`tabsShared.opens`)];A(`local.maxSessions`),A(`agentWindowWarn`);function Cu(e){let t=(e??``).trim();if(!/^\d{1,7}$/.test(t))return mt;let n=Number(t);return n>=5e4&&n<=2e6?n:mt}A(`backlog.closeWhenDone`);function wu(e){return Su.includes(e)}var Tu=[{id:`spectrum`,label:`Spectrum`,note:`Twelve hues round the whole circle, at least 28° apart.`,hues:[200,228,256,284,312,340,8,36,64,92,130,168]},{id:`cool`,label:`Cool`,note:`Green through violet — eight hues, nothing warmer than a jade.`,hues:[100,128,156,184,208,232,260,288]},{id:`warm`,label:`Warm`,note:`Magenta through amber — six hues, nothing colder than a gold.`,hues:[300,330,356,20,46,76]},{id:`cvd`,label:`Colour-blind safe`,note:`Six hues that survive simulated colour blindness — fewer colours, none confusable.`,hues:[204,30,178,348,60,248]}],Eu=`spectrum`;function Du(e){return Tu.find(t=>t.id===e)??Tu[0]}var Ou={palette:Eu,by:{}};function ku(e){return typeof e!=`number`||!Number.isFinite(e)?null:(Math.round(e)%360+360)%360}function Au(e){let t=e&&typeof e==`object`?e:{},n=Du(typeof t.palette==`string`?t.palette:void 0).id,r={},i=t.by&&typeof t.by==`object`?t.by:{};for(let[e,t]of Object.entries(i)){if(!e)continue;let n=ku(t);n!=null&&(r[e]=n)}return{palette:n,by:r}}function ju(e){let t=0;for(let n=0;n<e.length;n++)t=t*31+e.charCodeAt(n)>>>0;return t}function Mu(e,t){return t.hues[ju(e)%t.hues.length]}function Nu(e,t){let n=t.by[e];return typeof n==`number`?n:Mu(e,Du(t.palette))}function Pu(e,t){return typeof t.by[e]==`number`}function Fu(e,t,n){let r={...e.by};if(n==null)delete r[t];else{let i=ku(n);if(i==null)return e;r[t]=i}return{...e,by:r}}function Iu(e,t){return{...e,palette:Du(t).id}}function Lu(e,t){let n=new Map,r=[];for(let i of e){let e=Nu(i,t),a=n.get(e);a?a.push(i):(n.set(e,[i]),r.push(e))}return r.map(e=>n.get(e)).filter(e=>e.length>1)}function Ru(e,t,n){let r=Du(t.palette).hues,i=new Map;for(let r of e){if(r===n)continue;let e=Nu(r,t);i.set(e,(i.get(e)??0)+1)}let a=r[0],o=1/0;for(let e of r){let t=i.get(e)??0;t<o&&(a=e,o=t)}return a}function zu(e,t){let n=t,r=new Map;for(let t of e){let e=Nu(t,n);r.set(e,(r.get(e)??0)+1)}for(let i of e){if(Pu(i,t))continue;let a=Nu(i,n);if((r.get(a)??0)<=1)continue;let o=Ru(e,n,i);o!==a&&(r.set(a,(r.get(a)??1)-1),r.set(o,(r.get(o)??0)+1),n=Fu(n,i,o))}return n}var Bu={"queue.hold":{title:`Hold until the session can take it`,what:`Keeps this message in the queue until that session's turn has ended, no question box is open and it isn't blocked on a usage limit — then it goes on its own.`,when:`Text typed at a working agent lands in its composer mid-answer; text typed at an open question box answers the box instead of running. Holding avoids both. Exact for sessions that report turn boundaries, a guess from silence otherwise.`,confirm:!0},"queue.sendnow":{title:`Send it now, without waiting`,what:`Types the next queued message into this session immediately, instead of waiting for the turn to end. It drops the park on that message — and on anything queued AHEAD of it in the same session, because a session's queue is delivered in order and a held message behind it would hold this one too.`,when:`For when the turn has gone somewhere you did not expect and the follow-up is worth typing in mid-answer. It is refused, in words, when that session has a question box open or is blocked on a usage limit — prose typed into a dialog answers the dialog instead of running.`,confirm:!0},"queue.serial":{title:`Wait for this repo's other sessions`,what:`This row opens a session AND runs a prompt in it. With this on, it doesn't start until every other session in the same directory has finished its turn.`,when:`Several prompts queued for one repo would otherwise all open their own agent at once — one account's usage limit spent in parallel, nothing finished, and several agents editing the same files. Off means this one starts regardless. “Send this one now” also overrides it.`,confirm:!0},"queue.serialall":{title:`One session at a time per repo`,what:`The default for newly queued prompts that open a session: run them one after another within a repo, rather than all together.`,when:`Turn it off when you actually want the fan-out — usually you don't, because a fan-out belongs in separate worktrees, which this rule treats as separate repos anyway.`},"queue.retarget":{title:`Aim it at another session`,what:`Keeps the words, changes the destination — another live session, or a repo's backlog.`,when:`For when the session it was written for died, or the thought belongs to a different repo now. A fresh receipt id is minted, so it cannot collide with a verdict the host already recorded for the old one.`,confirm:!0},"queue.addprompt":{title:`Queue another prompt behind this one`,what:`This row OPENS a session. Prompts added here run inside it, one at a time — each delivered only after the one before has finished its turn.`,when:`Writing a plan with no link: “read the failing test” → “fix it” → “commit”. Queued as a chain rather than concatenated into one prompt.`,confirm:!0},"queue.restore":{title:`Put the text back in the message box`,what:`Takes it out of the queue and drops the words back into the composer, so you can rework them and send again.`,when:`Messages only. An action (fan out, run a build) and an answer to a question have no text worth pasting, so it is disabled for those.`},"queue.resend":{title:`Rewrite it and send it again`,what:`Opens the message in an editor, checks every file it names against the repo, the send queue and this phone, and sends it as a NEW message once you are happy with it.`,when:`For a send that gave up. Retrying re-sends the same words to the same place with the same attachments — which is exactly what already failed. By the time a link is back the words are often half wrong, and the photo behind them may have been dropped from the queue underneath, leaving text that points at a file nobody is sending.`,confirm:!0},"queue.sendone":{title:`Send this one now`,what:`Releases this message — and anything queued ahead of it for the SAME session, because one session is delivered strictly in order.`,when:`Other sessions stay held. If an attempt already failed, this is the retry.`},"queue.sendall":{title:`Send everything queued`,what:`Releases every message in the queue. Each session still takes them one at a time, in the order shown.`},"queue.retryall":{title:`Try every failed message again`,what:`Puts every message that gave up back in the queue with a fresh retry budget. Works with the link down — they go out when it is back.`,when:`A tunnel down for longer than a message is allowed to wait expires the whole backlog on the first reconnect, so the list is red all at once. Messages that were typed into a live session but never seen to submit are left out: re-sending one of those could type it twice, so it stays a per-message decision.`},"queue.remove":{title:`Discard this message`,what:`Drops it from the queue. It is never sent, and the text is gone unless you put it back in the message box first.`,danger:!0},"queue.more":{title:`The other actions`,what:`Reorder within this session, hold it until this session is free, aim it somewhere else, or put the text back in the box.`,when:`They live behind “⋯” because eight icons beside the message would leave no room to read the message.`},"queue.moveup":{title:`Move earlier`,what:`Sends it sooner within this session. Order only matters inside one session — different sessions are delivered at the same time.`},"queue.movedown":{title:`Move later`,what:`Sends it after the next one in this session.`},"compose.idle":{title:`Send when the agent is free`,what:`Queues the prompt and delivers it once this session's turn has ended — instead of typing it into a session that is mid-answer.`,when:`Same rule as the queue's hourglass. The plain send button delivers immediately, which is what you want when you are interrupting on purpose.`,confirm:!0},"compose.options":{title:`Where and when this goes`,what:`Opens the send sheet with what you have typed already in it: which session, a fresh session or a set of repos it is aimed at, and — in five answers — when it goes: now, when that session is free, at a time you pick, after another item finishes, or once its files have arrived. The button at the bottom always restates the whole decision before you press it.`,when:`Whenever “send” is not quite what you mean. The plain Send button stays one tap for the ordinary case; everything the old start, resend and schedule sheets used to ask lives here now, in the order you would ask it.`},"activity.open":{title:`Everything you have posted`,what:`One row per piece of work, for its whole life — waiting on this phone, held on the desktop, running, scheduled, finished, or failed. A row never disappears when its state changes; it changes what it says. Each one carries the repo its words were written for, so sending it again asks you nothing.`,when:`When you want to know what became of something. This replaces hunting through the queue, the backlog, the schedules and the network sheet for the same answer.`},"compose.cli":{title:`Type straight at the CLI`,what:`Turns the message box into a keyboard wired to the session: every key goes through as you press it, and the CLI echoes it on the screen above. Tap the terminal to bring the keyboard back up.`,when:`For driving the TUI — picking a file in /resume, walking a menu, answering a free-text box, typing “y”. Nothing is queued, confirmed or resent, so with the link down the keys are simply lost; a prompt you care about wants the normal send.`,confirm:!0},"toolbar:fork":{title:`Fork this conversation`,what:`Opens a SECOND session that continues this exact conversation from where it stands. The original keeps running and is untouched.`,when:`Trying a risky direction without losing the thread you already have.`,confirm:!0},"toolbar:companion":{title:`Companion shell`,what:`Opens a plain shell in this session's folder, as its own tab. It is temporary: closing this session closes the shell with it.`,when:`Running a command by hand next to the agent — a sudo step it asked for, a quick look at a log — without leaving a shell lying around afterwards.`},"toolbar:select":{title:`Copyable text`,what:`Dumps what is on the terminal screen into a plain text sheet you can select and copy. In reader view there is no terminal, so it dumps the conversation instead — from the offline cache, so it works with the link down.`,when:`A terminal grid fights text selection on a phone; this is the way out.`},"toolbar:clip":{title:`Send to the desktop clipboard`,what:`Puts this phone's clipboard contents onto the DESKTOP host's clipboard.`},"toolbar:shot":{title:`Screenshot the desktop`,what:`Captures the host's whole screen and shows it here.`},"toolbar:ctx":{title:`Context window`,what:`Runs /context in this session — how much of the model's window this conversation is using.`},"toolbar:usage":{title:`Cost`,what:`Runs /cost in this session.`},"toolbar:cpu":{title:`Desktop load`,what:`CPU and memory of the machine running the agent, as a toast.`},"toolbar:teleport":{title:`Teleport`,what:`Runs the CLI's /teleport command in this session.`},"toolbar:remote":{title:`Remote control`,what:`Runs the CLI's /remote-control command in this session.`},"toolbar:tasks":{title:`Tasks`,what:`Runs the CLI's /tasks command in this session.`},"toolbar:outline":{title:`Outline`,what:`A table of contents for this conversation: one row per prompt, with what it did and which files it touched. Tapping a row jumps there in the reader.`},"toolbar:sent":{title:`Sent commands`,what:`Everything this app typed into this session, when, whether the app or you decided it, and whether delivery actually worked.`,when:`Automation types through the same terminal a person does, so the scrollback alone cannot tell you who sent what.`},"toolbar:find":{title:`Find in this session`,what:`Searches the visible output, and separately the prompts recorded for this session.`},"toolbar:scrollback":{title:`Scrollback`,what:`Earlier terminal output, kept ON THIS DEVICE. Panning up in the terminal scrolls the agent's own screen and needs the connection; this reads the copy saved here, so it works with the tunnel down. Only as far back as this phone was watching.`},"toolbar:diff":{title:`Git`,what:`Status, diffs, staging, commit and push for this repo.`},"toolbar:files":{title:`Files`,what:`The gallery: what the agent has produced in this repo, and what you have sent it.`},"toolbar:browse":{title:`Browse the repo`,what:`The worktree as a folder tree — every file, not just the deliverables the gallery lists. Open one to read it, and edit it in place when that is quicker than asking.`,when:`A save carries the version you opened, so a file the agent rewrote in the meantime is refused rather than overwritten — and saving needs the link, since a write held until later would land on a file that has moved on.`},"toolbar:build":{title:`Builds`,what:`Named build commands for this repo, run WITHOUT a session — the way to still produce an APK while the agent is rate-limited.`},"toolbar:model":{title:`Model`,what:`Relaunches this session on a different model, resuming the same conversation.`},"limit.open":{title:`Blocked sessions`,what:`Lists every session stuck on something outside it — signed out, a network retry, out of credit, or the usage limit — grouped by reason, sign-in first.`,when:`These walls hit sessions as a group (an account or a link fails for all of them). One sign-in clears the first group; the usage-limit group is where you say which session resumes first.`},"compose.later":{title:`Run it at a time you pick`,what:`Hands the prompt to the schedule editor instead of sending it. It runs in THIS repo's backlog at the time you set — once, or every week.`,when:`The prompt box still holds your text until you save the schedule, so cancelling loses nothing. A scheduled prompt is aimed at the repo, not at this session: session ids do not survive a host restart.`,confirm:!0},"fanout.schedule":{title:`Run this sweep later`,what:`Takes the repos and the prompt you just composed into a schedule — once at a time you pick, or every week.`,when:`For the sweep that should run while you are asleep, or two hours before your weekly usage window rolls over and the leftover quota evaporates.`},"schedule.runnow":{title:`Run it now`,what:`Fires the schedule immediately — the same sweep, off the clock.`,when:`It does NOT use up the next scheduled run: testing Thursday's sweep on Tuesday still leaves Thursday armed.`},"schedule.session":{title:`Open the session this ran in`,what:`Jumps to the session this occurrence used, so you can read what it actually did.`,when:`Only where there IS one session to go to — a fan-out ran in N of them, and that is the fan-out view's job.`},"schedule.buildrun":{title:`Open the run this rule last started`,what:`Opens the repo's builds on the run this build rule started most recently, with its log and outcome.`,when:`The card says how that run ended and when, so a failed nightly build is one tap from its log. Only shown once the rule has started a run.`},"schedule.backlogitems":{title:`The items this rule has written`,what:`Opens the Backlog on exactly the rows this schedule created, however many runs ago.`,when:`The other direction of the link a row already shows (“from the schedule …”). The number is the filter — a tap opens those rows and says what it is hiding, never the whole list. Rows written before this link existed do not count towards it.`},"schedule.skipnext":{title:`Skip the next run`,what:`Lets one armed occurrence go by; everything after it stays on the clock.`,when:`Different from pausing, and the difference is who has to remember: a pause waits for you to come back, a skip does not. Never offered on a one-off — skipping the one run it has would be deleting it.`},"schedule.toggle":{title:`Arm or disarm this schedule`,what:`Stops it running without deleting it, and arms it again later.`,when:`Re-arming computes the next run from now — a run missed while it was off is not caught up.`,confirm:!0},"schedule.edit":{title:`Edit the schedule`,what:`Change the time, the lead, the repos or the prompt. Saving replaces the same schedule rather than adding a second one.`},"schedule.remove":{title:`Delete this schedule`,what:`Removes it for good. Anything it already started keeps running.`,danger:!0},"limit.first":{title:`Resume this one first`,what:`Moves this session to the front of the resume queue. Otherwise the order is starred sessions first, then whichever has been blocked longest.`,when:`When the limit lifts, the first session through gets the fresh window. Marking two keeps the order you marked them in.`,confirm:!0},"limit.auto":{title:`Auto-continue for this session`,what:`Whether this session resumes by itself once the limit resets. Off takes it out of the queue entirely — it waits for you.`,when:`The way to say “these three, not that one” when everything is blocked on one limit.`},"limit.resumeone":{title:`Resume this one now`,what:`Stops waiting for the reset time and tries this session immediately, ahead of the queue.`,when:`Also the way past the hold-off after a failed resume — an explicit tap overrules the clock. If the limit really has not reset, the attempt is spent for nothing.`,confirm:!0},"limit.resumeall":{title:`Start the queue now`,what:`Stops waiting for the clock for every queued session. They still go one at a time, in the order shown.`,when:`For a reset time the banner got wrong, or a plan that was just upgraded.`},"limit.starredonly":{title:`Only starred sessions resume`,what:`Turns auto-continue on for the starred blocked sessions and off for the rest, in one tap.`,when:`When the limit resets into a window worth spending on two sessions rather than eleven.`,confirm:!0},"limit.mode":{title:`How many resume at once`,what:`One at a time, one per repo, or all at once. The first session always goes alone whatever this says: if it comes back still blocked, nothing else spends an attempt proving the same thing.`,when:`“One per repo” is the middle answer — two agents must not edit one checkout, but two worktrees are not each other's business. “All at once” spends the fresh window broadly.`},"term.fullscreen":{title:`Full screen`,what:`Hides the header, the status line and the toolbar and gives those rows to whatever you are reading — the same layout typing room gives you, without the keyboard taking half the screen. The Esc/Tab/arrow row stays, because with no keyboard it is the only way to answer the CLI. Tap again, or the menu button in the corner, to come back.`},"hdr.pair":{title:`Claude · Shell`,what:`The session and its companion shell, as two tabs: the lit one is on screen, a tap on the other switches. They appear once the menu's "companion shell" has opened one in this session's folder — temporary, it closes when the session does. Gone in full screen and while typing, with the rest of the header.`},"term.read":{title:`Reader / terminal`,what:`Swaps the whole view: the live CLI screen, or the scrollable, searchable transcript of the conversation. It sits here rather than on the header because full screen hides the header — and this is the control you want most in the layout you read a long turn in.`},"term.folded":{title:`Folded strips`,what:`Brings back a strip you folded away above the prompt bar — downloads, a sign-in link, the next prompt and the like. The number is how many are folded; a tap lists exactly those, and a row opens its strip again. The button is only here while something is folded, and it lives in this corner so typing room and full screen keep it.`},"term.grip":{title:`Move these buttons`,what:`Drag the grip to move the whole group of terminal buttons anywhere inside the terminal, off a line it is hiding. The terminal itself is not resized, so the CLI does not redraw. Double-tap the grip to put the group back in its corner. Where you put it is remembered on this phone only.`},"term.modelwheel":{title:`Model · effort wheel`,what:`Picks model and effort on one wheel: a spoke per model, effort from low at the centre to max at the rim. A tap only selects — the sentence above the wheel says what Apply will do, and only a change the CLI cannot make live relaunches the session. The prompt cache belongs to one model, so a switch makes the next turn re-write the context; the line under the wheel prices it. The chips below choose which models are spokes.`},"term.zoom":{title:`Zoom this screen`,what:`How big the terminal — or, in the reader, the conversation — is drawn, on top of the app's text size. In the terminal, smaller is a BIGGER grid: the desktop resizes the session to the new columns and rows, so more of what the CLI prints fits on the phone. The two surfaces remember their own zoom. At either end of the range that button is simply not there, and the readout says which end.`},"limit.global":{title:`Auto-continue, globally`,what:`The master switch: whether any session resumes itself after a usage limit resets. Per-session settings override it.`},"toolbar:limit":{title:`Auto-continue`,what:`Whether this session resumes by itself once a usage limit resets. Tapping cycles: inherit the global setting → on → off.`},"toolbar:image":{title:`Attach a photo`,what:`Picks an image, uploads it into this repo's inbox and puts its path in the message box, so the prompt can point at it.`},"toolbar:file":{title:`Attach a file`,what:`Any kind — PDF, zip, audio, source. Uploaded into this repo's inbox with its path put in the message box.`},"toolbar:backlog":{title:`Backlog`,what:`This repo's waiting work: what is queued, what is running, and why anything queued has not started yet.`},"toolbar:history":{title:`History`,what:`The prompts recorded for this session — resend one, pin it as the overview label, or copy it.`},"toolbar:cmd":{title:`Slash commands`,what:`The CLI's built-in commands plus this repo's own, in a list you can tap instead of typing.`},"session.star":{title:`Star`,what:`Marks a session as one you are waiting on. A starred session that finishes a turn while you are elsewhere gets a “new” flag. Works with the link down — the star is kept on this phone and sent to the desktop when the connection is back.`},"session.followup":{title:`Flag for follow up`,what:`A one-shot mark that this session has something to come back and read. Opening the session does not clear it — only “Done — clear flag” does, here or on its Recently closed row, so it survives a restart, a close and a resume. A bulk close spares it, and the repo's flag count shows exactly the flagged ones.`,when:`Its colour says who set it: blue is you, by hand; purple is a launch you ticked “Flag for follow up when done” on, once it finished; teal is the session's own agent, with its one-line reason under the row.`},"session.bookmark":{title:`Bookmark`,what:`Marks the conversation as one you will want to look at again, with an optional one-line note. Closing the session is fine: Archive › Bookmarks lists this repo's bookmarked conversations, and read opens one read-only without starting the CLI.`,when:`Needs the desktop — with the link down a tap says so. Removing a bookmark that has a note asks a second tap, because the note goes with it.`},"session.context":{title:`Context window`,what:`How full this conversation's window has been over time, with a mark where it was compacted and a shaded band over every stretch the account refused to serve. Read off the CLI's own conversation log, which is dated — the badge beside it can only say where you are NOW.`,when:`The window size is not written to that log, so no ceiling is drawn unless the CLI has printed one on screen; the dashed line is then where a compaction was last seen to fire, which is a measurement rather than a setting.`},"session.pin":{title:`Pin a line`,what:`Replaces the session's second summary line with text you choose, so a long-lived session says what it is FOR rather than what it last did.`},"session.close.all":{title:`Close sessions`,what:`Opens a sheet over every listed session (or one repo's): tick facets — state, idle time, open time, what is still running underneath, unsent words, whether the conversation ever started, repo — to narrow which rows one tap ends. The conversations are kept and can be reopened later; the running processes are not — anything mid-turn is cut off where it stands, and a background shell under a closed session is stopped too, fully.`,when:`The list, not this device: every phone and tab loses the closed sessions together. Star a session to spare it by default — the sheet's own toggle can include it anyway.`,danger:!0},"session.close.stale":{title:`Idle for`,what:`Two facets, "idle for" and "open for", cut the close sheet's list by how long a session has gone quiet or how long it has existed — tick more than one edge (>1h, >6h, >1d, >3d) and they OR together; combine with another facet (state, underneath, …) and it ANDs.`,when:`"Idle" is measured from the last output, so a session paused on a question still counts as quiet by that clock — the sheet flags any row waiting on a box separately. A session with no readable activity record measures its quiet time only since the last desktop restart, and the sheet says so when that applies.`},"repo.hide":{title:`Hide this repo`,what:`Removes it from the launcher list on THIS device only. Nothing on disk changes; unhide it from Settings.`},"repo.focus":{title:`Focus this repo`,what:`Filters the whole launcher down to one repo. The header keeps an X to leave.`},"fanout.run":{title:`Fan out`,what:`Runs ONE prompt in every selected repo — a fresh session each, all at once.`,when:`The sweep that is otherwise N taps and N retypings (“/init everywhere”, “what did this cost this month?”). Each target is a real agent process, so pick the repos deliberately.`,confirm:!0},"fanout.followup":{title:`Follow up`,what:`Sends a second instruction into the sessions this run ALREADY opened.`,when:`It never spawns: a target whose session is gone is reported failed rather than restarted from scratch, because a fresh session would run “now commit that” against a repo that never did step one.`,confirm:!0},"backlog.fire":{title:`Run this item now`,what:`Starts it this second in a session of its own (or in the session it is aimed at) — skipping the queue: the budget, one at a time and wait until free.`,when:`For the one item you want now — it is the manual override, and one tap fires it past every hold. Several at once are several agents; if another agent is already working in this checkout, the row says so and the tap starts a second beside it.`,confirm:!0},"backlog.queuehere":{title:`When that session is free`,what:`Aims the item at the session on screen and marks it to fire on its own when that session is next idle — at the BOTTOM of that repo's queue, so tapping several items runs them in the order you tapped them.`,when:`For building a run of work against a session you are already driving. Tap it again to take the item back off; nothing is deleted either way.`},"backlog.refire":{title:`Run it again`,what:`Re-delivers an item that already ran, this second and in a session of its own — skipping the queue like fire. The agent sees the instruction a second time.`},"backlog.openholder":{title:`The session this item waits behind`,what:`Only one automatic job codes in a checkout at a time. This item is waiting for the one named here — working, on a usage limit, or with a question open that only you can answer. Opens that session.`,when:`When the row says it is waiting for your answer: answer it there and this item starts next. Fire skips the wait entirely.`},"backlog.runagain":{title:`Put it back in the queue`,what:`Puts a failed item back among the waiting ones, keeping its words, its place and the failure it had. It runs again in a new session of its own when its turn comes — one at a time in this repo, with auto taking it from there.`,when:`For work that failed for a reason that has passed. Nothing starts this second: “re-fire” beside it is the verb for that. The old failure stays on the row, so an item that keeps failing says so rather than looking new.`,confirm:!0},"backlog.name":{title:`Name these items`,what:`Reads the words of the items shown here — nothing else, no repo, no code — and writes each one a short title and a kind: bug, feature, enhancement or chore. It leaves out any item you titled yourself, and any it cannot name honestly stays without one.`,when:`For a list of long prompts that all look alike. One short call on the cheap model, so it costs little; it names only what is in the cut you are looking at, and running it again on the same rows changes nothing. A title it writes is yours to edit, and once you edit one nothing writes over it again.`},"backlog.done":{title:`Mark done`,what:`Closes the item off by hand, without running it.`},"gallery.pull":{title:`Download`,what:`Fetches the file to this phone through the resumable queue — the bytes survive a dead tunnel, a reload and the app being killed — and hands it to the phone's own Downloads by itself when it lands.`,when:`The same button everywhere: already fetching, a tap opens Downloads rather than starting a second copy; already here, it saves the file out again. Watch or pause it in Downloads.`,confirm:!0},"gallery.fullres":{title:`Full resolution`,what:`Re-fetches this image at its original size. The viewer shows a screen-sized copy by default, which is a fraction of the bytes.`},"pull.supersede":{title:`Keep only the newest`,what:`When a rebuild writes a new file of the same kind, the older queued one is dropped instead of being downloaded first.`,when:`An APK named with its build hash is a new file every build — without this an afternoon of builds queues five of them and the phone downloads all five to reach the one you wanted.`,confirm:!0},"pull.pause":{title:`Pause`,what:`Stops this download and KEEPS what has arrived. Resuming continues from that byte; it does not start over.`},"pull.retry":{title:`Retry`,what:`Tries again from the bytes already here.`},"pull.clearall":{title:`Clear the queue`,what:`Drops every download still waiting — the desktop's own queue and the ones asked for from this phone. Files already fully downloaded stay on the phone.`,danger:!0},"pull.auto":{title:`Auto-download`,what:`Whether files matching this repo's rule start downloading by themselves as soon as the agent produces them. A file YOU tapped is fetched whatever this says — the switch governs unattended work, not a person.`},"net.pulse":{title:`Connection strip`,what:`Live round-trip time to the desktop: a state dot, the last ~90 seconds as a graph, and the current number. Red marks are pings that got no answer at all — they are drawn rather than averaged in, because a link that loses one ping in four feels nothing like a slow one and only that one eats prompts. In the middle, how old what you are looking at is: while the link is down it counts up from the last thing the desktop actually said, and while it is up it is the age of the last full sync — the session list AND the repo listing, whichever is older. On the right, how much data this phone has moved: the down and up rates while something is actually transferring, and the running totals either way.`,when:`It only watches — a missed ping here never reconnects anything. Tap any part of it for that part's detail, or turn it off in Settings › Tools.`},"net.pulse.graph":{title:`Round trip`,what:`How long a ping to the desktop takes, drawn as the last ~30 probes. A second, dimmer number appears when the newest probe is far off the median, so one slow ping can't be the only figure on screen.`,when:`Tap for the window it is drawn from: last and median ping, how many probes are in it, and how many got no answer.`},"net.pulse.route":{title:`Route`,what:`How this phone reaches the desktop: LAN (its address on your Wi-Fi, used only after it proved it is this desktop) or the tailnet, the route that works anywhere.`,when:`Tap for the sentence saying why this route — the Wi-Fi name, the check that failed, or that a password is needed on the host before LAN can be used.`},"activity.group":{title:`One row per distinct message`,what:`Collapses rows that say the same thing into one strip: how many copies there are, how old the oldest is, and — the part that decides — whether one of those copies ALREADY RAN. Tap the chevron to see them all.`,when:`Always, on a long list. Unresolved sends are mostly repeated re-sends of the same few texts, because that is what a person does when the app says their prompt did not run.`},"activity.debris":{title:`Hide one-word replies`,what:`Hides “continue please”, “done?”, a bare /cost — words that mean nothing away from the screen they were typed on. Nothing is deleted; tap again to see them.`,when:`When you are reading a long failed list and want only the rows with a subject in them.`},"activity.bulkDismiss":{title:`File these away as dealt with`,what:`Marks the selected rows read-and-not-wanted. NOT a delete: they keep their words, their verdict and their buttons under the “dismissed” chip, and “bring back” returns them to the list.`,when:`After you have decided a batch is obsolete. It is what makes the list shrink.`,confirm:!0},"activity.bulkRefire":{title:`Send these again`,what:`Posts each selected row's words again in the repo they were written for — no picker, no retyping. Each one opens its own session when the desktop has room, and their old rows are filed away.`,when:`For the survivors of a triage pass: the ones that never ran and still make sense.`,confirm:!0},"net.pulse.sends":{title:`Sends that gave up`,what:`Prompts written on this phone that never made it into a session — the queue tried, ran out of tries, and stopped. Nothing ran, and nothing here retries itself. The words are kept: the queue row holds them for as long as it takes, and nothing retires it.`,when:`Tap for the list, with each one's words, what stopped it, and the repo it was written for — “send again” puts it back in that repo's backlog, with no picking and no retyping. This slot used to count unanswered PINGS; those are drawn in the graph instead, because a lost ping costs nothing and this does.`},"net.pulse.saved":{title:`Is it on the desktop yet?`,what:`The one reading on this strip that is about your words rather than the link. A green check means everything written on this phone — queued prompts, armed schedules, notes, settings — has reached the desktop and been stored there, so nothing is waiting on this device. A count instead means that many things are still only here; they go as soon as the link allows.`,when:`Look before putting the phone away. It stays blank until this phone has actually had something in flight, and it yields to the red slot when a send has given up — “all saved” beside “1 send stuck” would be a contradiction, and the red one is the one to believe.`},"net.pulse.when":{title:`How current this is`,what:`With the link down, how long since the desktop last said anything — the app keeps drawing from saved copies, and this is their age. With it up, how long since the last full refresh of both the session list and the repo listing; the older of the two is the one shown, because that is when everything on screen was last true.`,when:`Tap for the exact times, and for which half is still missing when it says it is syncing.`},"net.pulse.data":{title:`Data moved`,what:`How much this phone has downloaded and uploaded since the counter was last reset. A speed appears beside the arrow only while something is actually transferring, so no speed means nothing is moving.`,when:`Tap for the totals in full and for exactly what is and isn't counted.`},"hints.toggle":{title:`Explain mode`,what:`While it is on, tapping any button says what that button does instead of doing it. Tap it again to leave.`,when:`Long-pressing a button does the same thing one at a time, at any moment, without switching anything on.`},"schedule.spent":{title:`One-offs that have been and gone`,what:`A one-off schedule that has already fired — or that was missed — is not a schedule any more: there is no instant left for it to run at and it cannot be re-armed. So it stops being a row on this sheet and becomes a row in Activity, where every piece of posted work is kept for its whole life.`,when:`Tap to open exactly those rows in Activity, filtered — not the whole list for you to find them in. Run it now still works on one from there: the host revives a spent one-off and fires it.`},"localrt.bar":{title:`How hard this desktop is working`,what:`A live readout of the machine: CPU busy and its recent line, GPU busy, and memory available — amber when memory is tight. While a local model is loaded, that model takes the front of the strip: its name, the bytes it holds and their line. It watches — it never starts, stops or evicts anything.`,when:`A hosted model costs money on somebody's invoice; a local one costs this machine, and so does a build or twenty sessions — all invisible from a phone otherwise. Tap any reading for the full sheet; switch the strip off in Settings.`},"localrt.models":{title:`The models resident right now`,what:`Each model the runner is currently holding, with the bytes it occupies. Empty means the runner answered and is holding nothing, which is a different fact from the runner not answering at all — the strip words those two apart.`,when:`Tap for the full list: per-model size, how much of it is on the GPU, and when the runner intends to evict it.`},"localrt.graph":{title:`Held memory over the last few minutes`,what:`One mark per sample of the total bytes resident. A sample where the runner did not answer is drawn as its own full-height mark rather than averaged in or bridged over — those are a different kind of event, not a small number.`,when:`This is what a model being loaded or evicted looks like: a step, not a slope. It is the last hundred-odd samples, not a time axis — nothing is measured while the phone is in a pocket.`},"localrt.cpu":{title:`The desktop's CPU`,what:`How busy the machine is, from the operating system — not from the model. With no model loaded the strip leads with it, and the line beside it is the last few minutes of it. A local model generating text pins this; a model sitting loaded and idle does not.`,when:`Tap for the detail. Tokens per second is deliberately not shown anywhere here: nothing this app can read publishes it, and an estimate would be wrong in both directions that matter.`},"localrt.memory":{title:`Memory available on the desktop`,what:`What a new program could actually get, from the operating system — the file cache counts as available, because it is handed back on demand. It is the number a second local model would have to fit into. Amber when less than a tenth is left or the swap file is nearly full.`,when:`Good enough to warn on, nowhere near good enough to refuse work on, which is why nothing in this app ever blocks a launch over it.`},"localrt.agents":{title:`Agents running at once`,what:`Every session whose turn is running, plus every subagent running under any session on this desktop, added up. Amber past your warning mark, red past your limit — both set in Settings → Appearance (default 10 and 30). Crossing a mark on the way up also says so once.`,when:`Past a mark the strip shows itself even when it is switched off; its × hides it until the count passes your next mark. Tap for the count over time and which sessions hold the agents — a row opens that session. It only counts and colours: nothing here stops an agent or refuses a launch.`},"session.tabs":{title:`A session you have open`,what:`One tab per live session, coloured by its repo — the same colour that repo wears on the launcher's group header and down the side of every one of its rows, so a tab is recognised before it is read. The taller tab with a cap of colour on it is the one you are in. The mark beside the name is what that session is doing, in the launcher’s own five words and five colours: a turning ring while a turn is running, a red dot waiting on an answer from you, an orange one at the usage limit, a grey one with nothing left to do, and a red one on a process that has exited.`,when:`Tap to go straight there from wherever you are — everywhere else in the app the sessions are a column you scroll. The × closes that session and asks first; the conversation itself is kept either way. How many tabs fit, what order they sit in, and which colour each repo gets are all in Settings.`},"repohealth.size.p95":{title:`p95 file length`,what:`The length of the file at the 95th percentile: 95 out of 100 source files in the tree are shorter than this. Counted in lines, over the source set — whichever file kinds this repo's own detected languages count as source, minus their tests, minus build and vendor directories. The sheet names which languages it found.`,when:`A mean would be a number about the single biggest file and almost nothing else — one outsized file can carry a large share of every source line on its own. The p95 describes what a large file looks like with that kind of outlier already inside the 5% being ignored, so it moves when MANY files grow and barely twitches when one does. The tape at the foot of the sheet names the longest file and its length.`},"repohealth.retouch.rate":{title:`The re-touch rate`,what:`Over a trailing window of days, the share of file touches that were re-touches: the same file edited again soon after — soon in HOURS, or within a couple of commits that are also close in time — AND the later edit changes or removes lines the earlier one added. A touch that only adds lines near the last one (an append to a list or a registry) is not rework: it is counted apart and printed beside the rate, never in it. Sweep commits touching most of the tree are left out of both halves of the fraction. The touches it is a share of, and the three most re-touched files, are printed beside it. The exact window, hour and commit distance are pre-registered in the tool, not written down on this phone.`,when:`A file edited once and left alone is a decision that held; a file edited again two days later is one that did not. It is also the one number here that does not fall simply because more code was written, which is why the sheet plots it at all. Read it with its denominator: 1.00 over 6 touches and 0.69 over 36 are different claims.`},"repohealth.hatches.perKloc":{title:`Unexplained escape hatches per kLOC`,what:"How many places a rule was switched off WITHOUT a reason, per thousand source lines. Each detected language has its own marks — TypeScript's `as any` and `@ts-ignore`, Kotlin's `!!` and `@Suppress`, Python's `# type: ignore` and a bare `except:`. A mark that carries its reason (after it on the line, or in a comment directly above) is explained and counted apart; TODO and FIXME are reported apart too, and neither is in this number. All three counts are printed beside it. Counted as OCCURRENCES, so two on one line count twice.",when:`Per kLOC rather than raw, or it would mostly plot how fast the repo is growing. Whether any single hatch was the right call is a judgment and this tool never makes one: there is no threshold anywhere in it, and no colour on this number. Only the marks a detected language knows about are counted — the sheet lists which languages are active.`},"repohealth.context.claudeMdChars":{title:`CLAUDE.md, in characters`,what:`The size of this repo's CLAUDE.md at the commit that was measured. It is re-sent on every turn of every session in this repo, so it is paid per TURN, not per session.`,when:`The repo-setup sheet weighs the same file and can disagree with this: that row measures the WORKING TREE as it stands, this one the last commit. An uncommitted edit to CLAUDE.md is exactly the gap between them, and neither is corrected to match the other.`},"repohealth.context.descChars":{title:`The always-on skill descriptions`,what:`The one-line description of every skill this repo ships, added up. Descriptions are always in the window — that is how the agent knows a skill exists at all. Skill BODIES are loaded on demand and are not counted here.`,when:`Moving prose out of CLAUDE.md into a skill body takes it out of both numbers. Splitting one skill into six adds six descriptions, so a tidy-up that reads as a reduction can raise this half while lowering the other.`},"repohealth.context.skillCount":{title:`The count of skills`,what:`How many skills this repo ships at the commit that was measured — the same set the descriptions above are the descriptions OF, so the two can never describe different populations. It counts skills, not their size: a body is loaded on demand and weighs nothing here.`,when:`The one tile with no percentile and no arrow under it, and that is deliberate. A rise can be reference leaving CLAUDE.md for a skill that loads only when it is needed, and a rise can be one skill split finer than its subject divides — the count is identical either way, so the tool draws the shape and takes no position. Read it beside the other two: those move in opposite directions when reference is relocated, and this says how many pieces it landed in.`},"repohealth.untested.count":{title:`Modules no test reaches`,what:`Source modules that no test file names AND that no test reaches through imports — a test importing a module that imports this one, to any depth, by the import syntax of the detected language. A name has to carry at least one DIRECTORY segment, never a bare word on its own: a bare name is also ordinary prose, and matching it alone would mark most of the tree tested for no reason. The sentence under the tile adds the modules reached only through another module's imports, and what joined and left the list since the window opened.`,when:`A count and not a percentage, because a ratio rises when you add a tested feature and falls when you add an untested one, which mostly plots growth. Nobody can write a test for 27%; a list can be closed one line at a time. Reached means a test LOADS the module, never that its lines ran — and a module a test only reads as text counts as named without the modules it imports counting as reached. A language with no naming rule of its own sits outside this count rather than inside it, neither tested nor untested; one with a naming rule but no import rule is read on naming alone. In a language whose own tests sit beside what they test rather than importing it, a test that needs no import names nothing, so this count reads high there even where the tests do exercise the code.`},"repohealth.graph.cycleFiles":{title:`Files in import cycles`,what:`Source modules that sit in an import cycle: A imports B, B imports C, and C imports A again — through any number of steps, re-exports and lazy imports included. The sentence under the tile says how many cycles they form and names the members of the largest. Only imports between this repo's own modules count; a package from outside is not an edge. Aliases written in tsconfig "paths" and workspace packages imported by name are followed. Only languages with an import-graph rule are read — TypeScript and JavaScript today.`,when:`A file in a cycle cannot be understood, tested or changed on its own: touching one means holding all of them, for a person and for an agent alike. When too many of this repo's own imports cannot be followed — usually an alias only the bundler knows — the tile shows no number and names the imports it could not follow, because a missed import would make the cycles look smaller than they are.`},"repohealth.graph.fanOutP95":{title:`Imports per file, p95`,what:`How many distinct modules of this repo a file imports, at the 95th percentile: 95 out of 100 source files import fewer. Packages from outside the repo do not count. The sentence under the tile names the file that imports the most, and how many of the repo's own imports could be followed to a module.`,when:`A file that imports many others changes whenever any of them does, and has to be read with all of them in view. The p95 moves when many files pull in more, not when one barrel file re-exports a whole folder — that one is the max, named beside it.`},"repohealth.reading":{title:`The percentile and the arrow`,what:`Under every tile: where today's value sits among that series' own recent readings, and the direction of a straight line fitted through them. Too short a history and both are withheld, and the tile says so rather than guessing. How long the window is and how short is too short are the tool's, carried on the wire and printed in the caption under the tiles — this card does not keep a second copy to go stale.`,when:`The comparison is always a series against ITS OWN past — never another repo, never a target, and never a threshold. The arrow carries no colour because rising lines and rising escape hatches are opposite news and a hue would have to decide which.`},"repohealth.weight":{title:`Always-on weight over time`,what:`CLAUDE.md and the skill descriptions stacked, so the top edge is the total that every turn of every session re-sends. Zero-based, unlike the tiles above, because it is a quantity rather than a position.`,when:`A day where either half went unmeasured is a gap in BOTH bands, never a shortened top edge: the sum is the one mark a reader takes off this chart, and a total quietly short by an unknown amount would be read as a real drop.`},"repohealth.areas":{title:`What a change carries, per area`,what:`On the latest reading only. The hollow end is what an edit in that area usually carries — CLAUDE.md, every skill description, the area's router and the sub-skills that area's own files claim. The solid end is the same with every one of that area's skill bodies loaded.`,when:`Re-partitioning the skills moves the near end and cannot move the far one; deleting prose moves both. One scale across every row, zero at the left, so the areas are comparable to each other. This exists only in a repo that splits its skills into a router and sub-skills named after it; elsewhere there is nothing to draw here, and the repo-wide weight above still does.`},"repohealth.packages":{title:`Lines of source by group`,what:"Source lines per source group, stacked over the series, so the top edge is the whole tree. A group is a top-level slice the tool derives from where the files sit — `packages/web`, `app`, `service`, or `.` for files at the root — never an npm workspace list, so it draws the same way whatever this repo's package manager is, if it has one at all. That is why there is no separate total-lines curve beside it — one quantity, one mark.",when:`A colour follows a group by NAME and never by its size today, so one group overtaking another does not swap their bands and re-colour the whole history. A group with no files on a day that WAS measured is a zero, not a hole.`},"repohealth.types":{title:`Lines of source by file type`,what:`The same source lines the chart above stacks by group, cut by what the code is instead: one band per file extension the detected languages claim, with the language pack that claims it named beside it. The top edge is therefore the same total drawn twice — one quantity, two questions.`,when:`A group says which part of the tree grew; a type says what grew in it, and in a repo where one app is one language those two answers look identical until the day they are not. The chips above the chart are a filter: tapping types off redraws the stack over only those, and the caption then says how many types and how many lines the top edge is standing for.`},"repohealth.classics.files":{title:`Source files`,what:`How many source files live in the tree, over time — the source set the sheet's detected languages count, minus their tests, minus build and vendor directories. A size, not a reading: nothing compares it to anything, which is why no percentile and no arrow appears beside it.`,when:`It is part of what the percentiles above are percentiles OF. A position in a window means nothing without a feel for the magnitude being positioned.`},"repohealth.classics.deps":{title:`Production dependencies`,what:"Runtime dependencies declared in the manifests a detected language knows how to read — a `package.json`, a `requirements*.txt`, the `[project]` table of a `pyproject.toml` — added up across the tree. devDependencies are counted apart and never summed into this: one ships and is in the attack surface, the other is a build-time cost that can be swapped on a Tuesday.",when:"Some languages decline this on purpose rather than guess: a Gradle build script is a program and not a list, and a `pubspec.yaml` mixes shapes a plain count would misread — so where nothing in the tree is a manifest this tool knows how to read, the reading is ABSENT rather than zero. Absent means nobody counted, never that nothing is depended on. Where it does read, it moves in single steps and each step is a decision somebody made, which is what makes the shape of this curve readable at a glance in a way a line count is not."},"repohealth.table":{title:`The readings, as numbers`,what:`The tail of the series as a table — p95 file length, the longest file, file count, lines per group, dependencies — oldest first, the same direction the charts run. Its own caption says how many day-rows it shows and out of how many.`,when:`Two of the band colours sit under 3:1 contrast on a light screen, so the split has to be readable without them. And a crosshair answers for one day at a time: this is the only place on the sheet where a day can be held against the day beside it.`},"repohealth.longest":{title:`The longest file, over time`,what:`The length of the single longest source file at every reading, one hue per file. Where a different file takes the top spot the line changes hue and a ring marks the reading it happened on, joined to the old holder by a thin step. Drag across the curve for a day's length, file and commit; the legend lists each file that held the spot and for how many readings.`,when:`A tree whose biggest file only grows is one where every change keeps landing in the same place. A split shows up here as the curve dropping and a new name taking over; a file that is merely renamed shows up the same way, so the name is printed rather than inferred.`},"repohealth.classics.tape":{title:`The longest files`,what:`One bar per file for the longest source files in the tree, tallest first, drawn to scale against each other. Tap or drag across a bar to name its file under the chart, with an open button that shows the file itself; tap the same bar again to let go. The caption names how many were taken and out of how many.`,when:`This is the feel-for-the-magnitude picture the rest of the sheet is measured against: a shape, not a lookup. It is a slice of the tail, so its middle bar is not the repo's median file and no median is printed for it.`}};function Vu(e){return e.def?e.explain?`explain`:e.mode!==`first`||!e.def.confirm||e.seen?`act`:`explainThenAct`:`act`}var Hu=2e4,Uu=12e3,Wu=18e4,Gu=class extends Error{url;ms;constructor(e,t){super(`timed out after ${Math.round(t/1e3)}s`),this.name=`TimeoutError`,this.url=e,this.ms=t}};function Ku(e){if(e instanceof Gu||e instanceof TypeError)return!0;let t=String(e);return t.includes(`Failed to fetch`)||t.includes(`NetworkError`)||t.includes(`fetch failed`)}async function qu(e,t,n=Hu,r=fetch){let i=new AbortController,a=t?.signal,o=()=>i.abort();a&&(a.aborted?i.abort():a.addEventListener(`abort`,o,{once:!0}));let s=setTimeout(()=>i.abort(new Gu(e,n)),n);try{return await r(e,{...t,signal:i.signal})}catch(t){throw a?.removeEventListener(`abort`,o),i.signal.aborted&&!a?.aborted?new Gu(e,n):t}finally{clearTimeout(s)}}var Ju=12e3;function Yu(e,t,n=50){return e.push(t),e.length>n&&e.splice(0,e.length-n),e}function Xu(e){return e.fuseFired?`timeout`:e.ageMs>=12e3?e.answered?`late`:`failed`:null}var Zu=4e3,Qu=3,$u=e=>e.trim()===``;function ed(e=[],t=[]){return{archived:e,screen:t}}function td(e,t){if(e.length===0)return 0;let n=t.findIndex(e=>!$u(e));if(n<0)return 0;let r=t.slice(n,n+Qu);for(let t=0;t<e.length;t++){let n=!0,i=0;for(let a=0;a<r.length&&t+a<e.length;a++,i++)if(e[t+a]!==r[a]){n=!1;break}if(n&&i!==0)return t}return e.length}function nd(e,t,n=Zu){let r=od(t);if(r.length===0||sd(e.screen,r))return e;let i=td(e.screen,r);if(i===0)return{archived:e.archived,screen:r};if(i===e.screen.length){let t=rd(e.screen,r);if(t!==null)return{archived:id(e.archived,r.slice(0,t)),screen:r}}let a=e.archived.concat(od(e.screen.slice(0,i)));return{archived:a.length>n?a.slice(a.length-n):a,screen:r}}function rd(e,t){let n=e.findIndex(e=>!$u(e));if(n<0)return null;let r=e.slice(n,n+Qu);for(let e=1;e+r.length<=t.length;e++)if(r.every((n,r)=>t[e+r]===n))return e;return null}function id(e,t){let n=od(t);for(let t=Math.min(n.length,e.length);t>0;t--){let r=!0;for(let i=0;i<t;i++)if(e[e.length-t+i]!==n[n.length-t+i]){r=!1;break}if(r)return e.slice(0,e.length-t)}return e}function ad(e){return e.archived.concat(e.screen)}function od(e){let t=e.length;for(;t>0&&$u(e[t-1]);)t--;return t===e.length?e:e.slice(0,t)}function sd(e,t){if(e.length!==t.length)return!1;for(let n=0;n<e.length;n++)if(e[n]!==t[n])return!1;return!0}function cd(e,t){return e.kind!==`all`&&e.kind!==t.kind?!1:e.since==null||t.since!=null&&t.since<=e.since}function ld(e,t){let n=e.filter(e=>cd(e,t));if(!n.length)return null;let r=e=>+(e.kind===t.kind&&e.since===t.since);return n.reduce((e,t)=>r(t)===r(e)?t.savedAt>e.savedAt?t:e:r(t)>r(e)?t:e)}function ud(e,t,n,r){let i=(t.query??``).trim().toLowerCase(),a=t.since==null?0:r-t.since*1e3;return e.filter(e=>t.kind===`image`&&!n(e.relPath)||t.kind===`doc`&&n(e.relPath)||a&&e.mtime<a?!1:!i||e.name.toLowerCase().includes(i))}function dd(e,t,n){return e===`all`?`all|${n??``}`:`${t??``}|${e}`}function fd(e,t){return`${e}|${t.kind}|${t.since??`all`}`}var pd=[`7d`,`30d`,`90d`,`365d`],md={"7d":6048e5,"30d":2592e6,"90d":7776e6,"365d":31536e6},hd={"7d":`older than a week`,"30d":`older than 30 days`,"90d":`older than 90 days`,"365d":`older than a year`},gd={outbox:`outbox — what agents wrote for you`,inbox:`inbox — what this phone uploaded`};function _d(e,t,n){return n-e>md[t]}function vd(e){let t=0;for(let n of e)t+=n.size;return{count:e.length,bytes:t}}function yd(e,t){let n={};for(let e of pd)n[e]={count:0,bytes:0};for(let r of e)for(let e of pd)_d(r.mtime,e,t)&&(n[e].count++,n[e].bytes+=r.size);return n}function bd(e,t,n){let r=e.filter(e=>_d(e.mtime,t,n)).sort((e,t)=>t.mtime-e.mtime),i=vd(r);return{rows:r,count:i.count,bytes:i.bytes,total:vd(e),oldestMtime:r.length?Math.min(...r.map(e=>e.mtime)):null}}function q(e){if(!Number.isFinite(e)||e<0)return`?`;if(e<1024)return`${e} B`;let t=[`KB`,`MB`,`GB`,`TB`],n=e/1024,r=0;for(;n>=1024&&r<t.length-1;)n/=1024,r++;return`${n<10?n.toFixed(1):Math.round(n).toString()} ${t[r]}`}function xd(e){return e.count?`Delete ${e.count} file${e.count===1?``:`s`} · ${q(e.bytes)}`:`Nothing to delete`}function Sd(e,t){let n=e.total.count-e.count,r=e.total.bytes-e.bytes;return e.total.count?e.count?n?`${n} newer file${n===1?``:`s`} stay (${q(r)}).`:`Everything here is ${hd[t]}. Nothing would be kept.`:`Nothing here is ${hd[t]} — all ${e.total.count} files stay (${q(e.total.bytes)}).`:`Nothing here.`}function Cd(e){let t=[];return t.push(e.deleted?`Deleted ${e.deleted} file${e.deleted===1?``:`s`} · ${q(e.bytes)}.`:`Deleted nothing.`),e.missing.length&&t.push(`${e.missing.length} already gone.`),e.failed.length&&t.push(`${e.failed.length} could not be removed — still on disk.`),t.join(` `)}var wd={collect:!0,prune:!0,keep:3};function Td(e){return e.collect?e.prune?`collected into .claude/outbox with a versioned name · the newest ${e.keep} of each kept`:`collected into .claude/outbox with a versioned name · nothing is ever removed`:`builds are offered exactly where they land, under whatever name they have`}function Ed(e){return/^\d+$/.test(e)||/^v\d+$/i.test(e)?!0:/^(?=.*\d)[0-9a-f]{6,}$/i.test(e)}var Dd=/[-_. +~]+/;function Od(e){let t=e.replace(/\\/g,`/`),n=t.lastIndexOf(`/`),r=n>=0?t.slice(0,n+1):``,i=t.slice(n+1),a=i.lastIndexOf(`.`),o=a>0?i.slice(a).toLowerCase():``,s=(a>0?i.slice(0,a):i).replace(/_\d+$/,``).split(Dd).filter(e=>e&&!Ed(e));return s.length?`${r}${s.join(`-`).toLowerCase()}${o}`:`${r}${i.toLowerCase()}`}function kd(e,t,n,r=t){let i=new Set(t.map(Od)),a=new Set(r),o=new Map;for(let t of e){let e=Od(t.relPath);if(!i.has(e))continue;let n=o.get(e);n?n.push(t):o.set(e,[t])}let s=[];for(let e of o.values()){e.sort((e,t)=>t.mtime-e.mtime);for(let t of e.slice(Math.max(1,n)))a.has(t.relPath)||s.push(t)}return s}var Ad=[1,3,5],jd={1:`keep only the newest of each`,3:`keep the newest 3 of each`,5:`keep the newest 5 of each`};function Md(e){let t=new Set;for(let n of e)t.add(Od(n.relPath));return t.size}function Nd(e,t){let n=new Map;for(let t of e)n.set(t.relPath,t);let r=kd(e.map(e=>({relPath:e.relPath,mtime:e.mtime})),e.map(e=>e.relPath),t,[]).map(e=>n.get(e.relPath)).filter(e=>!!e).sort((e,t)=>t.mtime-e.mtime),i=vd(r);return{rows:r,count:i.count,bytes:i.bytes,total:vd(e),oldestMtime:r.length?Math.min(...r.map(e=>e.mtime)):null}}function Pd(e){let t={};for(let n of Ad){let r=Nd(e,n);t[n]={count:r.count,bytes:r.bytes}}return t}function Fd(e,t,n){let r=e.total.count-e.count,i=e.total.bytes-e.bytes,a=`${n} build ${n===1?`family`:`families`}`;return e.total.count?e.count?`${r} file${r===1?``:`s`} stay (${q(i)}) — the newest ${t} of each of ${a}.`:`Nothing here is superseded — every one of the ${e.total.count} files is among the newest ${t} of its family (${a}).`:`Nothing here.`}function Id(e){return e.count?`Delete ${e.count} superseded build${e.count===1?``:`s`} · ${q(e.bytes)}`:`Nothing superseded`}function Ld(e){let t=e.repos.length,n=`${t} repo${t===1?``:`s`}`;return e.total?e.total.count?`${e.total.count} file${e.total.count===1?``:`s`} · ${q(e.total.bytes)} across ${n}.`:`${n}, and nothing in any transport directory.`:`${n}. Some directories could not be counted, so there is no total — the rows that answered are below.`}function Rd(e){return e?e.count?`${e.count} · ${q(e.bytes)}`:`empty`:`not counted`}var zd={cache:`cache — re-made when it is next needed`,rollback:`migration leftover — a copy kept in case the upgrade was wrong`,ledger:`record — history, not a cache`,live:`in use — the daemon is reading this now`,unknown:`not in this app's catalogue`};function Bd(e){return e.filter(e=>!e.cant&&e.count>0)}function Vd(e){return e.count?e.bytes==null?`Clear ${e.label} · ${e.count}`:`Clear ${e.label} · ${e.count} · ${q(e.bytes)}`:`Nothing in ${e.label}`}function Hd(e,t){if(t.refused)return t.refused;let n=[];return n.push(t.deleted?`Cleared ${t.deleted} file${t.deleted===1?``:`s`} · ${q(t.bytes)} from ${e}.`:`${e} was already empty.`),t.failed&&n.push(`${t.failed} could not be removed — still on disk.`),n.join(` `)}function Ud(e){let t=e.indexOf(`/`);return t<0?e:e.slice(t+1)}function Wd(e,t,n){if(!e.length||e.some(e=>e.name===t))return null;let r=e.reduce((e,t)=>e+t.size,0),i=e.map(e=>e.name).join(`, `),a=e=>`${(e/2**30).toFixed(1)} GB`;return`${i} ${e.length===1?`is`:`are`} already loaded (${a(r)} held, ${a(n)} free). Running a second local model at the same time may evict it, and every switch between them reloads from disk.`}var Gd=(e,t)=>e?t?{requests:e.requests+t.requests,promptTok:e.promptTok+t.promptTok,promptMs:e.promptMs+t.promptMs,cachedTok:e.cachedTok+t.cachedTok,genTok:e.genTok+t.genTok,genMs:e.genMs+t.genMs}:e:t?{...t}:void 0,Kd=(e,t)=>e?t?{requests:e.requests+t.requests,ms:e.ms+t.ms}:e:t?{...t}:void 0,qd=(e,t)=>e?t?{loads:e.loads+t.loads,ms:e.ms+t.ms}:e:t?{...t}:void 0,Jd=(e,t)=>{if(!e)return t?{...t}:void 0;if(!t)return e;let n=t.contextLength??e.contextLength;return{samples:e.samples+t.samples,sumBytes:e.sumBytes+t.sumBytes,peakBytes:Math.max(e.peakBytes,t.peakBytes),sumVram:e.sumVram+t.sumVram,peakVram:Math.max(e.peakVram,t.peakVram),residentMs:e.residentMs+t.residentMs,...n==null?{}:{contextLength:n}}},Yd=(e,t)=>{if(!e)return t?{...t}:void 0;if(!t)return e;let n=e.swapPeak==null?t.swapPeak:t.swapPeak==null?e.swapPeak:Math.max(e.swapPeak,t.swapPeak);return{samples:e.samples+t.samples,usedSum:e.usedSum+t.usedSum,usedPeak:Math.max(e.usedPeak,t.usedPeak),availMin:Math.min(e.availMin,t.availMin),totalBytes:Math.max(e.totalBytes,t.totalBytes),...n==null?{}:{swapPeak:n},source:t.source}};function Xd(e,t){if(!e)return t?{...t}:void 0;if(!t)return e;let n={...e};for(let[e,r]of Object.entries(t))n[e]=(n[e]??0)+r;return n}function Zd(e,t){let n={model:e.model},r=(e,t)=>{t!==void 0&&(n[e]=t)};return r(`compute`,Gd(e.compute,t.compute)),r(`timed`,Kd(e.timed,t.timed)),r(`untimed`,Kd(e.untimed,t.untimed)),r(`loads`,qd(e.loads,t.loads)),r(`byApi`,Xd(e.byApi,t.byApi)),r(`mem`,Jd(e.mem,t.mem)),r(`machine`,Yd(e.machine,t.machine)),n}function Qd(e,t){let n=new Map;for(let r of e)if(!(t&&r.day<t))for(let e of r.models){let t=n.get(e.model);n.set(e.model,Zd(t||{model:e.model},e))}return[...n.values()].sort((e,t)=>+(e.model===null)-(t.model===null)||$d(t)-$d(e)||(t.mem?.residentMs??0)-(e.mem?.residentMs??0)||String(e.model).localeCompare(String(t.model)))}function $d(e){return e.compute?e.compute.promptMs+e.compute.genMs:0}function ef(e){return(e.compute?.requests??0)+(e.untimed?.requests??0)}function tf(e,t){return!e||!t||e<=0||t<=0?null:e/(t/1e3)}function nf(e,t){return t&&t>0&&e!=null?e/t:null}function rf(e){let t=new Date(e),n=e=>String(e).padStart(2,`0`);return`${t.getFullYear()}-${n(t.getMonth()+1)}-${n(t.getDate())}`}function af(e){if(!Number.isFinite(e)||e<0)return`?`;if(e<1e3)return`${Math.round(e)} ms`;let t=e/1e3;if(t<60)return`${t<10?t.toFixed(1):Math.round(t)} s`;let n=Math.floor(t/60);if(n<60)return`${n} min ${Math.round(t-n*60)} s`;let r=Math.floor(n/60);return`${r} h ${n-r*60} min`}function of(e,t){let n=[];return e.reachable===!1?n.push(`Ollama is not running — it did not answer on ${e.url}${e.lastSampleAt?` at ${t(e.lastSampleAt)}`:``}. Nothing is sampled until it does.`):e.reachable===null&&n.push(`Ollama has not been asked yet — the first sample is taken within ${Math.round(e.intervalMs/1e3)} s of the host starting.`),e.log.readable||n.push(`Server log not readable: ${e.log.reason} Compute time and tokens need it; memory is still sampled.`),!e.days.some(e=>e.models.some(e=>ef(e)>0))&&e.log.readable&&n.push(`No request seen yet — the runner's log has recorded no completed request since ${t(e.since)}.`),n}function sf(e){return e.launchModes??e.permissionModes}function cf(e,t,n){if(t===void 0)return null;let r=sf(n);return r.includes(t)?null:`${e} cannot start in "${t}" mode${n.permissionModes.includes(t)?` (it can switch to it once running)`:``}; it starts in: ${r.join(`, `)||`no mode`}.`}function lf(e,t){return t.onHost?.includes(e)?`host`:t.sending.includes(e)?`sending`:t.kept.includes(e)?`kept`:t.dead[e]?`dead`:t.onHost===null?`unknown`:`missing`}function uf(e,t){return e.map(e=>{let n=lf(e,t);return n===`dead`?{relPath:e,state:n,why:t.dead[e]}:{relPath:e,state:n}})}function df(e){return e.every(e=>e.state===`host`||e.state===`sending`)}function ff(e){let t={kept:0,dead:1,missing:2,unknown:3};return e.filter(e=>e.state in t).sort((e,n)=>t[e.state]-t[n.state])}function pf(e){return e.filter(e=>e.mode===`upload`&&e.upload&&e.status!==`failed`).map(e=>e.upload.relPath)}function mf(e){return[...pf(e)].sort().join(`
12
+ `)}var hf=`waiting for another session's retry to get through first`;function gf(e){return e.heldBy?hf:e.why||void 0}function _f(e){let t=Math.max(0,Math.ceil(e/1e3));if(t<60)return`${t}s`;let n=Math.floor(t/60),r=t%60;return r?`${n}m ${r}s`:`${n}m`}function vf(e,t){if(!e)return null;if(e.state===`waiting`)return`Network error — ${e.nextAt==null?`retry waiting`:`retrying in ${_f(e.nextAt-t)}`} (${e.attempt+1}/${e.max})${gf(e)?` · ${gf(e)}`:``}`;if(e.state===`sent`)return e.probe?`Network error — tried once more (try ${e.attempt}), waiting for the reply`:`Network error — retried (${e.attempt}/${e.max}), waiting for the reply`;let n=e.nextAt==null?``:`; one more try in ${yf(e.nextAt-t)}`;return`Network error — stopped retrying${e.why?`: ${e.why}`:``}${n}. Type to try again.`}function yf(e){return e<6e4?_f(e):`${Math.ceil(e/6e4)}m`}function bf(e){return!!e&&(e.state===`gaveup`||e.probe===!0)}function xf(e,t){if(e.state!==`running`||!e.sessionId)return null;let n=t.find(t=>t.id===e.sessionId)?.netRetry;return n&&bf(n)?n:null}function Sf(e,t){let n=e.attempt===1?`1 retry used`:`${e.attempt} retries used`,r=e.state===`gaveup`?(e.why??``).replace(/^after \d+ tr(?:y|ies)(?: — )?/,``).trim():``,i=e.nextAt!=null&&t!=null?` · next try in ${yf(e.nextAt-t)}`:``,a=e.state===`gaveup`?i:e.state===`waiting`&&gf(e)?` · ${gf(e)}${i}`:` · trying again now`;return`Stalled — API unreachable, ${n}${r?` (${r})`:``}${a}`}var Cf=`stopped: the CLI is signed out — sign in, then continue`,wf=`Retry now types “continue” into that session, the way the automatic retry does; the work completes on the next real reply.`,Tf=`retrying now — “continue” is typed once the session is quiet`;function Ef(e){return e.enabled&&!e.envOff}function Df(){return`Off on this desktop: ${hr(`NET_RETRY`)}=0 is set in its environment, and that wins over this switch. Remove it there and restart the host to use the switch.`}function Of(e,t=!1){return t?`saved ${e?`on`:`off`} — still off on this desktop while its environment says so`:e?`network-error retry on`:`network-error retry off — pending retries cancelled`}var kf=`signed out`,Af=`signed in again — continue?`,jf=`cannot tell whether you signed in again — continue if you have`,Mf=`signed in again — continues after the first session gets through`,Nf=`continuing after the sign-in`;function Pf(e){let t=e.signInWait;if(e.signedOut||e.login||e.cliSetup||t){let n={kind:`auth`,since:e.login?.at??t?.since??null,attempts:0,nextAt:null};return!t||e.login?{...n,phase:`needsYou`}:t.continuing?{...n,phase:`retrying`,detail:Nf}:t.queued?{...n,phase:`waiting`,detail:Mf}:t.signedInAt==null?t.unsure?{...n,phase:`needsYou`,detail:jf}:{...n,phase:`needsYou`,detail:kf}:{...n,phase:`waiting`,detail:Af}}let n=e.limit;if(n?.blocked)return{kind:n.spend===!0?`spend`:`limit`,since:n.blockedSince>0?n.blockedSince:null,attempts:n.attempts,nextAt:n.held&&!n.needsYou?null:n.nextAttemptAt,resetAt:n.resetAt,...n.needsYou?{detail:n.needsYou}:n.held?{detail:n.held}:{},phase:If(n)};let r=e.netRetry;return r?{kind:`net`,phase:r.state===`sent`?`retrying`:r.nextAt!=null||r.state===`waiting`?`waiting`:`gaveUp`,since:r.at>0?r.at:null,attempts:r.attempt,nextAt:r.nextAt,...r.heldBy&&r.state===`waiting`?{heldBy:r.heldBy}:{},...r.error?{detail:r.error}:{}}:null}function Ff(e){let t=Pf(e);return!t||t.kind===`net`&&t.phase===`gaveUp`||t.kind===`auth`&&!e.signedOut&&!e.login&&!e.signInWait?null:t.kind}function If(e){return e.needsYou==null?e.resuming?`retrying`:e.nextAttemptAt!=null||e.queuePos!=null?`waiting`:e.autoContinue?e.spend?`needsYou`:`gaveUp`:`needsYou`:`needsYou`}function Lf(e){return!e.running||Pf(e)?!1:!!(e.prompt||e.awaitingInput||e.asking)}function Rf(e,t,n){let r=e.filter(Lf).map(e=>e.id),i=new Set(r),a=t.filter(e=>Rs(e)&&!(e.kind===`prompt`&&e.sessionId&&i.has(e.sessionId))).slice().sort((e,t)=>t.ts-e.ts);return{ts:n,sessions:{n:r.length,ids:r.slice(0,20)},attention:{n:a.length,items:a.slice(0,10).map(e=>({id:e.id,ts:e.ts,kind:e.kind,title:e.title,...e.sessionId?{sessionId:e.sessionId}:{},...e.plugin?{plugin:e.plugin}:{},...e.tag?{tag:e.tag}:{}}))}}}function zf(e){return e.sessions.n+e.attention.n}function Bf(e){if(!e||typeof e!=`object`)return null;let t=e,n=t.sessions,r=t.attention,i=e=>typeof e==`number`&&Number.isFinite(e)&&e>=0;if(!i(t.ts)||!n||!r||!i(n.n)||!i(r.n)||!Array.isArray(n.ids)||!Array.isArray(r.items))return null;let a=[];for(let e of r.items.slice(0,10)){if(!e||typeof e!=`object`)continue;let t=e;typeof t.id==`string`&&typeof t.title==`string`&&typeof t.kind==`string`&&i(t.ts)&&a.push({id:t.id,ts:t.ts,kind:t.kind,title:t.title,...typeof t.sessionId==`string`?{sessionId:t.sessionId}:{},...typeof t.plugin==`string`?{plugin:t.plugin}:{},...typeof t.tag==`string`?{tag:t.tag}:{}})}let o=n.ids.filter(e=>typeof e==`string`).slice(0,20);return{ts:t.ts,sessions:{n:n.n,ids:o},attention:{n:r.n,items:a}}}var Vf=1.25,Hf=(e,t,n)=>Math.min(n,Math.max(t,e));function Uf(e){return e.map(e=>({w:Number.isFinite(e.w)&&e.w>0?e.w:1,h:Number.isFinite(e.h)&&e.h>0?e.h:1}))}function Wf(e,t){let n=[];for(let r=0;r<e.length;r+=t)n.push(e.slice(r,r+t));return n}function Gf(e){let t=Uf(e);if(t.length<2)return 0;let n=t.reduce((e,t)=>e+(t.w+t.h)/2,0)/t.length;return Hf(Math.round(n*.012),4,40)}function Kf(e,t,n){let r=Wf(e.map((e,t)=>({...e,i:t})),t).map(e=>{let t=Math.max(...e.map(e=>e.h)),r=e.map(e=>({i:e.i,w:e.w/e.h*t,h:t}));return{h:t,w:r.reduce((e,t)=>e+t.w,0)+n*(e.length-1),cells:r}}),i=Math.max(...r.map(e=>e.w)),a=r.reduce((e,t)=>e+t.h,0)+n*(r.length-1),o=[],s=0;for(let e of r){let t=(i-e.w)/2;for(let r of e.cells)o.push({i:r.i,x:t,y:s,w:r.w,h:r.h}),t+=r.w+n;s+=e.h+n}return{width:i,height:a,cells:o,rows:r.length}}function qf(e,t=0,n=Vf){let r=Uf(e);if(r.length<2)return 1;let i=1,a=1/0;for(let e=1;e<=r.length;e++){let o=Kf(r,e,t),s=o.width/o.height,c=e*o.rows-r.length,l=Math.abs(Math.log(s/n))+.05*(c/r.length);l<a-1e-9&&(a=l,i=e)}return i}function Jf(e,t={}){let n=Uf(e);if(!n.length)return{cols:0,rows:0,gap:0,width:0,height:0,scale:1,cells:[]};let r=Math.max(0,Math.round(t.gap??Gf(n))),i=Hf(Math.round(t.cols??qf(n,r,t.targetAspect)),1,n.length),a=Kf(n,i,r),o=t.maxSide??4096,s=t.maxPixels??24e6,c=Math.min(1,o/Math.max(a.width,a.height),t.maxWidth&&t.maxWidth>0?t.maxWidth/a.width:1,Math.sqrt(s/(a.width*a.height))),l=Math.max(1,Math.round(a.width*c)),u=Math.max(1,Math.round(a.height*c)),d=a.cells.map(e=>{let t=Math.round(e.x*c),n=Math.round(e.y*c);return{i:e.i,x:t,y:n,w:Math.max(1,Math.min(Math.round(e.w*c),l-t)),h:Math.max(1,Math.min(Math.round(e.h*c),u-n))}});return{cols:i,rows:a.rows,gap:Math.round(r*c),width:l,height:u,scale:c,cells:d}}function Yf(e,t){return e<=1?`single`:t===1?`stacked`:t>=e?`${e} across`:`${t} × ${Math.ceil(e/t)}`}function Xf(e,t,n){return e<=1?``:`collage of ${e} panels ${t===1?`stacked top to bottom`:t>=e?`in one row, left to right`:`${t} per row, left to right then down`}${n?`, numbered 1-${e} in that order`:`, not numbered`}`}var Zf=524288,Qf=2592e6;function $f(e){return typeof e==`number`&&Number.isFinite(e)?e:null}function ep(e){let t;try{t=e?JSON.parse(e):null}catch{return{notes:[],tombs:[]}}if(!Array.isArray(t))return{notes:[],tombs:[]};let n=new Map,r=new Map;for(let e of t){if(!e||typeof e!=`object`)continue;let t=e;if(typeof t.id!=`string`||!t.id)continue;if(typeof t.text==`string`){let e=Array.isArray(t.steps)?t.steps.filter(e=>typeof e==`string`):[],r={id:t.id,text:t.text,ts:$f(t.ts)??0};e.length&&(r.steps=e),typeof t.cwd==`string`&&t.cwd&&(r.cwd=t.cwd);let i=n.get(r.id);(!i||r.ts>i.ts)&&n.set(r.id,r);continue}let i=$f(t.gone);if(i!==null){let e=r.get(t.id);(!e||i>e.gone)&&r.set(t.id,{id:t.id,gone:i})}}return{notes:[...n.values()],tombs:[...r.values()]}}function tp(e){let t={id:e.id,text:e.text,ts:e.ts};return e.steps&&e.steps.length&&(t.steps=e.steps),e.cwd&&(t.cwd=e.cwd),t}function np(e){return JSON.stringify(tp(e))}function rp(e){let t=[...e.notes].sort((e,t)=>t.ts-e.ts||(e.id<t.id?-1:+(e.id>t.id))),n=[...e.tombs].sort((e,t)=>t.gone-e.gone||(e.id<t.id?-1:+(e.id>t.id)));return JSON.stringify([...t.map(tp),...n.map(e=>({id:e.id,gone:e.gone}))])}function ip(e,t,n){let r=[...e.tombs,...t.tombs].filter(e=>e&&e.id&&Number.isFinite(e.gone)),i=[...e.notes,...t.notes].filter(e=>e&&e.id),a=0;for(let e of i)Number.isFinite(e.ts)&&e.ts>a&&(a=e.ts);for(let e of r)e.gone>a&&(a=e.gone);let o=a-Qf,s=new Map;for(let e of r){if(e.gone<o)continue;let t=s.get(e.id);(!t||e.gone>t.gone)&&s.set(e.id,{id:e.id,gone:e.gone})}let c=new Map;for(let e of i){let t=c.get(e.id);t?(e.ts>t.ts||e.ts===t.ts&&np(e)>np(t))&&c.set(e.id,e):c.set(e.id,e)}let l=[];for(let e of c.values()){let t=s.get(e.id);t?t.gone>=e.ts||(s.delete(e.id),l.push(e)):l.push(e)}let u=[...s.values()].sort((e,t)=>t.gone-e.gone||(e.id<t.id?-1:+(e.id>t.id)));return u.length>400&&(u=u.slice(0,400)),{notes:l,tombs:u}}function ap(e,t,n){let r=new Set(t.filter(e=>typeof e==`string`&&e));if(!r.size)return e;let i=new Map(e.tombs.map(e=>[e.id,e]));for(let e of r){let t=i.get(e);(!t||n>t.gone)&&i.set(e,{id:e,gone:n})}return{notes:e.notes.filter(e=>!r.has(e.id)),tombs:[...i.values()]}}function op(e,t){return{notes:e.notes.some(e=>e.id===t.id)?e.notes.map(e=>e.id===t.id?t:e):[t,...e.notes],tombs:e.tombs.filter(e=>e.id!==t.id)}}function sp(e,t,n){let r=rp(ip(ep(t),ep(e),n));return{value:r,changed:r!==e}}var cp=`Notes with no target yet — write them anywhere, offline included, and aim them later. A note that names a repo can be filed straight onto that repo's backlog. Sending or filing one uses the normal queue, so it survives a dead tunnel like anything else you type.`;function lp(e,t){return`the pad is full (${e} notes, ${t} KB) — your text is still in the editor; send, file or clear a note first`}var up=`this phone's storage refused the note — your text is still in the editor; free some space, or send or clear a note first`;function dp(e){return e===1?`one note that was kept on this phone is back on the pad`:`${e} notes that were kept on this phone are back on the pad`}var fp=`kept your unfinished prompt — it is a note on the pad`,pp=`the pad could not take your unfinished prompt, so it was left in the box — nothing was replaced`,mp={label:`file it`,title:e=>`put it on ${e}'s backlog as it is — it waits there, nothing runs now`};function hp(e,t){return t?`filed offline — it reaches ${e}'s backlog when the link is back`:`filed — on ${e}'s backlog`}function gp(e,t){if(!e.trim()||e===t)return null;let[n=``,...r]=e.split(`\f`);return r.length?{text:n,steps:r}:{text:n}}var _p=e=>e==null||e===`subscription`||e===`unknown`,vp={degradedMisses:2,brokenMisses:5,rateWindow:20,rateMinSamples:8,rateDegraded:.2,rateBroken:.5,rateMaxAgeMs:432e5,forgetMs:864e5},yp=[{id:`prompt.box`,name:`Reading a question box off the screen`,means:`The choice-box detector. When it stops matching there is no error and no empty state — a live question simply never reaches the phone, and the session sits blocked in silence.`,capture:`line`,fallback:`the weaker “something is asking you something” flag`},{id:`prompt.submit`,name:`Placing the cursor on a multi-select Submit row`,means:`Where the answer keystroke goes on a checkbox box. Without it the app sends a bare Return, which toggles whatever row the cursor happens to be on instead of submitting.`,capture:`line`,fallback:`a bare Return`},{id:`askbox.enrich`,name:`Reading the CLI's own words for a question box`,means:`The full question and per-option descriptions, taken from the conversation log rather than the truncated screen. Without it the phone shows one-tap buttons whose explanation is nowhere on the device.`,capture:`shape`,fallback:`the labels as the terminal cut them`},{id:`limit.reset`,name:`Reading when a usage block ends`,means:`The reset instant parsed out of the CLI's own block notice. Without it a blocked session has no time to resume at and waits for a blind sweep instead.`,capture:`line`,fallback:`a periodic re-scan with no scheduled resume`,thresholds:{forgetMs:2592e6}},{id:`context.meter`,name:`Reading the context-window figure`,means:`The context badge. A miss hides a number rather than losing work, which is why it is the one signal here allowed to fail a few more times before it is worth a word.`,capture:`line`,thresholds:{degradedMisses:4,brokenMisses:10}},{id:`hook.pipe`,name:`The CLI's lifecycle hooks`,means:`The positive turn-boundary signal. Without it a session falls back to guessing from silence, so turn ends get mushy, the backlog's readiness is a timer, and auto-fire can land mid-task.`,capture:`shape`,fallback:`silence heuristics`},{id:`deliver.echo`,name:`Confirming a prompt reached the composer`,means:`The echo probe. When it stops finding text, deliveries come back unconfirmed — which is not a lost prompt but is reported to the user as one, and is the exact signal that ran at 22% for a week.`,capture:`shape`,fallback:`asking the conversation log later`,thresholds:{degradedMisses:5,brokenMisses:8}},{id:`deliver.submit`,name:`Confirming a submitted prompt started a turn`,means:`Proof the Return was not swallowed. When it fails the app says the text is sitting unsent in a composer — a specific, actionable claim that must not be made about a prompt that is running.`,capture:`shape`,fallback:`asking the conversation log later`,thresholds:{degradedMisses:5,brokenMisses:8}},{id:`transcript.jsonl`,name:`Reading the CLI's conversation log`,means:`The reader view, the archive titles, and the evidence that settles an unconfirmable delivery. This is the witness that is not a rendering; without it the app is back to believing screens.`,capture:`shape`,fallback:`our own record of what we typed`},{id:`slash.local`,name:`Delivering a TUI-local command`,means:`Commands that open a view instead of running a turn. Get the list wrong in either direction and the app either hammers Return into the view it just opened, or waits for a turn that never starts.`,capture:`line`}],bp=new Map(yp.map(e=>[e.id,e]));function xp(e){return bp.get(e)??{id:e,name:e,means:``,capture:`shape`}}function Sp(e){return{...vp,...bp.get(e)?.thresholds??{}}}function Cp(){return{version:null,versionSeenAt:null,signals:{}}}function wp(e,t){return{id:e,version:t,lastGoodAt:null,lastMissAt:null,misses:0,missStreakSince:null,window:[],totalGood:0,totalMiss:0}}var Tp=/\/(?:Users|home)\/[^/\s]+/g,Ep=/\b[\w.+-]+@[\w-]+\.[\w.-]+\b/g,Dp=/(\b[a-z][a-z0-9+.-]*:\/\/)[^\s/@]+@/gi,Op=/\b(tokens?|secrets?|passwds?|passwords?|api[-_ ]?keys?|apikeys?|authorization|auth|bearer|cookies?|credentials?)\b\s*[:=]\s*(?:(?:bearer|basic|token|jwt)\s+)?\S+/gi,kp=/[A-Za-z0-9_+=-]{24,}/g;function Ap(e,t=240){let n=jp(e.replace(/\s+/g,` `).trim());return n.length>t?n.slice(0,t-1)+`…`:n}function jp(e){let t=e.replace(Dp,`$1<redacted>@`);return t=t.replace(Op,(e,t)=>`${t}=<redacted>`),t=t.replace(Ep,`<email>`),t=t.replace(Tp,`~`),t.replace(kp,e=>`<redacted:${e.length}>`)}function J(e,t,n){let r={...Sp(e.id),...n??{}},i=Math.max(e.lastGoodAt??0,e.lastMissAt??0)||null,a=e.window.filter(e=>t-e.at<=r.rateMaxAgeMs),o=a.length,s=a.reduce((e,t)=>e+ +!t.ok,0),c=o>=r.rateMinSamples?s/o:null,l=o?a[0].at:null,u={misses:e.misses,samples:o,failed:s,rate:c};return i==null?{...u,verdict:`unknown`,because:`no-observations`,since:null}:t-i>r.forgetMs?{...u,verdict:`unknown`,because:`gone-quiet`,since:i}:e.misses>=r.brokenMisses?{...u,verdict:`broken`,because:`misses`,since:e.missStreakSince}:c!=null&&c>=r.rateBroken?{...u,verdict:`broken`,because:`rate`,since:l}:e.misses>=r.degradedMisses?{...u,verdict:`degraded`,because:`misses`,since:e.missStreakSince}:c!=null&&c>=r.rateDegraded?{...u,verdict:`degraded`,because:`rate`,since:l}:e.lastGoodAt!=null&&e.lastGoodAt>(e.clearedAt??-1/0)?{...u,verdict:`healthy`,because:`confirmed`,since:e.lastGoodAt}:{...u,verdict:`unknown`,because:`no-observations`,since:i}}function Y(e){if(!Number.isFinite(e)||e<6e4)return`<1m`;let t=Math.floor(e/6e4);if(t<60)return`${t}m`;let n=Math.floor(t/60);return n<48?`${n}h`:`${Math.floor(n/24)}d`}function Mp(e,t){let n=xp(e.id),r=J(e,t),i=e.sample?n.capture===`line`?` Last input: “${e.sample}”.`:` Last input: ${e.sample}.`:``,a=e.lastGoodAt==null?`never confirmed at all`:`last confirmed ${Y(t-e.lastGoodAt)} ago`;switch(r.because){case`confirmed`:return`${n.name} is working — ${a}.`;case`no-observations`:return e.clearedAt==null?e.priorVersion?`${n.name} has not been checked since claude ${e.version??`?`} — its history was cleared when the CLI changed from ${e.priorVersion}.`:`${n.name} has not been checked yet.`:`${n.name}: you cleared its misses up to ${Y(t-e.clearedAt)} ago, and it has not been seen working since — unknown until the next check.`;case`gone-quiet`:return`${n.name} has gone quiet — nothing observed for ${Y(t-(r.since??t))}, so its state is unknown.`;case`misses`:return`${n.name} is ${r.verdict} — ${r.misses} misses in a row over the last ${Y(t-(r.since??t))}, ${a}.${i}`;case`rate`:return`${n.name} is ${r.verdict} — ${r.failed} of the last ${r.samples} failed (${Math.round((r.rate??0)*100)}%) over the last ${Y(t-(r.since??t))}, ${a}.${i}`}}function Np(e,t){return t!=null&&e.lastGoodAt!=null&&e.lastGoodAt>=t}function Pp(e,t){let n={broken:0,degraded:1,unknown:2,healthy:3};return Object.values(e.signals).filter(e=>J(e,t).verdict!==`healthy`).sort((e,r)=>n[J(e,t).verdict]-n[J(r,t).verdict])}function Fp(e,t){let n=[],r=[],i=[],a=!1;for(let o of Object.values(e.signals)){let e=J(o,t).verdict;e===`broken`?n.push(o.id):e===`degraded`?r.push(o.id):e===`unknown`?i.push(o.id):a=!0}return{verdict:n.length?`broken`:r.length?`degraded`:a?`healthy`:`unknown`,broken:n,degraded:r,unknown:i,lines:Pp(e,t).filter(e=>J(e,t).verdict!==`unknown`).map(e=>Mp(e,t)),version:e.version}}function Ip(e){let t=e??{},n=Cp();n.version=typeof t.version==`string`&&t.version?t.version.slice(0,40):null,n.versionSeenAt=X(t.versionSeenAt),X(t.versionChangedAt)!=null&&(n.versionChangedAt=X(t.versionChangedAt));let r=t.signals??{};for(let e of yp){let t=r[e.id];if(!t||typeof t!=`object`)continue;let i=Sp(e.id),a=Array.isArray(t.window)?t.window.filter(e=>!!e&&typeof e==`object`&&Number.isFinite(e.at)).map(e=>({at:Number(e.at),ok:e.ok===!0,...e.fallback?{fallback:!0}:{}})).slice(-i.rateWindow):[],o={id:e.id,version:typeof t.version==`string`&&t.version?t.version.slice(0,40):null,lastGoodAt:X(t.lastGoodAt),lastMissAt:X(t.lastMissAt),misses:Math.max(0,Math.min(9999,Math.round(Number(t.misses)||0))),missStreakSince:X(t.missStreakSince),window:a,totalGood:Math.max(0,Math.round(Number(t.totalGood)||0)),totalMiss:Math.max(0,Math.round(Number(t.totalMiss)||0))};X(t.lastFallbackAt)!=null&&(o.lastFallbackAt=X(t.lastFallbackAt)),typeof t.via==`string`&&t.via&&(o.via=t.via.slice(0,60)),typeof t.sample==`string`&&t.sample&&(o.sample=Ap(t.sample)),X(t.sampleAt)!=null&&(o.sampleAt=X(t.sampleAt)),typeof t.priorVersion==`string`&&t.priorVersion&&(o.priorVersion=t.priorVersion.slice(0,40)),X(t.clearedAt)!=null&&(o.clearedAt=X(t.clearedAt)),t.priorVerdict&&[`healthy`,`degraded`,`broken`,`unknown`].includes(t.priorVerdict)&&(o.priorVerdict=t.priorVerdict),n.signals[e.id]=o}return n}function X(e){let t=Number(e);return Number.isFinite(t)&&t>0?t:null}var Lp=[2e5,1e6];Lp[0],Lp[Lp.length-1];function Rp(e,t){return!t||t<=0?null:e/t*100}function zp(e){return typeof e==`number`&&Number.isFinite(e)&&e>0?Math.floor(e):null}function Bp(e,t){let n=zp(e),r=zp(t);if(n===null||r===null||r/n<.25)return null;let i=n-r,a=`${E(n)} window, ~${E(r)} of it used by the first request of the last session on this model (mostly Claude Code's own instructions and tools)`;return i<=0?`${a} — that is the whole window, so the runner will cut the prompt. Pick a model with a larger window.`:`${a} — ~${E(i)} is left for the conversation.`}var Vp={maxChars:16e3,hardChars:4e4,maxSkills:30};function Hp(e){if(e<1e3)return String(e);let t=e/1e3;if(t>=10)return`${Math.round(t)}k`;let n=Math.round(t*10)/10;return`${Number.isInteger(n)?n:n.toFixed(1)}k`}var Up=Hp,Wp=Hp;function Gp(e,t,n){let r=e===`size`?`over the ${t}`:`past the ${t}`;return n===`repo`?`${r} you set for this repo`:n===`env`?`${r} you asked to be warned at`:`${r} default`}function Kp(e,t=Vp,n={}){let r=e.skills.reduce((e,t)=>e+t.descChars,0),i=Math.max(0,e.claudeMdChars)+r,a=e.skills.reduce((e,t)=>e+Math.max(0,t.bodyChars-t.descChars),0),o=Math.round(i/4),s=e.skills.length,c=i>=t.hardChars?`steep`:i>=t.maxChars||s>t.maxSkills?`heavy`:`lean`,l=a>0?` ${Wp(a)} more is in ${s} skill${s===1?``:`s`}, loaded only when needed.`:``;if(c===`lean`)return{verdict:c,alwaysOnChars:i,alwaysOnTokens:o,onDemandChars:a,skillCount:s,note:`Every turn here carries ${Wp(i)} chars of agent instructions (~${Up(o)} tokens).${l}`,advice:null};let u=i>=t.maxChars;return{verdict:c,alwaysOnChars:i,alwaysOnTokens:o,onDemandChars:a,skillCount:s,note:u?`Every turn here carries ${Wp(i)} chars of agent instructions (~${Up(o)} tokens), ${Gp(`size`,Wp(t.maxChars),n.maxChars??`default`)}.${l}`:`${s} skills, ${Gp(`skills`,String(t.maxSkills),n.maxSkills??`default`)} — their descriptions are loaded on every turn even when no skill is.${l}`,advice:u?`This is paid on every turn of every session and every subagent here. What has to stay is what is dangerous not to know before acting; reference belongs in a skill and reasoning in the docs. The “groom CLAUDE.md” fan-out preset does exactly that.`:`Descriptions are the always-on part of a skill. Merging near-duplicates, or shortening the descriptions of ones you rarely load, costs nothing on-demand.`}}var qp=/^["']?description["']?[ \t]*:[ \t]*/;function Jp(e){let t=/^(?:[ \t]*\r?\n)*---[ \t]*\r?\n(?:([\s\S]*?)\r?\n)?---[ \t]*(?:\r?\n|$)/.exec(e.replace(/^\uFEFF/,``));return t?(t[1]??``).split(/\r?\n/):null}function Yp(e){let t=Jp(e);if(!t)return 0;let n=t.findIndex(e=>qp.test(e));if(n<0)return 0;let r=t[n].replace(qp,``).trim(),i=/^[>|][+-]?\d*$/.test(r)?[]:[r];for(let e=n+1;e<t.length&&!/^[A-Za-z_-]+:/.test(t[e]);e++)i.push(t[e].trim());return i.join(` `).trim().length}var Xp={maxChars:{min:1e3,max:2e6},hardChars:{min:1e3,max:4e6},maxSkills:{min:1,max:500}};function Zp(e,t){let n=Xp[e],r=Number(t);return Number.isFinite(r)?Number.isInteger(r)?r<n.min?`${e} must be at least ${n.min}.`:r>n.max?`${e} must be at most ${n.max}.`:null:`${e} must be a whole number.`:`${e} must be a number.`}function Qp(e,t,n){return Object.prototype.hasOwnProperty.call(e,t)?e[t]:n}function $p(e){return Jp(e)}function em(e,t){let n=$p(e);if(!n)return null;let r=n.findIndex(e=>RegExp(`^${t}:`).test(e));if(r<0)return null;let i=e=>e.trim().replace(/^['"]|['"]$/g,``).trim(),a=n[r].slice(t.length+1).trim();if(a)return(a.startsWith(`[`)?a.replace(/^\[|\]$/g,``):i(a)).split(`,`).map(i).filter(Boolean);let o=[];for(let e=r+1;e<n.length&&/^\s*-\s/.test(n[e]);e++)o.push(i(n[e].replace(/^\s*-\s/,``)));return o}var tm=new Set([`**`,`**/*`,`*`,`/**`,`./**`]);function nm(e){return e.some(e=>tm.has(e))?{kind:`always`}:{kind:`scoped`,globs:e}}function rm(e,t){let n=em(e,`applyTo`),r=Yp(e);return n&&n.length?[{readers:t,when:nm(n),chars:e.length}]:r>0?[{readers:t,when:{kind:`always`},chars:r},{readers:t,when:{kind:`on-demand`},chars:Math.max(0,e.length-r)}]:[{readers:t,when:{kind:`on-demand`},chars:e.length}]}function im(e,t){let n=em(e,`paths`);return[{readers:t,when:n&&n.length?nm(n):{kind:`always`},chars:e.length}]}function am(e,t){let n=Yp(e);return[{readers:t,when:{kind:`always`},chars:n},{readers:t,when:{kind:`on-demand`},chars:Math.max(0,e.length-n)}]}var om=`imported by CLAUDE.local.md`;function sm(e){return!(e.unsized||e.scope===`desktop`||e.kind===`subagent`||e.kind===`CLAUDE.local.md`||e.kind.endsWith(om))}function cm(e){let t=[],n=0;for(let r of e){if(!sm(r))continue;let e=r.parts.filter(e=>e.readers.includes(`claude`));if(e.length){if(r.kind===`skill`)t.push({name:r.path.split(`/`).slice(-2)[0],descChars:e[0].chars,bodyChars:e.reduce((e,t)=>e+t.chars,0)});else for(let t of e)t.when.kind===`always`&&(n+=t.chars)}}return{claudeMdChars:n,skills:t}}function lm(e,t){if(!e.endsWith(`.md`))return!1;let n=`.claude/${t}/`,r=0;for(let t=e.length-1;t>=0;t--){let n=e[t];if(n===`
13
+ `||n===`\r`||n===`\u2028`||n===`\u2029`){r=t+1;break}}for(let t=e.indexOf(n,r);t>=0;t=e.indexOf(n,t+1))if(!(t>0&&e[t-1]!==`/`))return e.length-(t+n.length)>=4;return!1}function um(e,t){let n=e.replace(/\\/g,`/`),r=n.split(`/`).pop()??n,i,a;if([`CLAUDE.md`,`AGENTS.md`,`GEMINI.md`,`copilot-instructions.md`].includes(r))i=r===`copilot-instructions.md`?`Copilot instructions`:r,a=[{readers:[],when:{kind:`always`},chars:t.length}];else if(r===`SKILL.md`)i=`skill`,a=am(t,[]);else if(r.endsWith(`.instructions.md`))i=`instructions`,a=rm(t,[]);else if(lm(n,`rules`))i=`rule`,a=im(t,[]);else if(/(^|\/)\.claude\/agents\/[^/]+\.md$/.test(n))i=`subagent`,a=am(t,[]);else if(lm(n,`commands`))i=`command`,a=am(t,[]);else return null;let o={kind:i,chars:t.length,always:0,scoped:0,onDemand:0};for(let e of a)e.when.kind===`always`?o.always+=e.chars:e.when.kind===`scoped`?o.scoped+=e.chars:o.onDemand+=e.chars;return o}function dm(e,t=String){let n=e=>`~${t(Math.round(e/4))} tokens`,r=`${n(e.chars)} · ${t(e.chars)} chars`;if(e.always===e.chars)return`${r}, all of it every turn`;let i=[];return e.always&&i.push(`${n(e.always)} every turn`),e.scoped&&i.push(`${n(e.scoped)} when a matching file is touched`),e.onDemand&&i.push(`${n(e.onDemand)} only when used`),i.length?`${r} (${i.join(`, `)})`:r}var fm=e=>Math.round(e/4),pm=(e,t,n=`${t}s`)=>`${e} ${e===1?t:n}`;function mm(e){return e.map(e=>{let t=[...new Set(e.parts.flatMap(e=>e.readers))],n=t=>e.unsized?null:e.parts.filter(e=>e.when.kind===t).reduce((e,t)=>e+t.chars,0),r={path:e.path,kind:e.kind,scope:e.scope??`repo`,readers:t,always:n(`always`),scoped:n(`scoped`),onDemand:n(`on-demand`),counted:sm(e)&&t.includes(`claude`)};return e.unsized&&(r.unsized=e.unsized),e.off&&(r.off=e.off),r})}function hm(e){let t=0,n=0,r=0,i=0;for(let a of e){if(a.unsized){a.unsized===`its tool schemas are sent by the server when it connects — not measurable from the file`?r++:i++;continue}let e=a.parts.filter(e=>e.readers.includes(`claude`)&&e.when.kind===`always`);e.length&&(n++,t+=e.reduce((e,t)=>e+t.chars,0))}return{chars:t,files:n,servers:r,other:i}}var gm=(e,t)=>(e.servers?` ${pm(e.servers,`MCP server`)} ${t}add tool schemas nobody can size from here.`:``)+(e.other?` ${pm(e.other,`more row`)} ${e.other===1?`has`:`have`} no size here; each says why.`:``);function _m(e,t=E){let n=e.filter(e=>e.scope!==`desktop`),r=e.filter(e=>e.scope===`desktop`),i=[],a=hm(n);if(a.files){let e=Kp(cm(n)).alwaysOnChars,r=a.chars-e,o=r>0?`; the threshold row counts ${t(e)} of those (CLAUDE.md, its imports, rules, skill descriptions), the other ${t(r)} are listed beside it (CLAUDE.local.md, subagent descriptions)`:`; the threshold row counts all of them (CLAUDE.md, its imports, rules, skill descriptions)`;i.push(`Claude Code carries ~${t(fm(a.chars))} tokens (${t(a.chars)} chars) from ${pm(a.files,`repo file`)} on every turn${o}.${gm(a,``)}`)}else n.length&&i.push(`Claude Code carries nothing from this repo's files on every turn.${gm(a,``)}`);let o=hm(r);return o.files?i.push(`This desktop adds ~${t(fm(o.chars))} tokens (${t(o.chars)} chars) from ${pm(o.files,`file`)} to every session, whatever the repo; the threshold row counts none of it.${gm(o,`of this desktop's `)}`):r.length&&(o.servers||o.other)&&i.push(gm(o,`of this desktop's `).trim()),i.join(` `)}var vm=`~/.claude`;function ym(e,t=vm){return e?e.startsWith(`~`)||e.startsWith(`/`)||/^[A-Za-z]:[\\/]/.test(e)||e.startsWith(`\\\\`)?e:`${uo(t,`\\/`)}/${e}`:`not on disk`}var bm=`everything else in the first request: your prompt, and whatever the harness sent that the log does not record (≈)`,xm=`(undocumented record)`;function Sm(e){let t=e.count;switch(e.kind){case`instructions`:return`instruction files`;case`skill_listing`:return t==null?`skill listing`:`skill listing (${pm(t,`skill`)})`;case`mcp_instructions`:return t==null?`MCP instructions`:`MCP instructions (${pm(t,`server`)})`;case`deferred_tools`:return t==null?`deferred tool names`:`deferred tool names (${t})`;case`agent_listing`:return t==null?`subagent listing`:`subagent listing (${t})`;case`hook_context`:return t!=null&&t>1?`hook context (${t})`:`hook context`;case`system_prompt`:return`system prompt ${xm}`;case`tool_schemas`:return`tool schemas ${xm}`;default:return`a part this app version cannot name`}}var Cm=(e,t)=>`~${t(fm(e))} tokens · ${t(e)} chars`;function wm(e,t=E){if(e.unsized)return{num:null,rest:e.unsized};let n=e.always??0,r=e.scoped??0,i=e.onDemand??0,a=[r?`+ ${Cm(r,t)} when a matching file is touched`:null,i?`+ ${Cm(i,t)} only when used`:null].filter(Boolean).join(`; `);return{num:n?Cm(n,t):`nothing every turn`,rest:a||null}}var Tm=e=>Math.round(e.parts.reduce((e,t)=>e+t.chars,0)/4);function Em(e){if(e.firstRequestTok==null)return null;let t=e.firstRequestTok-Tm(e);return t>=0?t:null}var Dm=`The parts' estimate already exceeds the request, so the rest (your prompt among it) cannot be placed.`;function Om(e,t=E){let n=e=>$s.indexOf(e),r=[...e.parts].sort((e,t)=>n(e.kind)-n(t.kind)).map(e=>{let n={key:e.kind,label:Sm(e),chars:e.chars,tok:fm(e.chars),words:Cm(e.chars,t)};return e.files&&(n.files=e.files.map(e=>({label:`${e.path} · ${e.type}`,path:e.path,type:e.type,chars:e.chars,words:Cm(e.chars,t)}))),e.names&&(n.names=e.names),e.undocumented&&(n.undocumented=!0),n}),i=Em(e);return i!=null&&r.push({key:`remainder`,label:bm,chars:null,tok:i,words:`≈${t(i)} tokens`}),r}var km={instructions:`the instruction files`,skill_listing:`the skill listing`,mcp_instructions:`MCP instructions`,deferred_tools:`deferred tool names`,agent_listing:`the subagent listing`,hook_context:`hook context`,system_prompt:`the system prompt`,tool_schemas:`tool schemas`},Am=e=>Qp(km,e,`a part this app version cannot name`),jm=e=>e.charAt(0).toUpperCase()+e.slice(1),Mm=e=>e.length<=1?e.join(``):`${e.slice(0,-1).join(`, `)} and ${e[e.length-1]}`;function Nm(e,t=E,n={}){let r=new Set(e.parts.map(e=>e.kind)),i=$s.filter(e=>r.has(e)&&e!==`system_prompt`&&e!==`tool_schemas`),a=e.parts.filter(e=>!e.undocumented&&e.kind!==`system_prompt`&&e.kind!==`tool_schemas`).reduce((e,t)=>e+t.chars,0),o=(e.laterKinds??[]).filter(e=>e in km),s=o.length?` ${jm(Mm(o.map(e=>Am(e))))} changed later in the conversation; the change is not folded in.`:e.laterDeltas>0?` ${e.laterDeltas===1?`One kind`:`${e.laterDeltas} kinds`} of these changed later in the conversation; the change is not folded in.`:``;if(e.firstRequestTok==null)return`No request has been answered yet; these are the attachments the CLI has written so far (chars).${s}`;let c=[`The first request carried ${t(e.firstRequestTok)} tokens.`];i.length&&c.push(`About ${t(fm(a))} of them (${t(a)} chars) are ${Mm(i.map(e=>Am(e)))} the CLI attached;`);let l=[`system_prompt`,`tool_schemas`].filter(e=>r.has(e)),u=[`system_prompt`,`tool_schemas`].filter(e=>!r.has(e)).map(e=>Am(e));if(l.length){let n=l.map(n=>{let r=e.parts.filter(e=>e.kind===n).reduce((e,t)=>e+t.chars,0);return`${Am(n)} at about ${t(fm(r))} tokens (${t(r)} chars)`});c.push(`${i.length?`an`:`An`} undocumented record puts ${Mm(n)};`)}let d=c[c.length-1].endsWith(`;`);return Em(e)==null?n.unplacedShown?d&&(c[c.length-1]=c[c.length-1].replace(/;$/,`.`)):c.push(d?Dm.replace(/^The/,`the`):Dm):c.push(`${d?`the`:`The`} rest is ${Mm([...u,`your prompt with what the harness added to it`])}.`),c.join(` `)+s}var Pm=`400k`,Fm=[`200k`,`300k`,`400k`,`500k`,`700k`],Im=[`auto-compact`,`android-toolchain`,`signing-key`,`protect-main`,`era-seen`,`local-ci-status`];function Lm(e){return`Install a JDK and the Android SDK into your home directory (${typeof e==`number`&&Number.isFinite(e)&&e>0?`about ${Rm(e)} to download`:`the download size depends on what is already installed`}, no sudo) and accept the Android SDK licence: https://developer.android.com/studio/terms`}Lm(null);function Rm(e){let t=Math.max(10,Math.round(e/1048576/10)*10);return t>=1e3?`${(t/1024).toFixed(1)} GB`:`${t} MB`}var zm=`Creates an Android signing key on this desktop in <config dir>/keys/ (readable only by you, mode 600) and points this repo's gitignored keystore.properties at it. Back it up: lose it and installed apps can no longer be updated.`,Bm=`CLAUDE_CODE_AUTO_COMPACT_WINDOW`;function Vm(e){return e>=1e6?`${+(e/1e6).toFixed(2)}M`:e>=1e3?`${+(e/1e3).toFixed(1)}k`:String(e)}`${Bm}${O.displayName}`;var Hm=[`waiting`,`running`,`done`,`failed`,`canceled`,`open`,`ended`];function Um(e){return`(${O.slug} opt-in: ${e})`}var Wm=new Map([{id:`requirements`,title:`Requirements list`,pitch:`A list of what this repo is expected to do, rebuilt from your own prompts and commits, so an agent checks it before changing behaviour you rely on.`,cost:`Setting it up writes two files and spends nothing. Each later build is one paid run, and the setup checklist's row says when one is due.`,verb:`set it up`,action:{kind:`fix`,fix:`requirements`}},{id:`repo-health`,title:`Repo health series`,pitch:`Size, complexity, churn and test readings for this repo, measured weekly and drawn as a trend, so a slow slide shows up before it hurts.`,cost:`Spends no tokens: a local tool runs once a week while the desktop is up. The first measurement is a tap on the series screen.`,verb:`open the series`,action:{kind:`open`,to:`series`}},{id:`repo-health-own`,title:`Your own health readings`,pitch:`Numbers only this repo knows about itself (test count, bundle size, open TODOs), measured beside the standard ones in the same weekly series.`,cost:`One agent session to propose them. The readings themselves spend no tokens.`,verb:`propose readings`,action:{kind:`agent`},prompt:`Propose 2-4 repo-specific health readings for {repo}: numbers this repo knows about itself that a generic metric cannot (for example test count, bundle size, number of TODO/FIXME, count of skipped tests).
14
+
15
+ They are declared in \`{shared}/health.json\` as
16
+ { "readings": [ { "key": "testCount", "name": "Tests", "means": "one sentence", "better": "higher" | "lower", "unit": "tests", "run": ["node", "tools/health/testcount.mjs"] } ] }
17
+ \`run\` is an argv array (no shell), run from the repo root, and must print ONE JSON number or {"value": n} to stdout; anything else makes the reading absent.
18
+
19
+ Show me the readings you propose and the small scripts behind them before writing anything. Only declarations that are committed run, so after I agree, write the files and tell me to commit them.
20
+
21
+ {marker}`},{id:`security-review`,title:`Weekly security review`,pitch:`Every Monday a session reads the week's changes and dependency bumps and writes its findings to the outbox. It changes nothing; you decide what to fix.`,cost:`One Fable session a week, the most capable and most expensive model, picked on purpose. You can change the model, day and time before you save it, and each run's cost shows on its row.`,verb:`schedule it`,action:{kind:`schedule`,days:[1],hour:9,minute:0,graceMin:720,model:`fable`},prompt:`Weekly security review of {repo}. Read-only: change no file, commit nothing, push nothing.
22
+
23
+ 1. Read what changed since the last review (\`git log --since="8 days ago" --stat\`, then the diffs that touch auth, input handling, file paths, shell/process spawning, network listeners, secrets or dependencies).
24
+ 2. Check the dependency manifests and lockfiles for new or bumped packages, install scripts and known-vulnerable versions (\`npm audit --omit=dev\` or the ecosystem's equivalent, if it runs offline-safe).
25
+ 3. Look for secrets committed by accident (keys, tokens, .env files) in the changed files.
26
+
27
+ Write the findings to \`.claude/outbox/security-review-<YYYY-MM-DD>.md\`: each finding with severity (high/medium/low), the file and line, why it matters, and a proposed fix as words. If nothing was found, write that and what you checked. Do not fix anything — the person decides.
28
+
29
+ {marker}`},{id:`local-ci`,title:`Checks before every push`,pitch:`A git pre-push hook that runs this repo's tests and lint on your desktop, so a broken push is caught without paying for hosted CI minutes.`,cost:`One agent session to set it up. After that the hook runs locally and spends no tokens.`,verb:`set it up`,action:{kind:`agent`},prompt:`Set up a local pre-push check for {repo}, so tests and lint run on this desktop before every push instead of in hosted CI.
30
+
31
+ 1. Find the commands this repo already uses to lint, type-check and test (package.json scripts, Makefile, pyproject, CI config).
32
+ 2. Propose one pre-push hook: what it runs, in what order, roughly how long it takes. Keep it fast enough that people will not skip it; slow suites can be a separate command.
33
+ 3. Show me the hook before installing it. Prefer a committed hooks directory (\`git config core.hooksPath\`) so it survives a fresh clone, and say how to bypass it in an emergency.
34
+
35
+ Do not change the tests or the lint rules themselves.
36
+
37
+ {marker}`},{id:`npm-supply-chain`,title:`Safer npm installs`,pitch:`An .npmrc that stops dependencies running code at install time and waits a few days before taking a freshly published version, when most hijacked releases are caught.`,cost:`One short agent session. It spends nothing afterwards.`,verb:`set it up`,action:{kind:`agent`},prompt:"Harden npm installs in {repo} with a committed `.npmrc`:\n\n- `ignore-scripts=true`: no dependency runs code at install time. First list which dependencies have install scripts (preinstall/install/postinstall) and say, per one, whether it works without it (prebuilds) or needs a replacement step in our own build.\n- `min-release-age=7`: a version must be a week old before `npm install` picks it. Check the installed npm version supports it and say so if it does not.\n\nShow me the file and the list before writing. `npm ci` from the lockfile is unaffected; say that in a comment in the file.\n\n{marker}"},{id:`gcp-cleanup`,title:`Registry cleanup policy (GCP)`,pitch:`Cloud Run scales to zero; its Artifact Registry does not. One image per deploy piles up and bills as storage until a cleanup policy deletes the old ones.`,cost:`One agent session. The policy usually lowers the storage bill. The desktop cannot check it from here, so mark it done once it is set.`,verb:`set it up`,action:{kind:`agent`},prompt:`{repo} deploys to Google Cloud. Check its Artifact Registry repositories and set a cleanup policy so images stop piling up:
38
+
39
+ 1. List the registry repos this project deploys to and their size (\`gcloud artifacts repositories list\`, and describe each one).
40
+ 2. Propose a policy (keep the 5 most recent versions, delete older than 7 days) and show it with \`--dry-run\` first.
41
+ 3. Never delete the image the live Cloud Run revision serves; a keep-recent rule protects it. Name that digest.
42
+
43
+ Apply with \`--no-dry-run\` only after I agree. The size metric lags about 24h after a delete; say so.
44
+
45
+ {marker}`},{id:`screenshots`,title:`Screenshots of your app`,pitch:`Let an agent (and you, from the phone) capture this app's screens on the desktop and check them, instead of describing what it probably looks like.`,cost:`Setting up a capture target spends nothing. Each screenshot an agent looks at costs tokens on every later turn, and the checklist then offers the skill that keeps that cheap.`,verb:`open captures`,action:{kind:`open`,to:`capture`}},{id:`exposure-watch`,title:`Exposure watch`,pitch:`Once a day this desktop looks up what the outside world now says about this repo: published advisories on its dependencies, deprecations and, for a private repo, a local Scorecard run. Findings land under watch.`,cost:`Spends no tokens and makes no AI call: a daily job runs gh and npm audit-type lookups and, for a private repo, Scorecard locally. A tap only adds this repo to the list it reads.`,verb:`watch this repo`,action:{kind:`fix`,fix:`exposure-watch`}},{id:`local-ci-status`,title:`Report local checks to GitHub`,pitch:`This repo's rules require a local-ci status before a pull request can merge. After a push from this phone's push button, the desktop tells GitHub the checks passed. It is the honor system: the status says the pre-push hook did not fail the push, not that anyone verified the tests. It covers pushes from this phone's push button, not pushes an agent or a terminal makes.`,cost:`One GitHub API call after each push from the phone; no tokens.`,verb:`report it`,action:{kind:`fix`,fix:`local-ci-status`}}].map(e=>[e.id,e]));function Gm(e){return Wm.get(e)}function Km(e,t){let n=Wm.get(e);return n?.prompt?n.prompt.replaceAll(`{repo}`,t).replaceAll(`{marker}`,Um(e)).replaceAll(`{shared}`,O.sharedDirName).replaceAll(`{skill}`,O.skillName):null}function qm(e,t){let n=Wm.get(e)?.action;return n?.kind===`schedule`?{kind:`weekly`,days:[...n.days],hour:n.hour,minute:n.minute,tz:t}:null}function Jm(e){let t={offered:[],started:[],active:[],declined:[],unfit:[]};for(let n of e)Wm.has(n.id)&&(n.choice===`declined`?t.declined.push(n):n.state===`on`||n.choice===`done`?t.active.push(n):n.relevant?n.sent||n.partial?t.started.push(n):t.offered.push(n):t.unfit.push(n));return t}function Ym(e){return e.state===`on`?`on`:`marked done by you`}function Xm(e,t){let n=e.map(e=>Wm.get(e.id)).filter(e=>!!e);if(n.length===0)return null;let r=n.filter(e=>e.action.kind===`agent`||e.action.kind===`schedule`),i=n.filter(e=>e.action.kind===`fix`||e.action.kind===`open`),a=[`Walk me through the optional features ${O.displayName} offers for ${t}. Do NOT set any of them up in this session.`,``,`1. For each one below, look at the repo briefly and tell me in one or two lines whether it fits here and what it would take. Then ask me which ones I want, in ONE question.`,`2. For each one I pick, post its prompt (quoted below, unchanged) as its own new-session work item in this repo, using the ${O.skillName} skill's way of posting work for later. A schedule one is posted as a weekly schedule with the model named. Do not run them here.`,`3. Finish with a list of what you posted, and nothing else.`,``];for(let e of r){let n=e.action.kind===`schedule`?` — weekly, ${Qm(e.action.days)} ${$m(e.action.hour)}:${$m(e.action.minute)}, model ${e.action.model}`:``;a.push(`## ${e.title}${n}`,e.pitch,e.cost,``,`Prompt:`,"```",Km(e.id,t)??``,"```",``)}if(i.length){a.push(`These are a tap on the phone's Opt-ins screen, not something to post. Just say whether they fit:`);for(let e of i)a.push(`- ${e.title}: ${e.pitch}`)}return a.join(`
46
+ `).trimEnd()}var Zm=[`Sunday`,`Monday`,`Tuesday`,`Wednesday`,`Thursday`,`Friday`,`Saturday`];function Qm(e){return e.length===0?`every day`:e.map(e=>Zm[e]??`?`).join(`, `)}function $m(e){return String(e).padStart(2,`0`)}function eh(e){if(!e||typeof e!=`object`)return null;let t=e;if(typeof t.id!=`string`||typeof t.relevant!=`boolean`||t.state!==`on`&&t.state!==`off`&&t.state!==`unknown`)return null;let n={id:t.id,relevant:t.relevant,state:t.state,detail:typeof t.detail==`string`?t.detail:``};(t.choice===`declined`||t.choice===`done`)&&(n.choice=t.choice);let r=t.sent;return r&&typeof r==`object`&&typeof r.at==`number`&&Number.isFinite(r.at)&&r.at>0&&Hm.includes(r.status)&&(n.sent={at:r.at,status:r.status}),t.partial===!0&&(n.partial=!0),n}var th=864e5;function nh(e,t){let n=new Date(e);return n.setDate(n.getDate()+t),n.getTime()}function rh(e,t){let n=new Date(e),r=new Date(t);return Math.round((Date.UTC(r.getFullYear(),r.getMonth(),r.getDate())-Date.UTC(n.getFullYear(),n.getMonth(),n.getDate()))/th)}var ih=e=>e.state===`done`?`done`:e.state===`failed`||e.state===`canceled`?`failed`:e.state===`running`?`running`:e.state===`starting`?`starting`:`pending`,ah=e=>e.split(`/`).filter(Boolean).pop()||e;function oh(e,t=10){let n=new Map;for(let t of e){if(!ma(t))continue;let e=n.get(t.groupId)??[];e.push(t),n.set(t.groupId,e)}let r=[];for(let[t,i]of n){let n=e.find(e=>e.id===t),a=i.filter(e=>e.origin===ra).sort((e,t)=>(e.order??e.createdAt)-(t.order??t.createdAt));if(!a.length&&!n)continue;let o=(n?.payload.kind===`prompt`?n.payload.steps[0]:void 0)??(a[0]?.payload.kind===`prompt`?a[0].payload.steps[0]:``),s=n?.createdAt??Math.min(...a.map(e=>e.createdAt)),c=e=>e.state===`done`||e.state===`failed`||e.state===`canceled`,l=i.some(e=>!c(e)),u=new Map;for(let e of i){if(!e.origin?.startsWith(`fanout:fu:`))continue;let t=e.origin.slice(ia.length);u.set(t,[...u.get(t)??[],e])}let d=[...u.values()].map(e=>({text:e[0].payload.kind===`prompt`?e[0].payload.steps[0]:``,at:Math.min(...e.map(e=>e.createdAt)),dirs:e.map(e=>e.cwd)})).sort((e,t)=>e.at-t.at);r.push({id:t,text:o,startedAt:s,finishedAt:l?void 0:Math.max(...i.map(e=>e.settledAt??e.createdAt)),targets:a.map(e=>({dir:e.cwd,title:e.title||ah(e.cwd),sessionId:e.sessionId,status:ih(e),error:e.state===`failed`||e.state===`canceled`?e.result?.detail:void 0})),followUps:d.length?d:void 0})}return r.sort((e,t)=>t.startedAt-e.startedAt).slice(0,t)}var sh=[{id:`security`,label:`Security`,ask:`Security: anything touching sign-in, permissions, secrets or keys, input handling, file or network access, what is exposed and to whom, or new attack surface. Say plainly when nothing does.`},{id:`behavior`,label:`What changes for users`,ask:`Behaviour a user would notice: new or removed features, changed defaults, screens, wording, timing, notifications. Describe it as the user experiences it, not as code.`},{id:`deploy`,label:`Deployment needed`,ask:`Deployment: does any of this need a deploy or release before it takes effect, and of WHICH component — e.g. web app only, backend / server / cloud functions, a mobile, watch or desktop app that needs a store release, infrastructure or config, a database migration. Name the components from the paths. Say when nothing needs deploying (docs, tests, tooling only).`},{id:`data`,label:`Data & migrations`,ask:`Data: changes to stored data, schemas, file formats or migrations; anything irreversible or that touches existing users' data.`},{id:`breaking`,label:`Breaking changes`,ask:`Compatibility: changed APIs, config files, environment variables, CLI flags or URLs; whether older clients, devices or saved state keep working.`},{id:`deps`,label:`Dependencies & cost`,ask:`Dependencies and cost: packages added or upgraded, new external services, new paid API calls or anything that adds a running cost.`},{id:`surprises`,label:`Surprises`,ask:`Surprises: changes the commit messages do not mention, edits unrelated to the stated goal, debug leftovers, disabled or weakened checks and tests, TODOs left behind.`},{id:`check`,label:`What to check by hand`,ask:`Risk: how risky this is (low / medium / high, one reason), and a short list of things to try by hand afterwards. Say whether tests cover the change.`}],ch=sh.map(e=>e.id);function lh(e){let t=new Set(Array.isArray(e)?e.filter(e=>typeof e==`string`):[]);return sh.filter(e=>t.has(e.id)).map(e=>e.id)}var uh=/^[A-Za-z0-9\-._~:/?#[\]@!$&'()*+,;=%]+$/,dh=/https?:\/\//g,fh=/[.,;:!?)\]}'"]+$/,ph=24;function mh(e,t){let n=e.slice(t),r=n.search(/\s/);return r===-1?n:n.slice(0,r)}function hh(e){let t=0;for(;t<e.length&&uh.test(e[t]);)t++;return t}function gh(e){return e.length-e.trimStart().length}function _h(e){let t=[],n=new Set,r=e.map(e=>e.trimEnd());for(let e=0;e<r.length;e++){dh.lastIndex=0;let i;for(;i=dh.exec(r[e]);){let a=i.index,o=mh(r[e],a),s=hh(o),c=o.slice(0,s),l=s<o.length-1&&uh.test(o[s+1]),u=!l&&a+c.length===r[e].length,d=c,f=1;if(u){let t=gh(r[e]),n=r[e].length,i=[],a=null;for(let o=e+1;o<r.length;o++){let e=r[o];if(gh(e)!==t)break;let s=e.slice(t);if(!s||/https?:\/\//.test(s))break;if(!uh.test(s)){let e=hh(s);e&&!/\s/.test(s)&&t+s.length===n&&(a=s.slice(0,e));break}i.push(s)}if(n>=ph){let e=0,r=!1;for(let a=0;a<i.length&&(r=t+i[a].length!==n,e=a+1,!r);a++);e&&(d+=i.slice(0,e).join(``),f=1+e),!r&&e===i.length&&a!==null&&(d+=a,f+=1,l=!0)}}l||(d=d.replace(fh,``)),d.length>i[0].length&&!n.has(d)&&(n.add(d),t.push(l?{url:d,line:e,lines:f,truncated:l}:{url:d,line:e,lines:f})),dh.lastIndex=a+o.length}}return t}function vh(e){return _h(e.split(`
47
+ `))}var yh=new Set(`/usage./cost./stats./context./status./todos./help./release-notes./config./model./output-style./statusline./vim./terminal-setup./agents./mcp./hooks./permissions./sandbox./add-dir./resume./rewind./clear./export./memory./bashes./remote-control./ide./upgrade./bug./feedback./privacy-settings./login./logout./effort./fast./theme./color./keybindings./skills./plugin./version./diff./copy`.split(`.`));function bh(e){return yh.has(e.trim().split(/\s+/)[0]??``)}var xh=new Set([`/btw`]);function Sh(e){return xh.has(e.trim().split(/\s+/)[0]??``)}[O.stateDirName,..._r];function Ch(e,t){let n=t.toLowerCase().split(/\s+/).filter(Boolean);return n.length?e.filter(e=>{let t=`${e.name} ${e.cmd} ${e.dir??``} ${e.source}`.toLowerCase();return n.every(e=>t.includes(e))}):e}var wh={supported:!1,canInstall:!1,silent:!1};function Th(e){if(!e||typeof e!=`object`)return{};let t=e,n={};return(t.distribution===`dev`||t.distribution===`play`)&&(n.distribution=t.distribution),typeof t.self==`string`&&t.self&&(n.self=t.self),n}function Eh(e){return e.distribution===`play`}function Dh(e,t){return Eh(t)&&!!e&&!!t.self&&e===t.self}var Oh=`this build updates through Google Play — install the new version from the Play Store`,kh=`could not read which app this file is, and this build installs only an app it can name`;function Ah(e){return`new builds of ${e} wait for a tap: this ${O.displayName} comes from Google Play, which does not let it install apps by themselves — every install asks`}var jh=`A build downloaded here installs with the phone's own confirm dialog, one tap each. This ${O.displayName} comes from Google Play, which does not let it install apps by themselves, and it updates itself only through Play.`;function Mh(e){let t=(e.name??``).toLowerCase(),n=(e.mime??``).toLowerCase();return t.endsWith(`.apk`)||n===`application/vnd.android.package-archive`}function Nh(e){return e.pkgLabel||e.pkg||e.name}function Ph(e,t){return!!e.pkg&&t.includes(e.pkg)}function Fh(e,t){return t?e.includes(t)?e.filter(e=>e!==t):[...e,t]:[...e]}function Ih(e,t){return!t.supported||!Mh(e)||e.state!==`done`?{verb:null,reason:null}:Dh(e.pkg,t)?{verb:null,reason:Oh}:Eh(t)&&!e.pkg?{verb:null,reason:kh}:e.evicted&&e.cleanedAt?{verb:null,reason:qh(e)}:e.evicted?{verb:null,reason:`the bytes were cleared to save space — fetch it again to install it`}:t.plainRoute?{verb:null,reason:gc}:t.canInstall?e.install===`installing`?{verb:null,reason:null}:{verb:`install`,reason:null}:{verb:null,reason:`this phone has not allowed ${O.displayName} to install apps`,settings:!0}}function Lh(e,t,n,r){switch(e){case`installing`:return`installing…`;case`asked`:return`waiting for you to confirm it on this phone`;case`installed`:return`installed${r?` · ${n} ${r}`:``}`;case`failed`:return`could not install: ${Rh(t)}`;default:return null}}function Rh(e){if(!e)return`the phone did not say why`;if(zh(e))return`this build is signed with a different key than the copy already on this phone, and Android only updates an app signed with the same key — a retry fails the same way. Either build it with the key the installed copy has, or uninstall that copy first (which deletes its data on this phone) and then install this one (INSTALL_FAILED_UPDATE_INCOMPATIBLE)`;if(/VERIFICATION_FAILURE/.test(e))return`Google Play Protect stopped it — it checks every app from outside the Play Store, and refused this build with nobody there to answer it. Retry with the phone in hand: if Play Protect asks, install anyway. If it refuses without asking, Play Store › Play Protect says why`;if(/Session was abandoned/i.test(e))return`the install was dropped before it finished — Android abandons one when the app is closed mid-install or the confirm dialog goes unanswered. A retry starts a fresh one`;let t=/allocate (\d+) because only (\d+) allocatable/i.exec(e);if(!t)return e;let n=e=>`${Math.ceil(e/1e6)} MB`,r=Number(t[1]),i=Number(t[2]),a=i>0?`only ${n(i)} of it is usable`:`none of it is usable yet`;return`this phone is out of space — it needs ${n(r)} beyond the room Android keeps in reserve (up to 500 MB), and ${a}. Free space until Settings shows about ${n(r+5e8-i)} free, then retry`}function zh(e){return!!e&&/INSTALL_FAILED_UPDATE_INCOMPATIBLE|signatures do not match/i.test(e)}function Bh(e,t){return e===`failed`&&zh(t)?`install after uninstalling the old copy`:e===`failed`?`retry install`:e===`installed`?`install again`:`install`}function Vh(e){return Lh(e.install,e.installError,Nh(e),e.pkgVersion)}function Hh(e,t){let n=e.mtime;return!e.pkg||!e.pkgVersion||!n||!t.some(t=>t.pkg===e.pkg&&t.pkgVersion===e.pkgVersion&&!!t.mtime&&t.mtime<n)?null:`same version (${e.pkgVersion}) as an older build on this phone — its repo does not raise the version on every build, so once installed the two cannot be told apart. Ask the repo's agent to raise it on every build`}function Uh(e,t,n){if(!t.supported||!Mh(e)||!e.pkg)return null;let r=Nh(e);return Dh(e.pkg,t)?Oh:Eh(t)?Ah(r):Ph(e,n)?t.canInstall?t.silent?e.install===`installed`?`new builds of ${r} install by themselves`:`new builds of ${r} install by themselves — the first one asks once`:`new builds of ${r} install by themselves, and this Android asks every time`:`${r} would install itself once this phone allows it`:`new builds of ${r} wait for a tap`}function Wh(e,t,n){if(!t.supported||!Mh(e)||!e.pkg||Eh(t))return null;let r=Ph(e,n);return{pkg:e.pkg,on:r,label:r?`stop installing ${Nh(e)} by itself`:`install ${Nh(e)} by itself`}}function Gh(e,t){if(!e.supported)return null;if(!e.canInstall)return`Allow ${O.displayName} to install apps and a build downloaded here can go straight onto this phone.`;if(Eh(e))return jh;if(!t.length)return`No app installs by itself yet — you can turn it on for an app, one at a time.`;let n=t.length;return n===1?`1 app installs itself when a new build arrives.`:`${n} apps install themselves when a new build arrives.`}function Kh(e){return e>=1e6?`${Math.round(e/1e6)} MB`:`${Math.max(1,Math.round(e/1e3))} kB`}function qh(e){let t=`APK deleted after it installed${e.cleanedBytes?` (${Kh(e.cleanedBytes)} freed)`:``} — fetch it again to reinstall`;return e.cleanNote?`${t} · ${e.cleanNote}`:t}`${O.stateDirName}`;var Jh=[`Jan`,`Feb`,`Mar`,`Apr`,`May`,`Jun`,`Jul`,`Aug`,`Sep`,`Oct`,`Nov`,`Dec`];function Yh(e){let t=new Date(e),n=e=>String(e).padStart(2,`0`);return`${t.getDate()} ${Jh[t.getMonth()]} ${n(t.getHours())}:${n(t.getMinutes())}`}function Xh(e){let t=e.sha?`${e.sha}${e.dirty?` + edits`:``}`:e.dirty?`uncommitted edits`:``;return[e.version??``,t,Yh(e.at)].filter(Boolean).join(` · `)}var Zh=/^[^\r\n]{1,200}$/,Qh=e=>typeof e==`string`&&Zh.test(e.trim())?e.trim():void 0;function $h(e){if(!e||typeof e!=`object`)return null;let t=e;if(typeof t.at!=`number`||!Number.isFinite(t.at)||t.at<=0)return null;let n={at:t.at},r=Qh(t.version),i=Qh(t.sha);return r&&(n.version=r),i&&/^[0-9a-f]{4,40}$/i.test(i)&&(n.sha=i),t.dirty===!0&&(n.dirty=!0),n}var eg=(e,t)=>Number.isFinite(e)&&Number.isFinite(t)&&Math.floor(e)>=20&&Math.floor(t)>=12,tg=e=>Math.min(e,160),ng=/\x1b\[[0-9;?]*[ -/]*[@-~]/y,rg=/[\n\r\u2028\u2029]/g;function ig(e){let t=``,n=0,r=-2,i=-2,a=-2,o=(e,t,n)=>e===-1||e>=t?e:n(t);for(let s=e.indexOf(`\x1B`);s>=0;s=e.indexOf(`\x1B`,s)){let c=e[s+1],l=-1;c===`[`?(ng.lastIndex=s,ng.test(e)&&(l=ng.lastIndex)):c===`P`||c===`X`||c===`^`||c===`_`?(r=o(r,s+2,t=>e.indexOf(`\x1B\\`,t)),a=o(a,s+2,t=>(rg.lastIndex=t,rg.exec(e)?.index??-1)),r>=0&&(a<0||a>r)&&(l=r+2)):c===`]`&&(i=o(i,s+2,t=>e.indexOf(`\x07`,t)),i>=0&&(l=i+1)),l<0?s++:(t+=e.slice(n,s),n=s=l)}return n===0?e:t+e.slice(n)}var ag=/^(?:\d+(?:\.\d+)?\s*(?:ms|s|m|h)\s*)+$/i,og=/\b(?:esc|ctrl\+|shift\+|tab)\b/i;function sg(e,t=!1){let n=[],r=e=>e!==void 0&&/[A-Za-z'-]/.test(e),i=e=>e!==void 0&&/[A-Za-z]/.test(e),a=e=>e!==void 0&&/\s/.test(e),o=t=>{for(;r(e[t]);)t++;return t},s=t=>{for(;a(e[t]);)t++;return e[t]===`…`?t+1:e.startsWith(`...`,t)?t+3:-1},c=0;for(;c<e.length;){if(!r(e[c])){c++;continue}let l=o(c),u=c;for(;u<l&&!i(e[u]);)u++;let d=-1,f=l;if(l-u>=4&&e.endsWith(`ing`,l)){if(!t)d=s(l);else for(let t=0;t<3&&d<0;t++){let t=f;for(;a(e[t]);)t++;if(t===f||!i(e[t]))break;f=o(t),d=s(f)}}d<0?c=l:(n.push(e.slice(u,f)),c=d)}return n}var cg=/^[▰▱▬█▓░▒⣿⠿\s]*[▰▱▬█▓░▒⣿⠿]{4,}[\s]*(\d{1,3})\s?%$/,lg=/^\s*[◯◉○●◎⏺]\s+[A-Za-z][\w:-]*\s{2,}\S/;function ug(e){let t=e.lastIndexOf(`·`);return t>=0&&/(?:^|\s)\d+(?:\.\d+)?\s*[smh]\s+$/i.test(e.slice(0,t))&&/^\s+[↓↑]\s*[\d.,]+(?:\s*[km])?\s+tokens?\s*$/i.test(e.slice(t+1))}function dg(e){if(!e)return null;let t=ig(e).split(/[\r\n]+/),n=e=>(e??``).replace(/[│┃|╭╮╰╯─]/g,` `).replace(/\s+/g,` `).trim(),r=null;for(let e=t.length-1;e>=0;e--){if(lg.test(t[e]??``)||ug(t[e]??``))continue;let i=n(t[e]);if(!i)continue;let a=[...i.matchAll(/\(([^()]*)\)/g)],o=a[a.length-1],s=o?i.slice(0,o.index):i,c=null,l=null,u=[];for(let e of(o?.[1]??``).split(`·`)){let t=e.trim();t&&!og.test(t)&&(!c&&ag.test(t)?c=t:!l&&/tokens?\b/i.test(t)?l=t:u.push(t))}let d=cg.exec(n(t[e+1]))?.[1]??cg.exec(i.slice(i.search(/[▰▱▬█▓░▒⣿⠿]/)<0?i.length:i.search(/[▰▱▬█▓░▒⣿⠿]/)))?.[1]??null;d&&u.push(`${d}%`);let f=sg(s),p=f.length||!(c||l||d)?[]:sg(s,!0),m=f[f.length-1]??p[p.length-1];if(!m)continue;let h=`${m}…`;if(!c&&!l&&!d){r??={phrase:h,elapsed:null,tokens:null,extra:[],text:h};continue}let g=[h,l,...u].filter(Boolean).join(` · `);return{phrase:h,elapsed:c,tokens:l,extra:u,text:g.length>140?`${g.slice(0,139)}…`:g}}return r}var fg=/\bto scroll\b/i;function pg(e){return e?fg.test(ig(e).slice(-2e3)):!1}function mg(e){if(e===`shift+tab`)return`\x1B[Z`;if(e===`ctrl+c`||e===`ctrl+g`)return null;let t=/^ctrl\+([a-z])$/.exec(e);return t?String.fromCharCode(t[1].charCodeAt(0)-96):/^[a-z0-9]$/.test(e)?e:null}function hg(e){if(e===`shift+tab`)return`⇧Tab`;let t=/^ctrl\+([a-z])$/.exec(e);return t?`^${t[1].toUpperCase()}`:e}var gg={up:`A`,down:`B`,right:`C`,left:`D`,home:`H`,end:`F`},_g={pgup:`5`,pgdn:`6`,delete:`3`},vg={tab:` `,enter:`\r`,esc:`\x1B`,backspace:``,space:` `,up:`\x1B[A`,down:`\x1B[B`,right:`\x1B[C`,left:`\x1B[D`,home:`\x1B[H`,end:`\x1B[F`,pgup:`\x1B[5~`,pgdn:`\x1B[6~`,delete:`\x1B[3~`},yg={"[":`\x1B`,"\\":``,"]":``,"^":``,_:``,"?":``,"@":`\0`," ":`\0`};function bg(e,t){return[e.ctrl&&`ctrl`,e.alt&&`alt`,e.shift&&`shift`,t===` `?`space`:t].filter(Boolean).join(`+`)}function xg(e){return!!(e.ctrl||e.alt||e.shift)}function Sg(e,t){let n=bg(e,t),r=e=>({refused:`${n} has no terminal bytes — ${e}`});if(!t)return r(`no key`);if(t in gg||t in _g){if(!xg(e))return{bytes:vg[t]};let n=1+ +!!e.shift+(e.alt?2:0)+(e.ctrl?4:0);return{bytes:t in gg?`\x1b[1;${n}${gg[t]}`:`\x1b[${_g[t]};${n}~`}}if(e.alt){let n=Sg({ctrl:e.ctrl,shift:e.shift},t);return`bytes`in n?{bytes:`\x1b${n.bytes}`}:r(`refused`in n?n.refused.replace(/^.*? — /,``):``)}let i=t===`space`?` `:t;if(e.ctrl){if(e.shift&&t!==`tab`)return r(`a plain terminal sends the same byte as without shift`);if(t===`tab`)return r(`terminals send Tab for it`);if(t===`enter`)return r(`terminals send Return for it`);if(t===`backspace`)return{bytes:`\b`};if(t===`esc`)return r(`terminals send Esc for it`);if(i.length===1){let e=i.toLowerCase();if(/^[a-z]$/.test(e))return{bytes:String.fromCharCode(e.charCodeAt(0)-96)};if(i in yg)return{bytes:yg[i]};if(i===`-`)return{bytes:``}}return r(`ctrl combines only with a letter or [ \\ ] ^ _ ? @ space`)}return e.shift?t===`tab`?{bytes:`\x1B[Z`}:t===`enter`?r(`terminals send Return for it; Alt+Return is claude's newline`):t===`space`?{bytes:` `}:t in vg?{bytes:vg[t]}:i.length===1?{bytes:i.toUpperCase()}:r(`unknown key`):t in vg?{bytes:vg[t]}:i.length===1?{bytes:i}:r(`unknown key`)}var Cg=16e3;function wg(e,t=Cg){let n=e.length*2,r=new ArrayBuffer(44+n),i=new DataView(r),a=(e,t)=>{for(let n=0;n<t.length;n++)i.setUint8(e+n,t.charCodeAt(n))};return a(0,`RIFF`),i.setUint32(4,36+n,!0),a(8,`WAVE`),a(12,`fmt `),i.setUint32(16,16,!0),i.setUint16(20,1,!0),i.setUint16(22,1,!0),i.setUint32(24,t,!0),i.setUint32(28,t*2,!0),i.setUint16(32,2,!0),i.setUint16(34,16,!0),a(36,`data`),i.setUint32(40,n,!0),new Int16Array(r,44).set(e),new Uint8Array(r)}function Tg(e){let t=new Int16Array(e.length);for(let n=0;n<e.length;n++){let r=Math.max(-1,Math.min(1,e[n]));t[n]=r<0?r*32768:r*32767}return t}var Eg=.25,Dg=new Set(`af.am.ar.as.az.ba.be.bg.bn.bo.br.bs.ca.cs.cy.da.de.el.en.es.et.eu.fa.fi.fo.fr.gl.gu.ha.haw.he.hi.hr.ht.hu.hy.id.is.it.ja.jw.ka.kk.km.kn.ko.la.lb.ln.lo.lt.lv.mg.mi.mk.ml.mn.mr.ms.mt.my.ne.nl.nn.no.oc.pa.pl.ps.pt.ro.ru.sa.sd.si.sk.sl.sn.so.sq.sr.su.sv.sw.ta.te.tg.th.tk.tl.tr.tt.uk.ur.uz.vi.yi.yo.yue.zh`.split(`.`)),Og={nb:`no`,jv:`jw`,iw:`he`,in:`id`,ji:`yi`,fil:`tl`,cmn:`zh`,mo:`ro`};function kg(e){let t=(e||``).trim().toLowerCase();if(!t||t===`auto`)return`auto`;let n=t.split(/[-_]/)[0],r=Og[n]||n;return Dg.has(r)?r:`auto`}var Ag=`auto`,jg={en:`English`,de:`German`,fr:`French`,es:`Spanish`,it:`Italian`,nl:`Dutch`,pt:`Portuguese`,pl:`Polish`,ru:`Russian`,uk:`Ukrainian`,cs:`Czech`,sv:`Swedish`,da:`Danish`,no:`Norwegian`,fi:`Finnish`,tr:`Turkish`,el:`Greek`,he:`Hebrew`,ar:`Arabic`,hi:`Hindi`,ja:`Japanese`,ko:`Korean`,zh:`Chinese`},Mg=[`en`,`de`];function Ng(e){return e===`auto`?`auto — whichever is spoken`:jg[e]||e}function Pg(e){return e===`auto`?`auto`:e.toUpperCase()}function Fg(e){return e===`auto`?`dictation is read as whichever language is spoken — pick one to pin it`:`dictation is read as ${Ng(e)} — anything else spoken is TRANSLATED into it`}function Ig(e){let t=Object.keys(jg).filter(e=>!Mg.includes(e)),n=[Ag,...Mg,...t],r=kg(e);return r!==`auto`&&!n.includes(r)&&n.push(r),n.map(e=>({code:e,label:Ng(e)}))}var Lg=[Ag,`en`,`de`];function Rg(e,t,n){let r=Ig(n),i=new Set(r.map(e=>e.code)),a=new Set((e||[]).map(e=>{let t=kg(e);return t===`auto`&&e.trim().toLowerCase()!==`auto`?``:t}).filter(e=>i.has(e)));if(!a.size)for(let e of Lg)i.has(e)&&a.add(e);let o=kg(t);return i.has(o)&&a.add(o),r.filter(e=>a.has(e.code))}function zg(e,t){let n=t.trim();if(!n)return e;let r=e.trimEnd();return r?`${r} ${n}`:n}var Bg=e=>e.replace(/\s+/g,` `).trim().slice(0,40).trim();function Vg(e){let t=[],n=new Map;for(let r of String(e||``).split(/\r?\n/)){let e=r.trim();if(!e||e.startsWith(`#`))continue;let i=e.indexOf(`:`),a=Bg(i<0?e:e.slice(0,i));if(!a)continue;let o=i<0?[]:e.slice(i+1).split(`,`).map(Bg).filter(Boolean),s=a.toLowerCase(),c=n.get(s);if(!c){if(t.length>=60)continue;c={term:a,heard:[]},n.set(s,c),t.push(c)}for(let e of o){if(c.heard.length>=8)break;e.toLowerCase()!==s&&(c.heard.some(t=>t.toLowerCase()===e.toLowerCase())||c.heard.push(e))}}return t}function Hg(e){let t=String(e||``).split(/\r?\n/).map(e=>e.trim()).filter(e=>e&&!e.startsWith(`#`)),n=new Set(t.map(e=>Bg(e.split(`:`)[0]).toLowerCase()).filter(Boolean));return Math.max(0,n.size-Vg(e).length)}function Ug(e){return e.map(e=>e.heard.length?`${e.term}: ${e.heard.join(`, `)}`:e.term).join(`
48
+ `)}var Wg=`\\p{L}\\p{N}`,Gg=e=>e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`);function Kg(e){return e.length>=3&&/^\S+$/.test(e)&&(/\p{N}/u.test(e)||/\p{Lu}/u.test(e.slice(1)))}function qg(e,t){if(!e||!t.length)return e;let n=[];for(let e of t){for(let t of e.heard){let r=t.split(` `).map(Gg).join(`[\\s\\-]+`);n.push({re:RegExp(`(?<![${Wg}])${r}(?![${Wg}])`,`giu`),term:e.term,keep:()=>!1,len:t.length})}if(/^\S+$/.test(e.term)&&e.term.length>=2&&e.term.length<=16){let t=Array.from(e.term).map(Gg).join(`[\\s.\\-]?`),r=Kg(e.term);n.push({re:RegExp(`(?<![${Wg}])${t}(?![${Wg}])`,`giu`),term:e.term,keep:t=>t===e.term||!/[\s.\-]/.test(t)&&!r,len:e.term.length})}}n.sort((e,t)=>t.len-e.len);let r=e;for(let e of n)r=r.replace(e.re,t=>e.keep(t)?t:e.term);return r}var Jg=`tools/repohealth.mjs`,Yg=`the repo-health engine`,Xg=vr(`repohealth.jsonl`),Zg=yr(`health.json`);function Qg(e){return!e||typeof e.hasRepoHealth!=`boolean`?`unknown`:e.hasRepoHealth?`offered`:`absent`}function $g(e){return e===`absent`?`No repo-health engine on this desktop — neither this repo's own ${Jg} nor a bundled one was found, so there is nothing to read the history with.`:e===`unknown`?`This desktop is older than repo health and cannot say whether this repo has it.`:null}function e_(e){return!e||!(`plot`in e)||e.plot===void 0?`unknown`:e.plot===null?`none`:`plotted`}function t_(e,t){return e===`none`?typeof t==`string`&&t.length>0?t:`${Yg} read no series to plot here — refresh it to measure one.`:e===`unknown`?`This desktop is older than the repo-health plot and sent no series to draw.`:null}var n_=e=>typeof e==`string`&&e.length>0;function r_(e){return e&&n_(e.recut)?e.recut:null}var i_=[`size`,`retouch`,`hatches`,`context`,`untested`],a_={lineMean:500,max:1e3,retouch:.15,hatches:2,untested:.2},o_=16e3,s_=e=>typeof e==`number`&&Number.isFinite(e)&&e>0,Z=e=>typeof e==`number`&&Number.isFinite(e)&&e>=0;function c_(e,t){return e<=0?100:100*Math.min(1,t/e)}function l_(e){if(typeof e!=`string`||!/^\d{4}-\d{2}-\d{2}$/.test(e))return null;let t=Date.parse(`${e}T00:00:00Z`);if(!Number.isFinite(t)||new Date(t).toISOString().slice(0,10)!==e)return null;let n=(new Date(t).getUTCDay()+6)%7;return new Date(t-n*864e5).toISOString().slice(0,10)}function u_(e){let t=new Map;for(let n of e){if(!n||typeof n.ts!=`number`)continue;let e=l_(n.day);if(!e)continue;let r=t.get(e);(!r||n.ts>=r.ts)&&t.set(e,n)}return[...t.entries()].sort(([e],[t])=>e<t?-1:+(e>t)).map(([e,t])=>({week:e,row:t}))}function d_(e){return 1*(s_(e)?e:o_)}function f_(e){let t={},n,r=e.size?.value;r&&Z(r.max)&&(n={value:r.max,path:typeof r.maxPath==`string`&&r.maxPath?r.maxPath:null}),r&&Z(r.lineMean)&&n&&(t.size=r.lineMean);let i=e.retouch?.value?.rate;Z(i)&&(t.retouch=i);let a=e.hatches,o=e.classics?.value?.loc;if(a?.value&&typeof a.value==`object`&&s_(o)){let e=0,n=!0;if(a.split&&typeof a.split==`object`)Z(a.split.unexplained)?e=a.split.unexplained:n=!1;else for(let t of Object.values(a.value)){if(!Z(t)){n=!1;break}e+=t}n&&(t.hatches=e/(o/1e3))}let s=e.context?.value,c=s?.claudeMdChars,l=s?.descChars;!s&&e.context?.reason===`no CLAUDE.md at this commit`?t.context=0:Z(c)&&(l==null||Z(l))&&(t.context=c+(typeof l==`number`?l:0));let u=e.untested?.value,d=e.classics?.value?.files;Array.isArray(u)&&s_(d)&&u.length<=d&&(t.untested=u.length/d);let f=m_(e);for(let e of f.disabled)delete t[e],e===`size`&&(n=void 0);for(let r of f.overridden){delete t[r];let i=e.central?.override?.[r]?.value;Z(i)&&(r!==`size`||n)&&(t[r]=i)}return t.size===void 0&&(n=void 0),n?{values:t,max:n}:{values:t}}var p_=e=>i_.includes(e);function m_(e){let t=e.central;if(!t||typeof t!=`object`)return{fp:``,disabled:[],overridden:[]};let n=typeof t.fp==`string`?t.fp:``,r=e=>e&&typeof e==`object`?Object.keys(e).filter(p_):[],i=i_.filter(e=>r(t.disabled).includes(e));return{fp:n,disabled:i,overridden:i_.filter(e=>r(t.override).includes(e)&&!i.includes(e))}}var h_=864e5;function g_(e){let t=e.classics?.value;return t&&Z(t.files)&&Z(t.loc)?{files:t.files,loc:t.loc}:null}var __=(e,t)=>Math.round((Date.parse(`${t}T00:00:00Z`)-Date.parse(`${e}T00:00:00Z`))/h_),v_=e=>Math.round(e).toString().replace(/\B(?=(\d{3})+(?!\d))/g,`,`),y_=e=>`${Math.round(e*100)}%`,b_=e=>(Math.round(e*10)/10).toFixed(1),x_={size:`file length`,retouch:`re-touches`,hatches:`escape hatches`,context:`CLAUDE.md + skill descriptions`,untested:`untested modules`};function S_(e,t,n,r,i){return`${e}: ${(()=>{switch(t){case`max`:return`${i??`the longest file`} is ${v_(n)} lines (good: under ${v_(r)})`;case`lineMean`:return`the average line sits in a file of ${v_(n)} lines (good: under ${v_(r)})`;case`retouch`:return`${y_(n)} of recent file edits rework the edit before (good: under ${y_(r)})`;case`hatches`:return`${b_(n)} unexplained escape hatches per 1,000 lines (good: under ${b_(r)})`;case`context`:return`CLAUDE.md + skill descriptions are ${v_(n)} chars (good: under ${v_(r)})`;case`untested`:return`${y_(n)} of source files have no test reaching them (good: under ${y_(r)})`}})()}`}function C_(e,t,n,r,i){let a=c_(n,r);if(!(a<50))return null;let o=a<25?`severe`:`warn`,s=i??void 0;return{level:o,entry:e,subject:t,value:n,good:r,score:a,...s?{path:s}:{},text:S_(o,t,n,r,s)}}function w_(e){if(!e.cappedBy||!(e.value<e.mean))return null;let t=Math.round(e.value-30);return`Capped at ${Math.round(e.value)} by ${Qp(x_,e.cappedBy,`an entry this app version cannot name`)} (${t} of 100): the entries average ${Math.round(e.mean)}, and the score stays within 30 of its worst entry.`}function T_(e,t,n){let r=i_.filter(e=>!t.includes(e));if(r.length===0||r.some(t=>e.values[t]===void 0))return null;let i=d_(n),a={},o=null,s=[];for(let t of r){let n=e.values[t];if(t===`size`){let t=e.max;o={lineMean:{value:n,score:c_(n,a_.lineMean)},max:{value:t.value,score:c_(t.value,a_.max),path:t.path}},a.size=Math.sqrt(o.lineMean.score*o.max.score);let r=C_(`size`,`lineMean`,n,a_.lineMean),i=C_(`size`,`max`,t.value,a_.max,t.path);r&&s.push(r),i&&s.push(i);continue}let r=t===`context`?i:a_[t];a[t]=c_(n,r);let c=C_(t,t,n,r);c&&s.push(c)}let c=r.length,l=Math.exp(r.reduce((e,t)=>e+Math.log(a[t]),0)/c),u=r[0];for(let e of r)a[e]<a[u]&&(u=e);let d=a[u]+30,f=Math.min(l,d);return s.sort((e,t)=>e.score-t.score),{index:f,mean:l,scores:a,sizeParts:o,cappedBy:d<l?u:null,alerts:s,enabled:r}}function E_(e,t){let n=[];for(let{week:r,row:i}of u_(e)){let e=m_(i),a=f_(i),o=T_(a,e.disabled,t);if(!o)continue;let s=typeof i.prereg==`string`?i.prereg:null,c=n[n.length-1],l={week:r,index:o.index,mean:o.mean,scores:o.scores,sizeParts:o.sizeParts,cappedBy:o.cappedBy,alerts:o.alerts,values:a.values,prereg:s,central:e.fp,disabled:e.disabled,overridden:e.overridden,tree:g_(i)};if(!c){n.push({...l,gap:!1,lnLink:null,comparable:0,contributions:{},spanDays:null});continue}let u=__(c.week,r),d=c.prereg===s?c.central===e.fp?null:`central`:`prereg`;if(d){n.push({...l,gap:!0,lnLink:null,comparable:0,contributions:{},spanDays:u,gapReason:d});continue}let f=o.enabled.length,p={};for(let e of o.enabled){let t=c.scores[e],n=o.scores[e];t!==void 0&&n!==void 0&&(p[e]=c.mean*(Math.log(n)-Math.log(t))/f)}n.push({...l,gap:!1,lnLink:Math.log(o.index/c.index),comparable:f,contributions:p,spanDays:u})}return n.length===0?null:{baselineWeek:n[0].week,points:n}}function D_(e,t){let n=T_(f_(e),m_(e).disabled,t);return n?{index:n.index,mean:n.mean,scores:n.scores,cappedBy:n.cappedBy}:null}function O_(e,t){if(e.length<=t)return[...e];let n=new Set,r=new Map;e.forEach((e,t)=>r.set(e.week,t));for(let e of r.values())n.add(e);let i=Math.ceil(e.length/Math.max(1,t));for(let t=0;t<e.length;t+=i){let r=t,a=t,o=Math.min(e.length,t+i);for(let n=t;n<o;n++)e[n].index<e[r].index&&(r=n),e[n].index>e[a].index&&(a=n);n.add(r),n.add(a)}return[...n].sort((e,t)=>e-t).map(t=>e[t])}function k_(e,t,n=240){let r=e.filter(e=>e&&typeof e.ts==`number`).sort((e,t)=>e.ts-t.ts),i=[],a=null;for(let e of r){let n=l_(e.day),r=n?D_(e,t):null;if(!n||!r)continue;let o=typeof e.prereg==`string`?e.prereg:null,s=m_(e).fp;i.push({sha7:typeof e.sha==`string`?e.sha.slice(0,7):``,day:e.day,ts:e.ts,week:n,index:r.index,mean:r.mean,cappedBy:r.cappedBy,gap:a!==null&&(a.prereg!==o||a.central!==s)}),a={prereg:o,central:s}}if(i.length===0)return null;let o=O_(i,n);return{points:o,total:i.length,thinned:o.length<i.length}}function A_(e){return!e||e.commits===void 0?`absent`:e.commits&&e.commits.points.length>0?`present`:`none`}function j_(e,t=12,n=e.length-1){let r=e[n];if(!r||!(t>0)||!Number.isFinite(r.index))return null;let i=Date.parse(`${r.week}T00:00:00Z`),a=i-t*7*h_;for(let t=n-1;t>=0;t--){let n=Date.parse(`${e[t].week}T00:00:00Z`);if(n>a)continue;let o=e[t];return o.index>0?{ratio:r.index/o.index,delta:r.index-o.index,then:o,now:r,weeks:Math.round((i-n)/(7*h_))}:null}return null}function M_(e,t){let n=[...e].sort((e,t)=>e-t),r=t/100*(n.length-1),i=Math.floor(r),a=Math.ceil(r);return n[i]+(n[a]-n[i])*(r-i)}function N_(e,t={}){let n=t.minWeeks??8,r=t.minMonthWindows??4,i=t.lowPct??10,a=t.highPct??90,o=t.minPoints??2,s=(e,t=null,n=null)=>({kind:null,horizon:t,delta:n,reason:e}),c=e[e.length-1];if(!c)return s(`no index yet`);let l=e.filter(e=>e.lnLink!==null);if(l.length<n)return s(`${l.length} weekly link${l.length===1?``:`s`} so far; a move is called after ${n}`);if(c.lnLink!==null){let t=l.slice(0,-1).map(e=>e.lnLink),n=e[e.length-2].index,r=c.index-n;if(c.lnLink<M_(t,i)&&-r>=o)return{kind:`drop`,horizon:`week`,delta:r,reason:`the latest week's link sits below the ${i}th percentile of ${t.length} earlier weeks`};if(c.lnLink>M_(t,a)&&r>=o)return{kind:`rise`,horizon:`week`,delta:r,reason:`the latest week's link sits above the ${a}th percentile of ${t.length} earlier weeks`}}let u=e.length-1;if(u<4)return s(`too few weeks for a four-week reading`);let d=t=>{for(let n=t-4+1;n<=t;n++)if(e[n].gap)return!0;return!1};if(d(u))return s(`the last four weeks span a change of definition, so there is no month move to compare`);let f=[];for(let t=4;t<u;t++)d(t)||f.push(Math.log(e[t].index/e[t-4].index));let p=c.index-e[u-4].index;if(f.length<r)return s(`${f.length} earlier four-week window${f.length===1?``:`s`}; a month move is called after ${r}`);let m=Math.log(c.index/e[u-4].index);return m<M_(f,i)&&-p>=o?{kind:`drop`,horizon:`month`,delta:p,reason:`the last four weeks sit below the ${i}th percentile of ${f.length} earlier four-week windows`}:m>M_(f,a)&&p>=o?{kind:`rise`,horizon:`month`,delta:p,reason:`the last four weeks sit above the ${a}th percentile of ${f.length} earlier four-week windows`}:s(`within this repo's usual range`,null,c.lnLink===null?null:c.index-e[u-1].index)}var P_={size:[`files grew longer`,`files got shorter`],retouch:[`more re-touched files`,`fewer re-touched files`],hatches:[`more escape hatches`,`fewer escape hatches`],context:[`CLAUDE.md + skill descriptions grew`,`CLAUDE.md + skill descriptions shrank`],untested:[`more untested modules`,`fewer untested modules`]};function F_(e){let t=Math.round(e);return t===0?`±0`:t<0?`−${-t}`:`+${t}`}function I_(e,t){return t&&e===t?`this week`:`in the week of ${e}`}function L_(e,t,n){let r=e[e.length-1];if(!r||!t.kind||!t.horizon||t.delta===null)return null;let i=Math.round(r.index),a=t.horizon===`week`?1:4,o=n&&r.week===n,s=t.horizon===`week`?I_(r.week,n):o?`over four weeks`:`over the four weeks to ${r.week}`,c={},l=0,u=null,d=null,f=null,p=0;for(let t=Math.max(1,e.length-a);t<e.length;t++){let n=e[t],r=e[t-1];if(n.gap)continue;let i=Math.log(n.mean/r.mean),a=Math.abs(i)<1e-12?1:Math.expm1(i)/i;for(let e of i_){let t=n.contributions[e];t!==void 0&&(c[e]=(c[e]??0)+t*a)}let o=n.index-r.index-(n.mean-r.mean);l+=o;let s=o>0?r.cappedBy:n.cappedBy;s&&Math.abs(o)>p&&(p=Math.abs(o),u=s,d=r.cappedBy,f=n.cappedBy)}let m=t.kind===`drop`?-1:1,h=i_.filter(e=>(c[e]??0)*m>0).map(e=>({pts:c[e]??0,words:P_[e][t.kind===`drop`?0:1]}));if(u&&l*m>0){let e=x_[u],t=m>0?f===u?`${e} holds the score down less`:`${e} no longer holds the score down`:d===u?`${e} holds the score down more`:`${e} now holds the score down`;h.push({pts:l,words:t})}let g=h.filter(e=>Math.round(e.pts)!==0).sort((e,t)=>Math.abs(t.pts)-Math.abs(e.pts)).slice(0,2).map(e=>`${e.words} (${F_(e.pts)})`),_=t.kind===`rise`?B_(e,a,(c.size??0)+(u===`size`?l:0),t.delta):null,ee=t.kind===`drop`?`slipped`:`rose`,te=Math.abs(Math.round(t.delta)),ne=g.length?`The score ${ee} ${te} point${te===1?``:`s`} ${s}: ${g.join(`, `)}.`:`The score ${ee} ${te} point${te===1?``:`s`} ${s}.`;return{chip:`Health ${i} ${F_(t.delta)}`,title:`Health score ${i} (${F_(t.delta)} ${s})`,body:_?`${ne} ${_}`:ne}}var R_=e=>Math.round(e).toString().replace(/\B(?=(\d{3})+(?!\d))/g,`,`),z_=1.5;function B_(e,t,n,r){if(!(r>0)||n<r/2)return null;let i=e[Math.max(0,e.length-t-1)]?.tree,a=e[e.length-1]?.tree;return!i||!a||i.files<=0||i.loc<=0||a.files<i.files*z_||a.loc<i.loc*.9?null:`Mostly files split up: ${R_(i.files)} → ${R_(a.files)} source files while the code went from ${R_(i.loc)} to ${R_(a.loc)} lines. The score cannot tell whether the design got better.`}function V_(e,t){let n=e?.points,r=n?.[n.length-1];if(!n||!r)return null;let i=n[n.length-2];return{value:r.index,deltaWeek:r.lnLink!==null&&i?r.index-i.index:null,week:r.week,move:t?.kind??null,mean:r.mean,cappedBy:r.cappedBy,alert:r.alerts[0]?.level??null,alertText:r.alerts[0]?.text??null}}var H_=[`requested`,`shipped`,`superseded`,`dropped`];function U_(e){let t=e.trim(),n=/^\d{4}-\d{2}-\d{2}/.exec(t)?.[0]??null,r=/session ([0-9a-f]{8})/.exec(t)?.[1]??null,i=t.indexOf(`(`),a=i<0?-1:t.indexOf(`)`,i+1),o=a<0?null:t.slice(i+1,a).trim();return{date:n,session:r,note:o&&!r?o:!n&&/^[0-9a-f]{8}$/.test(t)?t:null}}function W_(e,t){if(!e||!t)return 0;let n=e.split(`.`).map(e=>parseInt(e,10)||0),r=t.split(`.`).map(e=>parseInt(e,10)||0);for(let e=0;e<Math.max(n.length,r.length);e++){let t=(n[e]??0)-(r[e]??0);if(t)return t>0?1:-1}return 0}function G_(e,t){return!e||!t?null:W_(t,e)>0?{running:e,installed:t}:null}function K_(e,t){let n=`This session runs Claude ${e.running}; ${e.installed} is installed.`;if(!t.resumeId)return{text:n,cant:`its conversation id is not known yet, so a restart could not reopen the same conversation`};let r=[];t.turnActive&&r.push(`the turn that is running`);let i=t.agents??0;return i>0&&r.push(i===1?`1 background agent`:`${i} background agents`),t.shells&&r.push(`the background shells`),r.length?{text:n,loses:r.join(` and `)}:{text:n}}function q_(e){return{title:`Restart on Claude ${e.installed} first?`,lines:[`This session still runs Claude ${e.running}; ${e.installed} is installed.`,`Restart, then send: the same conversation reopens on ${e.installed} and this message is its first prompt.`,`Send on ${e.running}: the message goes now and the bar above stays — this is not asked again for this version.`],confirmLabel:`Restart, then send`,cancelLabel:`Send on ${e.running}`}}var J_=6e5;function Y_(e,t,n=J_){return e.cpuMovedAt===void 0&&e.outputAt===void 0?`unknown`:e.workers===0?`waiting`:t-Math.max(e.cpuMovedAt??0,e.outputAt??0)<n?`working`:`quiet`}function X_(e){let t=Math.max(0,Math.round(e/1e3)),n=Math.floor(t/86400),r=Math.floor(t%86400/3600),i=Math.floor(t%3600/60),a=t%60;return n>0?r>0?`${n}d ${r}h`:`${n}d`:r>0?i>0?`${r}h ${i}m`:`${r}h`:i>0?`${i}m`:`${a}s`}var Z_=/pgrep\s+-f\s+(?:"([^"]*)"|'([^']*)')/g,Q_=/[$^.*+?()[\]{}|\\]/;function $_(e){Z_.lastIndex=0;let t;for(;t=Z_.exec(e);){let e=t[1]??t[2]??``;if(e&&!Q_.test(e))return e}return null}function ev(e,t){if(e.foreground)return`a command this turn is running`;let n=X_(t-e.startedAt);if(e.serverLike)return`long-running by design · ${n}`;if(e.selfMatch){let t=$_(e.command);if(t)return`waits for "${t}" to end — its own command line matches that pattern, so this never ends`}let r=Y_(e,t);return r===`unknown`?`can't tell yet`:r===`working`?`running · ${n} · CPU moved ${X_(t-Math.max(e.cpuMovedAt??0,e.outputAt??0))} ago`:r===`waiting`?`waiting in a loop · ${n} · only sleeps between checks`:`quiet ${n} · no CPU and no output`}function tv(e,t,n=J_){let r={working:0,waiting:0,quiet:0,unknown:0,foreground:0,total:0};for(let i of e)i.foreground?r.foreground++:(r[Y_(i,t,n)]++,r.total++);return r}function nv(e){let t=e.total===1?`shell`:`shells`,n=`${e.total} ${t}`;if(!e.total)return n;let r=[`quiet`,`waiting`,`unknown`,`working`].find(t=>e[t]>0);if(!r)return n;let i=r===`working`?`running`:r;return e.total===1?`${n} · ${i}`:`${n} · ${e[r]} ${i}`}function rv(e){return e.description?e.description:e.command.trim().split(/\s+/).slice(0,3).join(` `)||`shell`}function iv(e,t){if(!e.total)return``;let n=[],r=0;for(let e of t)e.foreground||(e.workers===0?r++:n.push(rv(e)));r&&n.push(r===1?`1 wait loop`:`${r} wait loops`);let i=e.total===1?`background shell`:`background shells`;return`stops ${e.total} ${i}${n.length?` — ${n.join(`, `)}`:``}`}function av(e){let t=new Set(e.map(e=>e.id)),n=new Map;for(let r of e){if(!r.companionOf||r.companionOf===r.id||!t.has(r.companionOf))continue;let e=n.get(r.companionOf);e?e.push(r):n.set(r.companionOf,[r])}if(!n.size)return[...e];let r=new Set([...n.values()].flat().map(e=>e.id)),i=[],a=e=>{i.push(e);for(let t of n.get(e.id)??[])a(t)};for(let t of e)r.has(t.id)||a(t);if(i.length<e.length)for(let t of e)i.includes(t)||i.push(t);return i}function ov(e,t){if(e.companionOf){let n=t.find(t=>t.id===e.companionOf);return n?{target:n,to:`cli`}:null}let n=t.filter(t=>t.companionOf===e.id);return n.length?{target:n.reduce((e,t)=>(t.createdAt??0)>(e.createdAt??0)?t:e),to:`shell`}:null}var sv=A(`brand.migratedFrom`);function cv(e){for(let t of k)if(t.storagePrefix!==O.storagePrefix&&e.startsWith(t.storagePrefix))return O.storagePrefix+e.slice(t.storagePrefix.length);return null}function lv(e,t){if(e.getItem(sv)!==null)return{ran:!1,copied:[],kept:[]};let n=[];for(let t=0;t<e.length;t++){let r=e.key(t);r!==null&&n.push(r)}let r=[],i=[];for(let t of k)if(t.storagePrefix!==O.storagePrefix)for(let a of n){if(!a.startsWith(t.storagePrefix))continue;let n=O.storagePrefix+a.slice(t.storagePrefix.length);if(e.getItem(n)!==null){i.push(a);continue}let o=e.getItem(a);o!==null&&(e.setItem(n,o),r.push([a,n]))}let a={from:k.map(e=>e.slug),at:t};return e.setItem(sv,JSON.stringify(a)),{ran:!0,copied:r,kept:i}}`${O.slug}`;var uv=/^[A-Za-z0-9][A-Za-z0-9_-]{0,31}$/;function dv(e){if(typeof e!=`string`||!e.trim())return`no address given`;let t=/^([^:/\s]+):(\d{1,5})$/.exec(e.trim());if(!t)return`write the address as host:port`;let n=Number(t[2]);if(n<1||n>65535)return`the port must be 1-65535`;let r=t[1].toLowerCase(),i=/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/.exec(r);if(i){let e=i.slice(1).map(Number);return e.some(e=>e>255)||i.slice(1).some(e=>e.length>1&&e.startsWith(`0`))?`not a valid IPv4 address`:e[0]===127&&e[1]===0&&e[2]===0&&e[3]===1||e[0]===100&&e[1]>=64&&e[1]<=127?null:`only a Tailscale address (100.64.0.0/10) or 127.0.0.1 may be a peer`}if(r.endsWith(`.ts.net`)){let e=r.split(`.`);return e.length>=4&&e.every(e=>/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/.test(e))?null:`a MagicDNS name looks like <machine>.<tailnet>.ts.net`}return`only a Tailscale address (100.x or <machine>.<tailnet>.ts.net) or 127.0.0.1 may be a peer`}function fv(e,t){if(!e||typeof e.peer!=`string`||!e.peer)return``;let n={queued:`waiting on ${e.peer}`,waiting:`waiting on ${e.peer}`,running:`waiting on ${e.peer}`,limit:`${e.peer} is at its usage limit`,unreachable:`${e.peer} unreachable`,done:`${e.peer} has answered`,failed:`${e.peer}'s job failed`,refused:`${e.peer} refused the job`}[e.state];if(!n)return``;if(typeof t!=`number`||!Number.isFinite(t)||!Number.isFinite(e.since)||e.since<=0||t<e.since)return n;let r=Math.floor((t-e.since)/6e4);return`${n} · ${r<1?`just now`:r<60?`${r} min`:r<1440?`${Math.floor(r/60)} h`:`${Math.floor(r/1440)} d`}`}var Q=e=>typeof e==`number`&&Number.isFinite(e)&&e>0,pv=e=>typeof e==`number`&&Number.isFinite(e)&&e>=0;function mv(e){if(typeof e!=`string`)return null;let t=We(e),n=t?t.replace(/^claude-/,``):e.trim().toLowerCase();return/^[a-z0-9][a-z0-9._/-]{0,47}$/.test(n)?n:null}function hv(e){if(!e||typeof e!=`object`)return;let t=e,n={};Q(t.usd)&&(n.usd=t.usd);let r=t.tokens&&typeof t.tokens==`object`?t.tokens:null;r&&pv(r.in)&&pv(r.out)&&pv(r.cacheRead)&&pv(r.cacheWrite)&&r.in+r.out+r.cacheRead+r.cacheWrite>0&&(n.tokens={in:r.in,out:r.out,cacheRead:r.cacheRead,cacheWrite:r.cacheWrite});let i=mv(t.model);return i&&(n.model=i),Q(t.durationMs)&&(n.durationMs=t.durationMs),Q(t.weekPct)&&t.weekPct<=100&&(n.weekPct=t.weekPct),Q(t.unpricedTok)&&(n.unpricedTok=t.unpricedTok),Object.keys(n).length?n:void 0}function gv(e){if(!Q(e))return``;let t=Math.floor(e/6e4);if(t<1)return`<1 min`;if(t<60)return`${t} min`;if(t<1440){let e=Math.floor(t/60),n=t%60;return n?`${e} h ${n} min`:`${e} h`}let n=Math.floor(t/1440),r=Math.floor(t%1440/60);return r?`${n} d ${r} h`:`${n} d`}function _v(e){return Q(e)?e<.001?`<0.001% of week`:`≈${e<1?String(Number(e.toPrecision(1))):e<10?e.toFixed(1):String(Math.round(e))}% of week`:``}function vv(e){if(!e)return[];let t=[];Q(e.usd)&&t.push(x(e.usd)),e.model&&t.push(e.model);let n=gv(e.durationMs);return n&&t.push(n),t}var yv={queued:`queued there`,waiting:`waiting there`,running:`running`,limit:`at its usage limit`,unreachable:`unreachable`,done:`done`,failed:`failed`,refused:`refused`},bv=e=>yv[e]??``;function xv(e){if(!e||typeof e.peer!=`string`||!e.peer)return``;let t=bv(e.state);if(!t)return``;let n=typeof e.label==`string`&&e.label.trim()?e.label.trim():`a job`;return[`sent to ${e.peer}: ${n}`,t,...vv(e.cost)].join(` · `)}function Sv(e,t){if(!t?.length)return null;let n=new Map,r=0;for(let e of t){let t=e.cost?.usd;Q(t)?n.set(e.peer,(n.get(e.peer)??0)+t):r++}if(!n.size)return null;let i=[...n].map(([e,t])=>({peer:e,usd:t})),a=i.map(e=>`${x(e.usd)} on ${e.peer}`).join(` + `);return{text:`${Q(e)?`${x(e)} here + `:``}${a}${Q(e)?``:` (this desktop's share is not priced)`}${r?` · ${r} peer job${r===1?``:`s`} not priced`:``}`,peerUsd:i.reduce((e,t)=>e+t.usd,0),byPeer:i,unpriced:r}}function Cv(e,t,n){if(!e?.length||!Number.isFinite(t)||!Number.isFinite(n)||n<=t)return null;let r=new Map,i=0;for(let a of e){let e=a.cost?.usd;if(!Q(e))continue;let o=Q(a.endedAt)?a.endedAt:null;o!=null&&a.since>=t&&o<=n?r.set(a.peer,(r.get(a.peer)??0)+e):a.since<n&&(o==null||o>t)&&i++}if(!r.size)return null;let a=[...r].map(([e,t])=>({peer:e,usd:t}));return{usd:a.reduce((e,t)=>e+t.usd,0),byPeer:a,straddling:i,text:`incl. ${a.map(e=>`${x(e.usd)} on ${e.peer}`).join(` + `)}`}}function wv(e){if(!e||typeof e.from!=`string`||!e.from)return``;let t=e=>typeof e==`string`?e.replace(/\s+/g,` `).trim().slice(0,80):``;return[`job from ${e.from}`,t(e.askerLabel),t(e.label)].filter(Boolean).join(` · `)}var Tv=.1;function Ev(e){if(!Q(e.here))return null;let t=(e.peers??[]).filter(t=>t.ok&&Q(t.usd)&&t.weeklyResetAt!=null&&Math.abs(t.weeklyResetAt-e.weeklyResetAt)<36e5);if(e.sumAll&&t.length){let n=new Set(t.map(e=>e.peer)),r=(e.jobs?.byPeer??[]).filter(e=>!n.has(e.peer)),i=[...t.map(e=>({peer:e.peer,usd:e.usd})),...r];return{usd:e.here+i.reduce((e,t)=>e+t.usd,0),incl:`incl. ${i.map(e=>`${x(e.usd)} on ${e.peer}`).join(` + `)}`}}let n=e.here+(e.jobs?.usd??0),r=t.filter(e=>e.usd>=n*Tv);if(!e.sumAll&&r.length){let e=r.map(e=>`${e.peer} priced ${x(e.usd)}`).join(`, `);return{refused:`% of week not shown: this desktop priced ${x(n)} of the week, ${e} on the same account — a share from this desktop alone would read too high. Settings → count every paired desktop adds them.`}}return{usd:n,incl:e.jobs?.text??null}}var Dv={dark:{background:`#0b0d10`,foreground:`#d6dce5`},light:{background:`#fcfcfd`,foreground:`#1c2430`}},Ov=`--bg.--panel.--sub.--raise.--well.--line.--pipe-bg.--fg.--muted.--dim.--ring.--accent.--ok.--dead.--warn.--star.--limit.--ask.--pair.--purple.--sched.--defer.--ctx-low.--fu-hand.--fu-launch.--fu-agent.--fu-host.--on-accent.--on-accent-strong.--on-accent-line.--on-dead.--on-ok.--on-limit.--on-star.--on-media.--accent-wash.--accent-tint.--accent-tint-hi.--accent-edge.--accent-edge-hi.--ok-wash.--ok-edge.--pick-fill.--pick-edge.--dead-wash.--dead-tint.--dead-edge.--dead-edge-hi.--warn-wash.--warn-tint.--warn-tint-hi.--warn-edge.--star-wash.--star-edge.--star-edge-hi.--limit-edge.--ask-wash.--ask-tint-hi.--ask-edge.--ctx-low-edge.--hover-soft.--hover.--hover-hi.--sheen.--panel-veil.--panel-veil-hi.--bg-veil.--float-edge.--scrim.--scrim-media.--scrim-label.--shadow.--shadow-soft.--media-bg.--paper.--chart-1.--chart-2.--chart-3.--chart-4.--ctx-series.--ctx-compact.--ctx-limit.--repo-veil.--repo-veil-on`.split(`.`),kv=[`--accent`,`--ok`,`--dead`,`--warn`,`--star`,`--limit`,`--ask`,`--pair`,`--fu-agent`],Av=new Set(Ov),jv=new Set(kv),Mv=[`dark`,`light`],Nv=[`favicon`,`apple-touch`,`192`,`512`,`maskable`],Pv=new Set(Nv),Fv=/^(?:[A-Za-z0-9_][A-Za-z0-9._-]*\/)*[A-Za-z0-9_][A-Za-z0-9._-]*\.(?:png|svg)$/,Iv=e=>typeof e==`string`&&e.length<=200&&Fv.test(e)&&!e.split(`/`).some(e=>e===`.`||e===`..`),Lv=(e,t,n)=>Math.min(n,Math.max(t,e));function Rv(e,t,n){t=Lv(t,0,100)/100,n=Lv(n,0,100)/100,e=(e%360+360)%360;let r=t*Math.min(n,1-n),i=t=>(t+e/30)%12,a=e=>n-r*Math.max(-1,Math.min(i(e)-3,Math.min(9-i(e),1)));return[a(0),a(8),a(4)].map(e=>Math.round(e*255))}var zv=String.raw`[+-]?(?:\d+\.?\d*|\.\d+)`,Bv=new RegExp(String.raw`^(rgba?|hsla?)\(\s*(${zv})(%?)(?:\s*,\s*|\s+)(${zv})(%?)(?:\s*,\s*|\s+)(${zv})(%?)(?:\s*(?:,|\/)\s*(${zv})(%?))?\s*\)$`,`i`);function Vv(e){if(typeof e!=`string`)return null;let t=e.trim(),n=/^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i.exec(t);if(n){let e=n[1];e.length<=4&&(e=[...e].map(e=>e+e).join(``));let t=t=>parseInt(e.slice(t,t+2),16);return{r:t(0),g:t(2),b:t(4),a:e.length===8?Math.round(t(6)/255*1e3)/1e3:1}}if(n=Bv.exec(t),!n)return null;let r=n[1].toLowerCase(),i=n[8]===void 0?1:Lv(Number(n[8])/(n[9]?100:1),0,1);if(r.startsWith(`rgb`)){let e=(e,t)=>Math.round(Lv(t?Number(e)*255/100:Number(e),0,255));return{r:e(n[2],n[3]),g:e(n[4],n[5]),b:e(n[6],n[7]),a:i}}if(n[3]||!n[5]||!n[7])return null;let[a,o,s]=Rv(Number(n[2]),Number(n[4]),Number(n[6]));return{r:a,g:o,b:s,a:i}}var Hv=e=>e.toString(16).padStart(2,`0`),Uv=e=>`#${Hv(e.r)}${Hv(e.g)}${Hv(e.b)}`,Wv=e=>e.a>=1?Uv(e):`rgb(${e.r} ${e.g} ${e.b} / ${Math.round(e.a*1e3)/1e3})`,$=e=>!!e&&typeof e==`object`&&!Array.isArray(e);function Gv(e){let t=[],n={};if(!$(e))return e!=null&&t.push(`top level must be an object; nothing applied`),{overlay:n,notes:t};for(let n of Object.keys(e))n!==`displayName`&&n!==`colors`&&n!==`terminal`&&n!==`icons`&&!n.startsWith(`//`)&&t.push(`unknown key "${n}" ignored (allowed: displayName, colors, terminal, icons)`);if(e.displayName!==void 0){let r=typeof e.displayName==`string`?e.displayName.trim():``;!r||r.length>40||/[\u0000-\u001f\u007f]/.test(r)?t.push(`"displayName" must be 1–40 printable characters; ignored`):n.displayName=r}if(e.colors!==void 0){if(!$(e.colors))t.push(`"colors" must be an object of { dark, light }; ignored`);else for(let r of Object.keys(e.colors)){if(!Mv.includes(r)){t.push(`"colors.${r}" ignored (allowed: dark, light)`);continue}let i=e.colors[r];if(!$(i)){t.push(`"colors.${r}" must be an object of token → colour; ignored`);continue}let a={};for(let[e,n]of Object.entries(i)){let i=e.startsWith(`--`)?e:`--${e}`;if(i===`--term-bg`){t.push(`"colors.${r}.${e}" ignored: set "terminal.${r}.background" instead (the grid and its frame are one colour)`);continue}if(!Av.has(i)){t.push(`"colors.${r}.${e}" ignored: not a colour token of this version`);continue}let o=Vv(n);o?jv.has(i)&&o.a<1?t.push(`"colors.${r}.${e}" ignored: must be opaque (its tints are derived from it)`):a[i]=Wv(o):t.push(`"colors.${r}.${e}" ignored: ${JSON.stringify(n)} is not a colour (hex, rgb(), hsl())`)}Object.keys(a).length&&((n.colors??={})[r]=a)}}if(e.terminal!==void 0){if(!$(e.terminal))t.push(`"terminal" must be an object of { dark, light }; ignored`);else for(let r of Object.keys(e.terminal)){if(!Mv.includes(r)){t.push(`"terminal.${r}" ignored (allowed: dark, light)`);continue}let i=e.terminal[r];if(!$(i)){t.push(`"terminal.${r}" must be an object of { background, foreground }; ignored`);continue}let a={};for(let[e,n]of Object.entries(i)){if(e!==`background`&&e!==`foreground`){t.push(`"terminal.${r}.${e}" ignored (allowed: background, foreground)`);continue}let i=Vv(n);!i||i.a<1?t.push(`"terminal.${r}.${e}" ignored: ${JSON.stringify(n)} is not an opaque colour`):a[e]=Uv(i)}Object.keys(a).length&&((n.terminal??={})[r]=a)}}if(e.icons!==void 0){if(!$(e.icons))t.push(`"icons" must be an object of slot → path; ignored`);else{let r={};for(let[n,i]of Object.entries(e.icons))Pv.has(n)?Iv(i)?r[n]=i:t.push(`"icons.${n}" ignored: ${JSON.stringify(i)} is not a .png/.svg path relative to the config dir`):t.push(`"icons.${n}" ignored (allowed: ${Nv.join(`, `)})`);Object.keys(r).length&&(n.icons=r)}}return{overlay:n,notes:t}}var Kv=e=>!e||e.displayName===void 0&&!e.colors&&!e.terminal&&!e.icons;function qv(e,t){let n=t?.terminal?.[e];return!n||!n.background&&!n.foreground?Dv[e]:{...Dv[e],...n}}function Jv(e){if(!e)return``;let t=[];for(let n of Mv){let r=[];for(let[t,i]of Object.entries(e.colors?.[n]??{})){if(!Av.has(t))continue;let e=Vv(i);e&&(jv.has(t)?r.push(`${t}-rgb: ${e.r} ${e.g} ${e.b};`):r.push(`${t}: ${Wv(e)};`))}let i=e.terminal?.[n]?.background;if(i&&Vv(i)&&r.push(`--term-bg: ${Uv(Vv(i))};`),!r.length)continue;let a=n===`light`?`html[data-theme="light"]`:`html:not([data-theme="light"])`;t.push(`${a} { ${r.join(` `)} }`)}return t.join(`
49
+ `)}function Yv(e,t){let n=Vv(t?.colors?.[e]?.[`--bg`]);return n?Uv(n):null}function Xv(e){return e.pending||e.picked===`named`?!1:e.picked!==`chosen`||!e.rootExists}var Zv=`Fix the repo's weakest health reading`,Qv=["Make ONE focused improvement. Run the repo's tests. Commit on the current branch only if they pass: stage explicit paths, never `git add -A`, never push, never stash or reset.",`If nothing worth doing is left, change nothing and say so in one line.`];function $v(e){let t=e.healthSummary&&e.healthSummary.trim()?`Latest repo readings:\n${e.healthSummary.trim()}`:null,n=e.task&&e.task.trim(),r=n?[`What to work on (from the person who picked this repo):\n${n}`,...t?[t]:[]]:t?[t,`Pick the weakest reading.`]:[`Look for the repo's own checks, tests and lint, and pick the weakest area.`],i=e.note&&e.note.trim();return[`This is an unattended week-end burn package for ${e.repoName}. Nobody is watching, so keep it small.`,...r,...i?[`For this repo:\n${i}`]:[],...Qv].join(`
50
+
51
+ `)}var ey=`weekburn:`,ty=e=>!!e?.startsWith(ey),ny=`from the week-end burn`,ry=e=>`${e} from the week-end burn`;export{Xg as $,Tc as $a,Qn as $c,au as $i,Et as $l,ap as $n,wo as $o,Nd as $r,Ei as $s,ch as $t,c as $u,av as A,Yc as Aa,M as Ac,Ou as Ai,Rt as Al,Rp as An,L as Ao,sf as Ar,Ba as As,$h as At,We as Au,U_ as B,Hc as Ba,hr as Bc,zu as Bi,T as Bl,_p as Bn,$o as Bo,Ud as Br,Sa as Bs,Bh as Bt,Se as Bu,Cv as C,el as Ca,qr as Cc,Wu as Ci,bn as Cl,sm as Cn,Is as Co,Sf as Cr,oo as Cs,mg as Ct,b as Cu,cv as D,Jc as Da,Ur as Dc,qu as Di,Zt as Dl,Xp as Dn,hs as Do,pf as Dr,Ua as Ds,tg as Dt,Je as Du,sv as E,Wc as Ea,Hr as Ec,Ku as Ei,rn as El,Qp as En,ws as Eo,df as Er,za as Es,dg as Et,x as Eu,tv as F,$c as Fa,Or as Fc,Du as Fi,Jt as Fl,Mp as Fn,ls as Fo,of as Fr,ua as Fs,qh as Ft,Te as Fu,A_ as G,pc as Ga,vr as Gc,_u as Gi,Tt as Gl,cp as Gn,qo as Go,Rd as Gr,ya as Gs,Th as Gt,ne as Gu,L_ as H,_c as Ha,gr as Hc,Cu as Hi,C as Hl,pp as Hn,Qo as Ho,Bd as Hr,ga as Hs,Eh as Ht,Ce as Hu,G_ as I,Kc as Ia,Tr as Ic,Lu as Ii,qt as Il,J as In,as as Io,nf as Ir,va as Is,Rh as It,Me as Iu,w_ as J,bc as Ja,Kn as Jc,uu as Ji,jt as Jl,gp as Jn,Ko as Jo,jd as Jr,Ai as Js,Ch as Jt,_ as Ju,k_ as K,fc as Ka,pr as Kc,xu as Ki,Nt as Kl,up as Kn,Xo as Ko,Ld as Kr,fa as Ks,Lh as Kt,ee as Ku,q_ as L,Xc as La,Er as Lc,Nu as Li,Wt as Ll,Np as Ln,os as Lo,ef as Lr,ba as Ls,Gh as Lt,Ee as Lu,iv as M,Fc as Ma,kr as Mc,Au as Mi,Gt as Ml,Fp as Mn,us as Mo,af as Mr,Pa as Ms,jh as Mt,y as Mu,ev as N,Lc as Na,Ar as Nc,Ru as Ni,Kt as Nl,Y as Nn,fs as No,rf as Nr,Ma as Ns,Wh as Nt,ze as Nu,lv as O,Ic as Oa,Pr as Oc,Bu as Oi,It as Ol,Zp as On,_s as Oo,mf as Or,Ha as Os,eg as Ot,Xe as Ou,nv as P,Zc as Pa,jr as Pc,Pu as Pi,E as Pl,wp as Pn,ps as Po,Qd as Pr,la as Ps,Uh as Pt,we as Pu,Zg as Q,Sc as Qa,ir as Qc,su as Qi,Ot as Ql,ep as Qn,To as Qo,Fd as Qr,Di as Qs,sh as Qt,s as Qu,K_ as R,nl as Ra,O as Rc,Iu as Ri,zt as Rl,yp as Rn,ns as Ro,tf as Rr,Ta as Rs,Ih as Rt,De as Ru,fv as S,Uc as Sa,Gr as Sc,Hu as Si,Dn as Sl,ym as Sn,Ps as So,xf as Sr,io as Ss,xg as St,Be as Su,Ev as T,Bc as Ta,Br as Tc,Gu as Ti,un as Tl,dm as Tn,js as To,uf as Tr,La as Ts,pg as Tt,Ye as Tu,N_ as U,mc as Ua,A as Uc,wu as Ui,Ft as Ul,mp as Un,Yo as Uo,Vd as Ur,ha as Us,Dh as Ut,oe as Uu,V_ as V,gc as Va,mr as Vc,Su as Vi,Ut as Vl,fp as Vn,ts as Vo,zd as Vr,sa as Vs,Mh as Vt,be as Vu,j_ as W,hc as Wa,yr as Wc,bu as Wi,At as Wl,Zf as Wn,Jo as Wo,Hd as Wr,ca as Ws,Hh as Wt,re as Wu,l_ as X,z as Xa,ar as Xc,mu as Xi,Dt as Xl,lp as Xn,ko as Xo,Md as Xr,Oi as Xs,bh as Xt,m as Xu,E_ as Y,xc as Ya,Wn as Yc,hu as Yi,wt as Yl,hp as Yn,Fo as Yo,Id as Yr,ki as Ys,Sh as Yt,h as Yu,r_ as Z,wc as Za,Yn as Zc,lu as Zi,Pt as Zl,dp as Zn,Oo as Zo,Pd as Zr,Ti as Zs,vh as Zt,p as Zu,gv as _,rl as _a,Qr as _c,ed as _i,en as _l,wm as _n,Vs as _o,Of as _r,$a as _s,Tg as _t,$e as _u,ry as a,Hl as aa,gi as ac,q as ai,Vn as al,Ym as an,nc as ao,Jf as ar,Eo as as,qg as at,gt as au,bv as b,Oc as ba,Kr as bc,Xu as bi,En as bl,Om as bn,Rs as bo,Cf as br,ao as bs,Sg as bt,tt as bu,Yv as c,Ql as ca,ui as cc,yd as ci,zn as cl,Km as cn,Qs as co,Lf as cr,So as cs,Ug as ct,ct as cu,Kv as d,Xl as da,si as dc,vd as di,dn as dl,Fm as dn,Js as do,Af as dr,ho as ds,Cg as dt,et as du,ou as ea,Ci as ec,e as ed,wd as ei,rr as el,lh as en,uc as eo,rp as er,xo as es,Jg as et,Mt as eu,Dv as f,_l as fa,ci as fc,ud as fi,An as fl,Pm as fn,Xs as fo,jf as fr,co as fs,zg as ft,ut as fu,vv as g,vl as ga,$r as gc,nd as gi,nn as gl,Vm as gn,Ms as go,Df as gr,Qa as gs,Fg as gt,it as gu,dv as h,Fl as ha,ai as hc,ld as hi,yn as hl,Lm as hn,Hs as ho,Ef as hr,no as hs,Rg as ht,rt as hu,$v as i,Rl as ia,N as ic,i as id,gd as ii,qn as il,eh as in,sc as io,Gf as ir,Do as is,$g as it,ht as iu,Y_ as j,Nc as ja,Mr as jc,Tu as ji,Ht as jl,Ip as jn,ds as jo,$d as jr,Na as js,wh as jt,Ge as ju,ov as k,Mc as ka,Cr as kc,Vu as ki,w as kl,Bp as kn,As as ko,cf as kr,Ia as ks,Xh as kt,Ke as ku,qv as l,Zl as la,fi as lc,Sd as li,Fn as ll,qm as ln,Zs as lo,Rf as lr,go as ls,Ag as lt,st as lu,hv as m,Ll as ma,oi as mc,dd as mi,jn as ml,zm as mn,Ws as mo,Ff as mr,Ka as ms,Pg as mt,at as mu,Zv as n,ru as na,mi as nc,t as nd,pd as ni,Jn as nl,nh as nn,rc as no,Yf as nr,bo as ns,e_ as nt,mt as nu,Xv as o,Vl as oa,Si as oc,bd as oi,Bn as ol,Jm as on,tc as oo,qf as or,Co as os,Hg as ot,xt as ou,uv as p,Il as pa,ii as pc,fd as pi,Pn as pl,Im as pn,qs as po,Pf as pr,Wa as ps,Ig as pt,S as pu,x_ as q,R as qa,nr as qc,du as qi,kt as ql,sp as qn,Uo as qo,Ad as qr,$i as qs,Fh as qt,te as qu,ty as r,iu as ra,hi as rc,n as rd,hd as ri,tr as rl,rh as rn,ac as ro,Xf as rr,Ao as rs,t_ as rt,yt as ru,Gv as s,Kl as sa,pi as sc,xd as si,In as sl,Gm as sn,ec as so,Bf as sr,vo as ss,Vg as st,lt as su,ny as t,cu as ta,wi as tc,r as td,Td as ti,$n as tl,oh as tn,lc as to,op as tr,yo as ts,Qg as tt,Ct as tu,Jv as u,ql as ua,li as uc,Cd as ui,$t as ul,Xm as un,Ys as uo,zf as ur,_o as us,Eg as ut,ot as uu,xv as v,al as va,ni as vc,ad as vi,tn as vl,mm as vn,zs as vo,wf as vr,Za as vs,wg as vt,Qe as vu,_v as w,zc as wa,zr as wc,Uu as wi,xn as wl,um as wn,Bs as wo,ff as wr,Ra as ws,hg as wt,qe as wu,Sv as x,Ac as xa,Wr as xc,Yu as xi,On as xl,Nm as xn,Us as xo,vf as xr,so as xs,bg as xt,Ve as xu,wv as y,ol as ya,ri as yc,Ju as yi,Mn as yl,_m as yn,Ls as yo,Tf as yr,ro as ys,kg as yt,nt as yu,H_ as z,qc as za,k as zc,Fu as zi,Lt as zl,xp as zn,is as zo,Wd as zr,oa as zs,Vh as zt,xe as zu};