@prestyj/cli 5.11.0 → 5.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (366) hide show
  1. package/assets/skills/compliance-guard/SKILL.md +251 -0
  2. package/assets/skills/compliance-guard/references/artifacts.md +186 -0
  3. package/assets/skills/compliance-guard/references/eu-uk.md +151 -0
  4. package/assets/skills/compliance-guard/references/exposure-triage.md +161 -0
  5. package/assets/skills/compliance-guard/references/lawsuit-vectors.md +141 -0
  6. package/assets/skills/compliance-guard/references/provenance.md +42 -0
  7. package/assets/skills/compliance-guard/references/sector-gates.md +173 -0
  8. package/assets/skills/compliance-guard/references/security-baseline.md +130 -0
  9. package/assets/skills/compliance-guard/references/trigger-map.md +163 -0
  10. package/assets/skills/compliance-guard/references/us.md +164 -0
  11. package/dist/app-sidecar-auth-broadcast.test.js +69 -3
  12. package/dist/app-sidecar-auth-broadcast.test.js.map +1 -1
  13. package/dist/app-sidecar-sessions.test.js +1 -1
  14. package/dist/app-sidecar.js +119 -45
  15. package/dist/app-sidecar.js.map +1 -1
  16. package/dist/chat-agents/jiwa.test.js +1 -1
  17. package/dist/cli/auth.d.ts.map +1 -1
  18. package/dist/cli/auth.js +33 -36
  19. package/dist/cli/auth.js.map +1 -1
  20. package/dist/cli.d.ts.map +1 -1
  21. package/dist/cli.js +12 -1
  22. package/dist/cli.js.map +1 -1
  23. package/dist/config.d.ts +16 -5
  24. package/dist/config.d.ts.map +1 -1
  25. package/dist/config.js +35 -76
  26. package/dist/config.js.map +1 -1
  27. package/dist/config.test.js +20 -12
  28. package/dist/config.test.js.map +1 -1
  29. package/dist/core/agent-session-checkpoint-flush.test.js +2 -2
  30. package/dist/core/agent-session-crash-durability.test.js +3 -3
  31. package/dist/core/agent-session-model-switch.test.js +1 -1
  32. package/dist/core/agent-session-process-gate.test.js +7 -1
  33. package/dist/core/agent-session-process-gate.test.js.map +1 -1
  34. package/dist/core/agent-session-review-coverage.test.js +1 -1
  35. package/dist/core/agent-session-tool-tiers.test.d.ts +2 -0
  36. package/dist/core/agent-session-tool-tiers.test.d.ts.map +1 -0
  37. package/dist/core/agent-session-tool-tiers.test.js +138 -0
  38. package/dist/core/agent-session-tool-tiers.test.js.map +1 -0
  39. package/dist/core/agent-session.d.ts +43 -3
  40. package/dist/core/agent-session.d.ts.map +1 -1
  41. package/dist/core/agent-session.js +142 -31
  42. package/dist/core/agent-session.js.map +1 -1
  43. package/dist/core/agents.d.ts +29 -1
  44. package/dist/core/agents.d.ts.map +1 -1
  45. package/dist/core/agents.js +47 -97
  46. package/dist/core/agents.js.map +1 -1
  47. package/dist/core/agents.test.js +87 -7
  48. package/dist/core/agents.test.js.map +1 -1
  49. package/dist/core/api-benchmark.d.ts +3 -3
  50. package/dist/core/api-benchmark.js +7 -7
  51. package/dist/core/auth-providers.d.ts +37 -1
  52. package/dist/core/auth-providers.d.ts.map +1 -1
  53. package/dist/core/auth-providers.js +83 -3
  54. package/dist/core/auth-providers.js.map +1 -1
  55. package/dist/core/auto-update.test.js +1 -1
  56. package/dist/core/autopilot-gate.d.ts +2 -2
  57. package/dist/core/autopilot-gate.js +1 -1
  58. package/dist/core/bash-spawn-benchmark.js +6 -6
  59. package/dist/core/bundled-agents.d.ts +3 -0
  60. package/dist/core/bundled-agents.d.ts.map +1 -0
  61. package/dist/core/bundled-agents.js +252 -0
  62. package/dist/core/bundled-agents.js.map +1 -0
  63. package/dist/core/cache-warm-benchmark.d.ts +2 -2
  64. package/dist/core/cache-warm-benchmark.js +5 -5
  65. package/dist/core/code-retrieval-chunkers.d.ts +27 -0
  66. package/dist/core/code-retrieval-chunkers.d.ts.map +1 -0
  67. package/dist/core/code-retrieval-chunkers.js +264 -0
  68. package/dist/core/code-retrieval-chunkers.js.map +1 -0
  69. package/dist/core/code-retrieval-chunkers.test.d.ts +2 -0
  70. package/dist/core/code-retrieval-chunkers.test.d.ts.map +1 -0
  71. package/dist/core/code-retrieval-chunkers.test.js +203 -0
  72. package/dist/core/code-retrieval-chunkers.test.js.map +1 -0
  73. package/dist/core/code-retrieval.d.ts +6 -0
  74. package/dist/core/code-retrieval.d.ts.map +1 -1
  75. package/dist/core/code-retrieval.js +38 -1
  76. package/dist/core/code-retrieval.js.map +1 -1
  77. package/dist/core/encode-cwd.test.js +1 -1
  78. package/dist/core/extensions/plugin-bundles.js +2 -2
  79. package/dist/core/extensions/plugin-bundles.js.map +1 -1
  80. package/dist/core/extensions/plugin-bundles.test.js +2 -2
  81. package/dist/core/extensions/plugin-bundles.test.js.map +1 -1
  82. package/dist/core/fast-apply-benchmark.d.ts +2 -2
  83. package/dist/core/fast-apply-benchmark.js +6 -6
  84. package/dist/core/foreign-session-import.test.js +1 -1
  85. package/dist/core/goal-lifecycle-smoke.test.js +2 -2
  86. package/dist/core/goal-store.js +1 -1
  87. package/dist/core/goal-store.test.js +2 -2
  88. package/dist/core/goal-verifier.test.js +2 -2
  89. package/dist/core/goal-worker-dev-server-lifecycle.test.js +1 -1
  90. package/dist/core/goal-worker.test.js +2 -2
  91. package/dist/core/hashline-edit-benchmark.d.ts +2 -2
  92. package/dist/core/hashline-edit-benchmark.js +7 -7
  93. package/dist/core/local-endpoint-store.test.js +1 -1
  94. package/dist/core/logger.d.ts +1 -1
  95. package/dist/core/logger.js +2 -2
  96. package/dist/core/logger.js.map +1 -1
  97. package/dist/core/lsp/client-navigation.test.d.ts +2 -0
  98. package/dist/core/lsp/client-navigation.test.d.ts.map +1 -0
  99. package/dist/core/lsp/client-navigation.test.js +135 -0
  100. package/dist/core/lsp/client-navigation.test.js.map +1 -0
  101. package/dist/core/lsp/client.d.ts +69 -0
  102. package/dist/core/lsp/client.d.ts.map +1 -1
  103. package/dist/core/lsp/client.js +151 -2
  104. package/dist/core/lsp/client.js.map +1 -1
  105. package/dist/core/lsp/integration.test.js +2 -2
  106. package/dist/core/lsp/manager-navigation.test.d.ts +2 -0
  107. package/dist/core/lsp/manager-navigation.test.d.ts.map +1 -0
  108. package/dist/core/lsp/manager-navigation.test.js +121 -0
  109. package/dist/core/lsp/manager-navigation.test.js.map +1 -0
  110. package/dist/core/lsp/manager.d.ts +35 -1
  111. package/dist/core/lsp/manager.d.ts.map +1 -1
  112. package/dist/core/lsp/manager.js +92 -0
  113. package/dist/core/lsp/manager.js.map +1 -1
  114. package/dist/core/lsp/servers.test.js +1 -1
  115. package/dist/core/lsp/windows.test.js +4 -4
  116. package/dist/core/mcp/catalog-cache.test.js +1 -1
  117. package/dist/core/mcp/client-session-recovery.test.js +1 -1
  118. package/dist/core/mcp/client.d.ts.map +1 -1
  119. package/dist/core/mcp/client.js +2 -10
  120. package/dist/core/mcp/client.js.map +1 -1
  121. package/dist/core/mcp/content.d.ts +19 -0
  122. package/dist/core/mcp/content.d.ts.map +1 -0
  123. package/dist/core/mcp/content.js +172 -0
  124. package/dist/core/mcp/content.js.map +1 -0
  125. package/dist/core/mcp/content.test.d.ts +2 -0
  126. package/dist/core/mcp/content.test.d.ts.map +1 -0
  127. package/dist/core/mcp/content.test.js +135 -0
  128. package/dist/core/mcp/content.test.js.map +1 -0
  129. package/dist/core/mcp/deferred-catalog.d.ts +1 -1
  130. package/dist/core/mcp/deferred-catalog.js +1 -1
  131. package/dist/core/mcp/elicitation.test.js +1 -1
  132. package/dist/core/mcp/legacy-negotiation.test.js +2 -2
  133. package/dist/core/mcp/oauth-store.test.js +2 -2
  134. package/dist/core/mcp/resolve-stdio.test.js +5 -5
  135. package/dist/core/mcp/shared-pool.test.js +5 -5
  136. package/dist/core/mcp/store.test.js +5 -5
  137. package/dist/core/mcp/when-connected.test.js +2 -2
  138. package/dist/core/nolan-model.test.js +1 -1
  139. package/dist/core/nolan-prompt.js +5 -5
  140. package/dist/core/oauth/xai.d.ts +2 -0
  141. package/dist/core/oauth/xai.d.ts.map +1 -0
  142. package/dist/core/oauth/xai.js +4 -0
  143. package/dist/core/oauth/xai.js.map +1 -0
  144. package/dist/core/persistent-shell.js +1 -1
  145. package/dist/core/persistent-shell.test.js +6 -6
  146. package/dist/core/process-manager-dev-server-repro.test.js +51 -12
  147. package/dist/core/process-manager-dev-server-repro.test.js.map +1 -1
  148. package/dist/core/process-manager-notifications.test.js +24 -14
  149. package/dist/core/process-manager-notifications.test.js.map +1 -1
  150. package/dist/core/process-manager.d.ts +22 -0
  151. package/dist/core/process-manager.d.ts.map +1 -1
  152. package/dist/core/process-manager.js +58 -2
  153. package/dist/core/process-manager.js.map +1 -1
  154. package/dist/core/progress/git-xp.test.js +2 -2
  155. package/dist/core/progress/ranks.d.ts +14 -3
  156. package/dist/core/progress/ranks.d.ts.map +1 -1
  157. package/dist/core/progress/ranks.js +181 -12
  158. package/dist/core/progress/ranks.js.map +1 -1
  159. package/dist/core/progress/ranks.test.js +48 -7
  160. package/dist/core/progress/ranks.test.js.map +1 -1
  161. package/dist/core/progress/rebuild.test.js +1 -1
  162. package/dist/core/progress/store.test.js +1 -1
  163. package/dist/core/progress/types.d.ts +2 -1
  164. package/dist/core/progress/types.d.ts.map +1 -1
  165. package/dist/core/project-discovery.d.ts.map +1 -1
  166. package/dist/core/project-discovery.js +62 -48
  167. package/dist/core/project-discovery.js.map +1 -1
  168. package/dist/core/project-discovery.test.js +10 -10
  169. package/dist/core/prompt-commands.js +3 -3
  170. package/dist/core/radio.d.ts +1 -1
  171. package/dist/core/radio.d.ts.map +1 -1
  172. package/dist/core/radio.js +90 -6
  173. package/dist/core/radio.js.map +1 -1
  174. package/dist/core/radio.test.js +15 -2
  175. package/dist/core/radio.test.js.map +1 -1
  176. package/dist/core/run-journal.test.js +2 -2
  177. package/dist/core/sandbox.test.js +6 -6
  178. package/dist/core/semantic-search-benchmark.d.ts +2 -2
  179. package/dist/core/semantic-search-benchmark.js +5 -5
  180. package/dist/core/session-compaction.test.js +1 -1
  181. package/dist/core/session-manager.d.ts.map +1 -1
  182. package/dist/core/session-manager.js +83 -67
  183. package/dist/core/session-manager.js.map +1 -1
  184. package/dist/core/session-manager.test.js +7 -7
  185. package/dist/core/session-storage-fd-leak.test.d.ts +2 -0
  186. package/dist/core/session-storage-fd-leak.test.d.ts.map +1 -0
  187. package/dist/core/session-storage-fd-leak.test.js +116 -0
  188. package/dist/core/session-storage-fd-leak.test.js.map +1 -0
  189. package/dist/core/session-storage.d.ts +22 -2
  190. package/dist/core/session-storage.d.ts.map +1 -1
  191. package/dist/core/session-storage.js +33 -6
  192. package/dist/core/session-storage.js.map +1 -1
  193. package/dist/core/session-storage.test.js +2 -2
  194. package/dist/core/settings-manager.d.ts +2 -0
  195. package/dist/core/settings-manager.d.ts.map +1 -1
  196. package/dist/core/settings-manager.js +10 -1
  197. package/dist/core/settings-manager.js.map +1 -1
  198. package/dist/core/shell-path.js +1 -1
  199. package/dist/core/shell.d.ts +1 -1
  200. package/dist/core/shell.js +2 -2
  201. package/dist/core/shell.test.js +2 -2
  202. package/dist/core/shutdown.d.ts +71 -0
  203. package/dist/core/shutdown.d.ts.map +1 -0
  204. package/dist/core/shutdown.js +144 -0
  205. package/dist/core/shutdown.js.map +1 -0
  206. package/dist/core/shutdown.test.d.ts +2 -0
  207. package/dist/core/shutdown.test.d.ts.map +1 -0
  208. package/dist/core/shutdown.test.js +160 -0
  209. package/dist/core/shutdown.test.js.map +1 -0
  210. package/dist/core/sidecar-error-reporter.js +1 -1
  211. package/dist/core/sidecar-error-reporter.test.js +2 -2
  212. package/dist/core/skills-routing.test.js +96 -0
  213. package/dist/core/skills-routing.test.js.map +1 -1
  214. package/dist/core/skills.d.ts.map +1 -1
  215. package/dist/core/skills.js +3 -0
  216. package/dist/core/skills.js.map +1 -1
  217. package/dist/core/subagent-manager.d.ts +9 -0
  218. package/dist/core/subagent-manager.d.ts.map +1 -1
  219. package/dist/core/subagent-manager.js +45 -12
  220. package/dist/core/subagent-manager.js.map +1 -1
  221. package/dist/core/subagent-manager.test.js +14 -8
  222. package/dist/core/subagent-manager.test.js.map +1 -1
  223. package/dist/core/subagent-store.test.js +3 -3
  224. package/dist/core/task-store.js +1 -1
  225. package/dist/index.js +1 -1
  226. package/dist/index.js.map +1 -1
  227. package/dist/modes/acp-mode.js +2 -2
  228. package/dist/modes/acp-mode.test.js +4 -4
  229. package/dist/modes/agent-home-mode.d.ts.map +1 -1
  230. package/dist/modes/agent-home-mode.js +15 -11
  231. package/dist/modes/agent-home-mode.js.map +1 -1
  232. package/dist/modes/json-mode.d.ts +9 -1
  233. package/dist/modes/json-mode.d.ts.map +1 -1
  234. package/dist/modes/json-mode.js +3 -1
  235. package/dist/modes/json-mode.js.map +1 -1
  236. package/dist/modes/serve-mode.d.ts +1 -1
  237. package/dist/modes/serve-mode.d.ts.map +1 -1
  238. package/dist/modes/serve-mode.js +14 -9
  239. package/dist/modes/serve-mode.js.map +1 -1
  240. package/dist/modes/subagent-worker-mode.d.ts +5 -0
  241. package/dist/modes/subagent-worker-mode.d.ts.map +1 -1
  242. package/dist/modes/subagent-worker-mode.js.map +1 -1
  243. package/dist/session.test.js +1 -1
  244. package/dist/system-prompt.d.ts +37 -1
  245. package/dist/system-prompt.d.ts.map +1 -1
  246. package/dist/system-prompt.js +123 -11
  247. package/dist/system-prompt.js.map +1 -1
  248. package/dist/system-prompt.test.js +90 -11
  249. package/dist/system-prompt.test.js.map +1 -1
  250. package/dist/system-prompt.tiering.test.d.ts +2 -0
  251. package/dist/system-prompt.tiering.test.d.ts.map +1 -0
  252. package/dist/system-prompt.tiering.test.js +105 -0
  253. package/dist/system-prompt.tiering.test.js.map +1 -0
  254. package/dist/tools/code-nav.d.ts +30 -0
  255. package/dist/tools/code-nav.d.ts.map +1 -0
  256. package/dist/tools/code-nav.js +320 -0
  257. package/dist/tools/code-nav.js.map +1 -0
  258. package/dist/tools/code-nav.test.d.ts +2 -0
  259. package/dist/tools/code-nav.test.d.ts.map +1 -0
  260. package/dist/tools/code-nav.test.js +136 -0
  261. package/dist/tools/code-nav.test.js.map +1 -0
  262. package/dist/tools/edit.test.js +1 -1
  263. package/dist/tools/generate-image.d.ts +1 -1
  264. package/dist/tools/goals.d.ts +2 -2
  265. package/dist/tools/goals.test.js +2 -2
  266. package/dist/tools/grep-parity.test.d.ts +2 -0
  267. package/dist/tools/grep-parity.test.d.ts.map +1 -0
  268. package/dist/tools/grep-parity.test.js +92 -0
  269. package/dist/tools/grep-parity.test.js.map +1 -0
  270. package/dist/tools/grep-recall.test.d.ts +2 -0
  271. package/dist/tools/grep-recall.test.d.ts.map +1 -0
  272. package/dist/tools/grep-recall.test.js +114 -0
  273. package/dist/tools/grep-recall.test.js.map +1 -0
  274. package/dist/tools/grep-spawn.test.d.ts +2 -0
  275. package/dist/tools/grep-spawn.test.d.ts.map +1 -0
  276. package/dist/tools/grep-spawn.test.js +66 -0
  277. package/dist/tools/grep-spawn.test.js.map +1 -0
  278. package/dist/tools/grep.d.ts +13 -3
  279. package/dist/tools/grep.d.ts.map +1 -1
  280. package/dist/tools/grep.js +340 -40
  281. package/dist/tools/grep.js.map +1 -1
  282. package/dist/tools/grep.test.js +17 -14
  283. package/dist/tools/grep.test.js.map +1 -1
  284. package/dist/tools/index.d.ts +7 -0
  285. package/dist/tools/index.d.ts.map +1 -1
  286. package/dist/tools/index.js +8 -1
  287. package/dist/tools/index.js.map +1 -1
  288. package/dist/tools/plan-mode.test.js +1 -1
  289. package/dist/tools/prompt-hints.d.ts +9 -0
  290. package/dist/tools/prompt-hints.d.ts.map +1 -1
  291. package/dist/tools/prompt-hints.js +61 -8
  292. package/dist/tools/prompt-hints.js.map +1 -1
  293. package/dist/tools/safe-env.js +1 -1
  294. package/dist/tools/search-code.d.ts.map +1 -1
  295. package/dist/tools/search-code.js +7 -6
  296. package/dist/tools/search-code.js.map +1 -1
  297. package/dist/tools/search-code.test.js +8 -2
  298. package/dist/tools/search-code.test.js.map +1 -1
  299. package/dist/tools/skill.js +2 -1
  300. package/dist/tools/skill.js.map +1 -1
  301. package/dist/tools/subagent-control.d.ts.map +1 -1
  302. package/dist/tools/subagent-control.js +20 -5
  303. package/dist/tools/subagent-control.js.map +1 -1
  304. package/dist/tools/subagent-control.test.js +34 -1
  305. package/dist/tools/subagent-control.test.js.map +1 -1
  306. package/dist/tools/subagent-shared.d.ts +20 -1
  307. package/dist/tools/subagent-shared.d.ts.map +1 -1
  308. package/dist/tools/subagent-shared.js +34 -7
  309. package/dist/tools/subagent-shared.js.map +1 -1
  310. package/dist/tools/subagent-shared.test.js +43 -9
  311. package/dist/tools/subagent-shared.test.js.map +1 -1
  312. package/dist/tools/subagent.d.ts.map +1 -1
  313. package/dist/tools/subagent.js +11 -8
  314. package/dist/tools/subagent.js.map +1 -1
  315. package/dist/tools/subagent.test.js +3 -0
  316. package/dist/tools/subagent.test.js.map +1 -1
  317. package/dist/tools/task-send.test.js +19 -10
  318. package/dist/tools/task-send.test.js.map +1 -1
  319. package/dist/tools/tool-search.d.ts.map +1 -1
  320. package/dist/tools/tool-search.js +2 -1
  321. package/dist/tools/tool-search.js.map +1 -1
  322. package/dist/tools/tool-tiers.d.ts +42 -0
  323. package/dist/tools/tool-tiers.d.ts.map +1 -0
  324. package/dist/tools/tool-tiers.js +78 -0
  325. package/dist/tools/tool-tiers.js.map +1 -0
  326. package/dist/tools/tool-tiers.test.d.ts +2 -0
  327. package/dist/tools/tool-tiers.test.d.ts.map +1 -0
  328. package/dist/tools/tool-tiers.test.js +48 -0
  329. package/dist/tools/tool-tiers.test.js.map +1 -0
  330. package/dist/tools/write.test.js +1 -1
  331. package/dist/ui/App.js.map +1 -1
  332. package/dist/ui/components/Banner.d.ts.map +1 -1
  333. package/dist/ui/components/Banner.js +24 -16
  334. package/dist/ui/components/Banner.js.map +1 -1
  335. package/dist/ui/components/ToolExecution.js +42 -34
  336. package/dist/ui/components/ToolExecution.js.map +1 -1
  337. package/dist/ui/components/force-color.d.ts +2 -0
  338. package/dist/ui/components/force-color.d.ts.map +1 -0
  339. package/dist/ui/components/force-color.js +11 -0
  340. package/dist/ui/components/force-color.js.map +1 -0
  341. package/dist/ui/components/themed-output.test.d.ts +2 -0
  342. package/dist/ui/components/themed-output.test.d.ts.map +1 -0
  343. package/dist/ui/components/themed-output.test.js +111 -0
  344. package/dist/ui/components/themed-output.test.js.map +1 -0
  345. package/dist/ui/error-item.d.ts +1 -1
  346. package/dist/ui/error-item.js +3 -3
  347. package/dist/ui/error-item.js.map +1 -1
  348. package/dist/ui/hooks/useAgentLoop.d.ts +3 -0
  349. package/dist/ui/hooks/useAgentLoop.d.ts.map +1 -1
  350. package/dist/ui/hooks/useAgentLoop.js +27 -2
  351. package/dist/ui/hooks/useAgentLoop.js.map +1 -1
  352. package/dist/ui/login.js +1 -1
  353. package/dist/ui/login.js.map +1 -1
  354. package/dist/ui/render.d.ts +1 -1
  355. package/dist/ui/render.js +6 -6
  356. package/dist/ui/theme/dark-ansi.json +6 -0
  357. package/dist/ui/theme/dark-daltonized.json +6 -0
  358. package/dist/ui/theme/dark.json +6 -0
  359. package/dist/ui/theme/light-ansi.json +6 -0
  360. package/dist/ui/theme/light-daltonized.json +6 -0
  361. package/dist/ui/theme/light.json +6 -0
  362. package/dist/ui/theme/theme.d.ts +6 -0
  363. package/dist/ui/theme/theme.d.ts.map +1 -1
  364. package/dist/ui/tui-terminal-recorder.test.js +1 -1
  365. package/dist/utils/git.test.js +3 -3
  366. package/package.json +4 -4
@@ -1,5 +1,17 @@
1
- // The 50-rank ladder: 10 tiers × 5 levels, with CSS effect ids and tier glyphs.
2
- export const MAX_LEVEL = 50;
1
+ // The 1000-level rank ladder: 145 named ranks across 29 tiers, with CSS effect ids
2
+ // and tier glyphs.
3
+ //
4
+ // Two paces, so nobody is ever re-ranked by an update:
5
+ // • Levels 1–50 (the original ladder) — 10 tiers × 5 ranks, one rank per level.
6
+ // • Levels 51–1000 (the long game) — 19 tiers × 5 ranks, one rank per 10 levels.
7
+ // Names, tiers and XP costs below level 51 are byte-identical to the old 50-level
8
+ // ladder, so an existing Deity stays a Deity and simply keeps climbing.
9
+ export const MAX_LEVEL = 1000;
10
+ /** Last level of the original one-rank-per-level ladder. */
11
+ const KNEE_LEVEL = 50;
12
+ /** Levels each rank spans above the knee. */
13
+ const LEVELS_PER_RANK = 10;
14
+ const RANKS_PER_TIER = 5;
3
15
  const TIERS = [
4
16
  {
5
17
  name: "Boot",
@@ -61,28 +73,181 @@ const TIERS = [
61
73
  effectId: "iridescent",
62
74
  ranks: ["Anomaly", "Entity", "Overmind", "Deity", "Singularity"],
63
75
  },
76
+ // ── Past the Singularity: levels 51–1000, one rank per 10 levels. ──
77
+ {
78
+ name: "Supernova",
79
+ glyph: "✶",
80
+ effectId: "ember",
81
+ ranks: ["Starforge", "Cataclysm", "Hypergiant", "Hypernova", "Supernova"],
82
+ },
83
+ {
84
+ name: "Quasar",
85
+ glyph: "✷",
86
+ effectId: "ember",
87
+ ranks: ["Blazecore", "Jetstream", "Starflare", "Radiance", "Quasar"],
88
+ },
89
+ {
90
+ name: "Nebula",
91
+ glyph: "❂",
92
+ effectId: "nebula",
93
+ ranks: ["Stardust", "Starbirth", "Veilspinner", "Auroral", "Nebulon"],
94
+ },
95
+ {
96
+ name: "Horizon",
97
+ glyph: "✺",
98
+ effectId: "nebula",
99
+ ranks: ["Accretion", "Gravwell", "Lightcage", "Eventline", "Horizon"],
100
+ },
101
+ {
102
+ name: "Vortex",
103
+ glyph: "✸",
104
+ effectId: "rift",
105
+ ranks: ["Maelstrom", "Spiralbound", "Whirlcore", "Cyclonic", "Vortex"],
106
+ },
107
+ {
108
+ name: "Rift",
109
+ glyph: "⬡",
110
+ effectId: "rift",
111
+ ranks: ["Fracture", "Seamripper", "Riftwalker", "Breachlord", "Worldrift"],
112
+ },
113
+ {
114
+ name: "Void",
115
+ glyph: "⬣",
116
+ effectId: "void",
117
+ ranks: ["Hollow", "Nullpointer", "Voidwalker", "Abyssal", "Voidcrown"],
118
+ },
119
+ {
120
+ name: "Aether",
121
+ glyph: "⧫",
122
+ effectId: "aether",
123
+ ranks: ["Etherborn", "Luminant", "Skyforge", "Aetherlord", "Empyrean"],
124
+ },
125
+ {
126
+ name: "Eidolon",
127
+ glyph: "⬟",
128
+ effectId: "aether",
129
+ ranks: ["Revenant", "Wraithcode", "Phantasm", "Soulforge", "Eidolon"],
130
+ },
131
+ {
132
+ name: "Paradox",
133
+ glyph: "✳",
134
+ effectId: "prism",
135
+ ranks: ["Recursor", "Loopbreaker", "Strangeloop", "Antilogic", "Paradox"],
136
+ },
137
+ {
138
+ name: "Infinite",
139
+ glyph: "∞",
140
+ effectId: "prism",
141
+ ranks: ["Unbounded", "Limitless", "Aleph", "Transfinite", "Infinitum"],
142
+ },
143
+ {
144
+ name: "Eternal",
145
+ glyph: "✴",
146
+ effectId: "eternal",
147
+ ranks: ["Ageless", "Timeless", "Eonkeeper", "Perpetual", "Eternal"],
148
+ },
149
+ {
150
+ name: "Genesis",
151
+ glyph: "✱",
152
+ effectId: "eternal",
153
+ ranks: ["Firstlight", "Sparkbearer", "Worldsmith", "Lifegiver", "Genesis"],
154
+ },
155
+ {
156
+ name: "Zenith",
157
+ glyph: "▲",
158
+ effectId: "platinum",
159
+ ranks: ["Summit", "Crestline", "Apex", "Pinnacle", "Zenith"],
160
+ },
161
+ {
162
+ name: "Absolute",
163
+ glyph: "◉",
164
+ effectId: "platinum",
165
+ ranks: ["Invariant", "Immutable", "Axiom", "Sovereign", "Absolute"],
166
+ },
167
+ {
168
+ name: "Immortal",
169
+ glyph: "❈",
170
+ effectId: "radiant",
171
+ ranks: ["Undying", "Deathless", "Phoenix", "Everflame", "Immortal"],
172
+ },
173
+ {
174
+ name: "Transcendent",
175
+ glyph: "❋",
176
+ effectId: "radiant",
177
+ ranks: ["Ethereal", "Sublime", "Numinous", "Apotheosis", "Transcendent"],
178
+ },
179
+ {
180
+ name: "Omega",
181
+ glyph: "Ω",
182
+ effectId: "omega",
183
+ ranks: ["Terminus", "Lastlight", "Endbringer", "Omegacore", "Omega"],
184
+ },
185
+ {
186
+ name: "Origin",
187
+ glyph: "✵",
188
+ effectId: "origin",
189
+ ranks: ["Firstcause", "Primemover", "Demiurge", "Worldseed", "Origin"],
190
+ },
64
191
  ];
65
- /** Cumulative XP required to reach level n (level 1 = 0). */
192
+ /** Cumulative XP to reach the knee — the last level of the original curve. */
193
+ const KNEE_XP = Math.round(100 * Math.pow(KNEE_LEVEL, 1.6));
194
+ /** Cost of the knee level itself (level 49 → 50), the step the long game inherits. */
195
+ const KNEE_STEP = KNEE_XP - Math.round(100 * Math.pow(KNEE_LEVEL - 1, 1.6));
196
+ /** Each level past the knee costs this much more than the one before it. */
197
+ const STEP_GROWTH = 2;
198
+ /**
199
+ * Cumulative XP required to reach level n (level 1 = 0).
200
+ *
201
+ * Levels 2–50 keep the original 100 × N^1.6 curve untouched. Past the knee the
202
+ * exponential would balloon to millions per level, so the cost switches to a linear
203
+ * ramp that starts exactly at the knee step (~1.7k) and grows to ~3.6k at level 1000
204
+ * — roughly 2.53M XP for the full climb, steady instead of a wall.
205
+ */
66
206
  export function xpForLevel(n) {
67
207
  if (n <= 1)
68
208
  return 0;
69
- return Math.round(100 * Math.pow(n, 1.6));
209
+ if (n <= KNEE_LEVEL)
210
+ return Math.round(100 * Math.pow(n, 1.6));
211
+ const past = n - KNEE_LEVEL;
212
+ return KNEE_XP + KNEE_STEP * past + (STEP_GROWTH * past * (past - 1)) / 2;
70
213
  }
71
214
  /** Level for a cumulative XP total (1..MAX_LEVEL). */
72
215
  export function levelForXp(xp) {
73
- let level = 1;
74
- while (level < MAX_LEVEL && xp >= xpForLevel(level + 1))
75
- level++;
76
- return level;
216
+ // Binary search — the ladder is 1000 rungs deep and this runs on every award.
217
+ let low = 1;
218
+ let high = MAX_LEVEL;
219
+ while (low < high) {
220
+ const mid = Math.ceil((low + high) / 2);
221
+ if (xp >= xpForLevel(mid))
222
+ low = mid;
223
+ else
224
+ high = mid - 1;
225
+ }
226
+ return low;
227
+ }
228
+ /** Tier + rank slot for a level: one rank per level to the knee, then one per 10. */
229
+ function slotForLevel(level) {
230
+ if (level <= KNEE_LEVEL) {
231
+ return {
232
+ tierIndex: Math.floor((level - 1) / RANKS_PER_TIER),
233
+ rankIndex: (level - 1) % RANKS_PER_TIER,
234
+ };
235
+ }
236
+ const past = level - KNEE_LEVEL - 1;
237
+ const rankSlot = Math.floor(past / LEVELS_PER_RANK);
238
+ return {
239
+ tierIndex: KNEE_LEVEL / RANKS_PER_TIER + Math.floor(rankSlot / RANKS_PER_TIER),
240
+ rankIndex: rankSlot % RANKS_PER_TIER,
241
+ };
77
242
  }
78
243
  /** Rank metadata for a level (clamped to 1..MAX_LEVEL). */
79
244
  export function rankForLevel(level) {
80
245
  const l = Math.min(Math.max(1, Math.floor(level)), MAX_LEVEL);
81
- const tierIndex = Math.floor((l - 1) / 5);
246
+ const { tierIndex, rankIndex } = slotForLevel(l);
82
247
  const tier = TIERS[tierIndex];
83
248
  return {
84
249
  level: l,
85
- name: tier.ranks[(l - 1) % 5],
250
+ name: tier.ranks[rankIndex],
86
251
  tier: tierIndex + 1,
87
252
  tierName: tier.name,
88
253
  tierGlyph: tier.glyph,
@@ -122,10 +287,14 @@ export function buildSnapshot(file) {
122
287
  eventNonce: file.lastEvent?.nonce ?? null,
123
288
  };
124
289
  }
125
- /** Full 50-entry ladder for the scorecard. */
290
+ /**
291
+ * One entry per named rank (145 of them), not per level — above the knee a rank spans
292
+ * 10 levels, so a per-level ladder would ship 1000 near-duplicate rungs on every frame.
293
+ * `level` is the first level at which the rank is earned.
294
+ */
126
295
  export function rankLadder() {
127
296
  const ladder = [];
128
- for (let level = 1; level <= MAX_LEVEL; level++) {
297
+ for (let level = 1; level <= MAX_LEVEL; level += level <= KNEE_LEVEL ? 1 : LEVELS_PER_RANK) {
129
298
  const rank = rankForLevel(level);
130
299
  ladder.push({
131
300
  level,
@@ -1 +1 @@
1
- {"version":3,"file":"ranks.js","sourceRoot":"","sources":["../../../src/core/progress/ranks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ranks.js","sourceRoot":"","sources":["../../../src/core/progress/ranks.ts"],"names":[],"mappings":"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"}
@@ -1,16 +1,28 @@
1
1
  import { describe, expect, it } from "vitest";
2
2
  import { MAX_LEVEL, levelForXp, rankForLevel, rankLadder, xpForLevel } from "./ranks.js";
3
3
  describe("xpForLevel", () => {
4
- it("matches the 100 × N^1.6 curve", () => {
4
+ it("matches the 100 × N^1.6 curve up to the level-50 knee", () => {
5
5
  expect(xpForLevel(1)).toBe(0);
6
6
  expect(xpForLevel(2)).toBe(303);
7
7
  expect(xpForLevel(10)).toBe(3981);
8
8
  expect(xpForLevel(50)).toBe(52282);
9
9
  });
10
- it("is strictly increasing", () => {
10
+ it("continues past the knee at the knee's own step, then ramps", () => {
11
+ // No cliff and no cheap level at the seam: level 51 costs what level 50 did.
12
+ expect(xpForLevel(51) - xpForLevel(50)).toBe(xpForLevel(50) - xpForLevel(49));
13
+ expect(xpForLevel(1000) - xpForLevel(999)).toBe(3561);
14
+ // The full climb stays in reach: ~2.5M XP rather than the exponential's 6.3M.
15
+ expect(xpForLevel(MAX_LEVEL)).toBe(2533682);
16
+ });
17
+ it("is strictly increasing with a monotonically growing step", () => {
11
18
  for (let n = 2; n <= MAX_LEVEL; n++) {
12
19
  expect(xpForLevel(n)).toBeGreaterThan(xpForLevel(n - 1));
13
20
  }
21
+ for (let n = 52; n <= MAX_LEVEL; n++) {
22
+ const step = xpForLevel(n) - xpForLevel(n - 1);
23
+ const prevStep = xpForLevel(n - 1) - xpForLevel(n - 2);
24
+ expect(step).toBeGreaterThan(prevStep);
25
+ }
14
26
  });
15
27
  });
16
28
  describe("levelForXp", () => {
@@ -22,7 +34,14 @@ describe("levelForXp", () => {
22
34
  expect(levelForXp(303)).toBe(2);
23
35
  expect(levelForXp(3981)).toBe(10);
24
36
  });
37
+ it("crosses boundaries above the knee too", () => {
38
+ for (const level of [50, 51, 52, 137, 500, 999, 1000]) {
39
+ expect(levelForXp(xpForLevel(level))).toBe(level);
40
+ expect(levelForXp(xpForLevel(level) - 1)).toBe(level - 1);
41
+ }
42
+ });
25
43
  it("caps at MAX_LEVEL", () => {
44
+ expect(MAX_LEVEL).toBe(1000);
26
45
  expect(levelForXp(10_000_000)).toBe(MAX_LEVEL);
27
46
  });
28
47
  });
@@ -35,25 +54,47 @@ describe("rankForLevel", () => {
35
54
  expect(rankForLevel(25).name).toBe("Netrunner");
36
55
  expect(rankForLevel(50).name).toBe("Singularity");
37
56
  });
38
- it("assigns tiers 1–10", () => {
57
+ it("holds one rank per 10 levels above the knee", () => {
58
+ expect(rankForLevel(51).name).toBe("Starforge");
59
+ expect(rankForLevel(60).name).toBe("Starforge");
60
+ expect(rankForLevel(61).name).toBe("Cataclysm");
61
+ expect(rankForLevel(100).name).toBe("Supernova");
62
+ expect(rankForLevel(101).name).toBe("Blazecore");
63
+ expect(rankForLevel(1000).name).toBe("Origin");
64
+ });
65
+ it("assigns tiers 1–29", () => {
39
66
  expect(rankForLevel(1).tier).toBe(1);
40
67
  expect(rankForLevel(5).tier).toBe(1);
41
68
  expect(rankForLevel(6).tier).toBe(2);
42
69
  expect(rankForLevel(50).tier).toBe(10);
70
+ expect(rankForLevel(51).tier).toBe(11);
71
+ expect(rankForLevel(100).tier).toBe(11);
72
+ expect(rankForLevel(101).tier).toBe(12);
73
+ expect(rankForLevel(1000).tier).toBe(29);
43
74
  });
44
75
  it("clamps out-of-range levels", () => {
45
76
  expect(rankForLevel(0).level).toBe(1);
46
- expect(rankForLevel(99).level).toBe(50);
77
+ expect(rankForLevel(9999).level).toBe(1000);
47
78
  });
48
79
  });
49
80
  describe("rankLadder", () => {
50
- it("has 50 unique names with increasing xpRequired", () => {
81
+ it("has 145 unique names with increasing xpRequired", () => {
51
82
  const ladder = rankLadder();
52
- expect(ladder).toHaveLength(50);
53
- expect(new Set(ladder.map((r) => r.name)).size).toBe(50);
83
+ expect(ladder).toHaveLength(145);
84
+ expect(new Set(ladder.map((r) => r.name)).size).toBe(145);
54
85
  for (let i = 1; i < ladder.length; i++) {
55
86
  expect(ladder[i].xpRequired).toBeGreaterThan(ladder[i - 1].xpRequired);
56
87
  }
57
88
  });
89
+ it("lists the first level of every rank, covering the whole ladder", () => {
90
+ const ladder = rankLadder();
91
+ expect(ladder[0].level).toBe(1);
92
+ expect(ladder[49].level).toBe(50);
93
+ expect(ladder[50].level).toBe(51);
94
+ expect(ladder[ladder.length - 1].level).toBe(991);
95
+ for (const entry of ladder) {
96
+ expect(rankForLevel(entry.level).name).toBe(entry.name);
97
+ }
98
+ });
58
99
  });
59
100
  //# sourceMappingURL=ranks.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ranks.test.js","sourceRoot":"","sources":["../../../src/core/progress/ranks.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ranks.test.js","sourceRoot":"","sources":["../../../src/core/progress/ranks.test.ts"],"names":[],"mappings":"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"}
@@ -6,7 +6,7 @@ import { levelForXp, xpForLevel } from "./ranks.js";
6
6
  import { rebuildFromSessions } from "./rebuild.js";
7
7
  let sessionsDir;
8
8
  beforeEach(async () => {
9
- sessionsDir = await fs.mkdtemp(path.join(os.tmpdir(), "gg-sessions-"));
9
+ sessionsDir = await fs.mkdtemp(path.join(os.tmpdir(), "ez-sessions-"));
10
10
  });
11
11
  afterEach(async () => {
12
12
  await fs.rm(sessionsDir, { recursive: true, force: true });
@@ -6,7 +6,7 @@ import { createEmptyProgress, loadProgress, saveProgress, signProgress, updatePr
6
6
  let dir;
7
7
  let opts;
8
8
  beforeEach(async () => {
9
- dir = await fs.mkdtemp(path.join(os.tmpdir(), "gg-progress-"));
9
+ dir = await fs.mkdtemp(path.join(os.tmpdir(), "ez-progress-"));
10
10
  opts = {
11
11
  filePath: path.join(dir, "progress.json"),
12
12
  backupPath: path.join(dir, "progress.backup.json"),
@@ -52,8 +52,9 @@ export interface ProgressFile {
52
52
  /** HMAC-SHA256 of canonical JSON minus this field. */
53
53
  sig: string;
54
54
  }
55
- /** One rung of the 50-rank ladder, as sent to the webview. */
55
+ /** One named rank of the 1000-level ladder, as sent to the webview. */
56
56
  export interface RankLadderEntry {
57
+ /** First level at which this rank is earned (ranks span 10 levels above level 50). */
57
58
  level: number;
58
59
  name: string;
59
60
  tier: number;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/progress/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/progress/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"project-discovery.d.ts","sourceRoot":"","sources":["../../src/core/project-discovery.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,aAAa,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE3E,MAAM,WAAW,uBAAuB;IACtC,sEAAsE;IACtE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uDAAuD;IACvD,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,wDAAwD;IACxD,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gEAAgE;IAChE,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,iBAAiB,EAAE,CAAC,CA8C9B;AAiFD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEpD;AA8dD,MAAM,WAAW,aAAa;IAC5B,kBAAkB;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAC;IACb,sEAAsE;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,MAAM,EACX,KAAK,SAAI,EACT,WAAW,SAA4B,GACtC,OAAO,CAAC,aAAa,EAAE,CAAC,CAkB1B;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,MAAM,EACX,KAAK,SAAI,EACT,OAAO,SAAe,GACrB,OAAO,CAAC,aAAa,EAAE,CAAC,CAS1B"}
1
+ {"version":3,"file":"project-discovery.d.ts","sourceRoot":"","sources":["../../src/core/project-discovery.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,aAAa,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE3E,MAAM,WAAW,uBAAuB;IACtC,sEAAsE;IACtE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,uDAAuD;IACvD,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,wDAAwD;IACxD,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gEAAgE;IAChE,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,iBAAiB,EAAE,CAAC,CA8C9B;AAiFD;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEpD;AAoeD,MAAM,WAAW,aAAa;IAC5B,kBAAkB;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAC;IACb,sEAAsE;IACtE,OAAO,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED;;;;;;;;GAQG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,MAAM,EACX,KAAK,SAAI,EACT,WAAW,SAA4B,GACtC,OAAO,CAAC,aAAa,EAAE,CAAC,CAkB1B;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,MAAM,EACX,KAAK,SAAI,EACT,OAAO,SAAe,GACrB,OAAO,CAAC,aAAa,EAAE,CAAC,CAS1B"}
@@ -88,10 +88,10 @@ async function discoverEzcoderProjects() {
88
88
  // had dozens of session stores.
89
89
  const results = await mapConcurrent(entries, async (entry) => {
90
90
  const dir = path.join(sessionsDir, entry);
91
- const mtime = await maxGgcoderSessionMtime(dir);
91
+ const mtime = await maxEzcoderSessionMtime(dir);
92
92
  if (mtime === null)
93
93
  return null;
94
- const rawCwd = (await readFirstFromGgcoderDir(dir, ezcoderCwdExtractor)) ?? fallbackUnderscoreDecode(entry);
94
+ const rawCwd = (await readFirstFromEzcoderDir(dir, ezcoderCwdExtractor)) ?? fallbackUnderscoreDecode(entry);
95
95
  if (!rawCwd)
96
96
  return null;
97
97
  // Normalize traversal segments (e.g. an agent launched with cwd
@@ -377,10 +377,10 @@ async function maxJsonlMtime(dir) {
377
377
  max = f.mtime;
378
378
  return max > 0 ? max : null;
379
379
  }
380
- async function maxGgcoderSessionMtime(dir) {
380
+ async function maxEzcoderSessionMtime(dir) {
381
381
  if (!(await isDirectory(dir)))
382
382
  return null;
383
- const files = await collectGgcoderSessionFiles(dir, 2);
383
+ const files = await collectEzcoderSessionFiles(dir, 2);
384
384
  if (files.length === 0)
385
385
  return null;
386
386
  return Math.max(...files.map((file) => file.mtime));
@@ -419,7 +419,7 @@ async function collectJsonlFiles(dir, maxDepth) {
419
419
  }
420
420
  }
421
421
  }
422
- async function collectGgcoderSessionFiles(dir, maxDepth) {
422
+ async function collectEzcoderSessionFiles(dir, maxDepth) {
423
423
  const byResolvedPath = new Map();
424
424
  await walk(dir, 0);
425
425
  return [...byResolvedPath.values()];
@@ -513,20 +513,27 @@ async function readFirstFromJsonlDir(dir, extractor) {
513
513
  }
514
514
  return null;
515
515
  }
516
- async function readFirstFromGgcoderDir(dir, extractor) {
517
- const files = await collectGgcoderSessionFiles(dir, 2);
516
+ async function readFirstFromEzcoderDir(dir, extractor) {
517
+ const files = await collectEzcoderSessionFiles(dir, 2);
518
518
  files.sort((a, b) => b.mtime - a.mtime);
519
519
  for (const file of files) {
520
520
  try {
521
- const { stream } = await openSessionReadStream(file.path);
521
+ const { stream, close } = await openSessionReadStream(file.path);
522
522
  const rl = readline.createInterface({ input: stream, crlfDelay: Infinity });
523
- let lines = 0;
524
- for await (const line of rl) {
525
- if (++lines > 200)
526
- break;
527
- const value = extractor(line);
528
- if (value)
529
- return value;
523
+ try {
524
+ let lines = 0;
525
+ for await (const line of rl) {
526
+ if (++lines > 200)
527
+ break;
528
+ const value = extractor(line);
529
+ if (value)
530
+ return value;
531
+ }
532
+ }
533
+ finally {
534
+ // Always via close(): destroying the gunzip alone strands the source fd.
535
+ rl.close();
536
+ close();
530
537
  }
531
538
  }
532
539
  catch {
@@ -621,7 +628,7 @@ function formatRelativeTime(ms) {
621
628
  */
622
629
  export async function listRecentSessions(cwd, limit = 5, sessionsDir = getAppPaths().sessionsDir) {
623
630
  const dir = path.join(sessionsDir, encodeCwd(cwd));
624
- const files = await collectGgcoderSessionFiles(dir, 1);
631
+ const files = await collectEzcoderSessionFiles(dir, 1);
625
632
  if (files.length === 0)
626
633
  return [];
627
634
  files.sort((a, b) => b.mtime - a.mtime);
@@ -743,7 +750,7 @@ async function readForeignSessionSummary(file, source) {
743
750
  /** Single-pass parse of one session file: identity + count + activity + preview. */
744
751
  async function readSessionSummary(file) {
745
752
  try {
746
- const { path: resolvedPath, stream } = await openSessionReadStream(file);
753
+ const { path: resolvedPath, stream, close } = await openSessionReadStream(file);
747
754
  const rl = readline.createInterface({ input: stream, crlfDelay: Infinity });
748
755
  let id = "";
749
756
  let conversationId = "";
@@ -753,41 +760,48 @@ async function readSessionSummary(file) {
753
760
  let preview = "";
754
761
  let label = "";
755
762
  let valid = false;
756
- for await (const line of rl) {
757
- if (!line)
758
- continue;
759
- try {
760
- const entry = JSON.parse(line);
761
- if (!valid) {
762
- if (entry.type !== "session")
763
- return null;
764
- valid = true;
765
- id = entry.id ?? "";
766
- conversationId = entry.conversationId ?? id;
767
- if (typeof entry.preview === "string") {
768
- headerPreview = entry.preview.replace(/\s+/g, " ").trim().slice(0, 80);
769
- }
770
- if (entry.timestamp)
771
- lastActivity = entry.timestamp;
763
+ try {
764
+ for await (const line of rl) {
765
+ if (!line)
772
766
  continue;
773
- }
774
- if (entry.type === "label" && typeof entry.label === "string" && entry.label.trim()) {
775
- label = entry.label.replace(/\s+/g, " ").trim().slice(0, 80);
776
- }
777
- else if (entry.type === "message") {
778
- messageCount += 1;
779
- if (entry.timestamp)
780
- lastActivity = entry.timestamp;
781
- if (!preview && entry.message?.role === "user") {
782
- const text = getUserSessionPrompt(entry.message.content);
783
- if (text)
784
- preview = text.replace(/\s+/g, " ").trim().slice(0, 80);
767
+ try {
768
+ const entry = JSON.parse(line);
769
+ if (!valid) {
770
+ if (entry.type !== "session")
771
+ return null;
772
+ valid = true;
773
+ id = entry.id ?? "";
774
+ conversationId = entry.conversationId ?? id;
775
+ if (typeof entry.preview === "string") {
776
+ headerPreview = entry.preview.replace(/\s+/g, " ").trim().slice(0, 80);
777
+ }
778
+ if (entry.timestamp)
779
+ lastActivity = entry.timestamp;
780
+ continue;
781
+ }
782
+ if (entry.type === "label" && typeof entry.label === "string" && entry.label.trim()) {
783
+ label = entry.label.replace(/\s+/g, " ").trim().slice(0, 80);
784
+ }
785
+ else if (entry.type === "message") {
786
+ messageCount += 1;
787
+ if (entry.timestamp)
788
+ lastActivity = entry.timestamp;
789
+ if (!preview && entry.message?.role === "user") {
790
+ const text = getUserSessionPrompt(entry.message.content);
791
+ if (text)
792
+ preview = text.replace(/\s+/g, " ").trim().slice(0, 80);
793
+ }
785
794
  }
786
795
  }
796
+ catch {
797
+ // Skip malformed lines; archive migration preserves them byte-for-byte.
798
+ }
787
799
  }
788
- catch {
789
- // Skip malformed lines; archive migration preserves them byte-for-byte.
790
- }
800
+ }
801
+ finally {
802
+ // `return null` above exits mid-stream; close() destroys gunzip + source.
803
+ rl.close();
804
+ close();
791
805
  }
792
806
  return valid
793
807
  ? {