@pi-unipi/unipi 3.0.0-alpha.2 → 3.0.0-alpha.21

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 (359) hide show
  1. package/CHANGELOG.md +292 -0
  2. package/README.md +8 -11
  3. package/docs/prefix-cache-architecture.md +14 -0
  4. package/package.json +22 -24
  5. package/packages/ask-user/README.md +55 -107
  6. package/packages/ask-user/ask-ui.ts +306 -732
  7. package/packages/ask-user/clipboard.ts +50 -0
  8. package/packages/ask-user/config.ts +74 -78
  9. package/packages/ask-user/package.json +2 -2
  10. package/packages/ask-user/questions.ts +151 -0
  11. package/packages/ask-user/skills/ask-user/SKILL.md +59 -133
  12. package/packages/ask-user/tools.ts +198 -432
  13. package/packages/autocomplete/package.json +1 -1
  14. package/packages/autocomplete/src/constants.ts +38 -43
  15. package/packages/autocomplete/src/sorting.ts +8 -0
  16. package/packages/background-tasks/package.json +2 -2
  17. package/packages/background-tasks/src/config.ts +0 -73
  18. package/packages/background-tasks/src/index.ts +20 -16
  19. package/packages/background-tasks/src/registry.ts +1 -171
  20. package/packages/background-tasks/src/types.ts +0 -32
  21. package/packages/btw/README.md +13 -56
  22. package/packages/btw/extensions/btw.ts +403 -1796
  23. package/packages/btw/package.json +5 -2
  24. package/packages/btw/skills/btw/SKILL.md +7 -143
  25. package/packages/compactor/README.md +56 -287
  26. package/packages/compactor/package.json +5 -9
  27. package/packages/compactor/skills/compactor/SKILL.md +13 -20
  28. package/packages/compactor/src/card.ts +90 -0
  29. package/packages/compactor/src/commands/index.ts +73 -130
  30. package/packages/compactor/src/compaction/compact-args.ts +5 -3
  31. package/packages/compactor/src/compaction/filter-noise.ts +1 -1
  32. package/packages/compactor/src/compaction/hooks.ts +487 -311
  33. package/packages/compactor/src/compaction/source.ts +178 -0
  34. package/packages/compactor/src/compaction/summarize.ts +586 -52
  35. package/packages/compactor/src/config/manager.ts +130 -127
  36. package/packages/compactor/src/config/schema.ts +32 -48
  37. package/packages/compactor/src/index.ts +40 -431
  38. package/packages/compactor/src/info-screen.ts +44 -190
  39. package/packages/compactor/src/session/recall-blocks.ts +1 -1
  40. package/packages/compactor/src/stats.ts +76 -0
  41. package/packages/compactor/src/tools/context-budget.ts +17 -34
  42. package/packages/compactor/src/tools/ctx-doctor.ts +45 -36
  43. package/packages/compactor/src/tools/register.ts +29 -269
  44. package/packages/compactor/src/types.ts +47 -186
  45. package/packages/core/README.md +25 -0
  46. package/packages/core/child-agent.ts +1 -0
  47. package/packages/core/command-echo.ts +63 -0
  48. package/packages/core/compaction-context.ts +41 -0
  49. package/packages/core/constants.ts +8 -38
  50. package/packages/core/events.ts +0 -53
  51. package/packages/core/fusion-status.ts +4 -0
  52. package/packages/core/global.d.ts +10 -0
  53. package/packages/core/harness-messages.ts +392 -0
  54. package/packages/core/index.ts +14 -0
  55. package/packages/core/kanboard-status.ts +49 -0
  56. package/packages/core/long-horizon-owner-status.ts +46 -0
  57. package/packages/core/model-cache.ts +81 -7
  58. package/packages/core/package.json +6 -3
  59. package/packages/core/src/attach/detect.ts +163 -0
  60. package/packages/core/src/child-agent/child-args.ts +31 -0
  61. package/packages/core/src/child-agent/delivery.ts +41 -0
  62. package/packages/core/src/child-agent/index.ts +5 -0
  63. package/packages/core/src/child-agent/readers.ts +203 -0
  64. package/packages/core/src/child-agent/runtime.ts +584 -0
  65. package/packages/core/src/evidence.ts +78 -0
  66. package/packages/core/src/hints/browser.ts +278 -0
  67. package/packages/core/src/hints/crab-data.ts +19 -0
  68. package/packages/core/src/hints/index.ts +865 -0
  69. package/packages/core/src/hints/lines.ts +607 -0
  70. package/packages/core/src/hints/store.ts +120 -0
  71. package/packages/core/src/jev/chatter.ts +24 -0
  72. package/packages/core/src/jev/settings.ts +177 -14
  73. package/packages/core/src/package-colors.ts +2 -0
  74. package/packages/core/src/settings/catalog.ts +39 -15
  75. package/packages/core/src/settings/engine.ts +48 -2
  76. package/packages/core/src/settings/hub.ts +83 -20
  77. package/packages/core/src/settings/open.ts +49 -0
  78. package/packages/core/src/settings/schema.ts +27 -7
  79. package/packages/core/src/tui/hub-kit.ts +18 -5
  80. package/packages/core/src/tui/kit.ts +198 -0
  81. package/packages/core/src/tui/progress.ts +73 -0
  82. package/packages/core/src/turn/arbiter.ts +290 -0
  83. package/packages/footer/README.md +4 -6
  84. package/packages/footer/package.json +3 -3
  85. package/packages/footer/src/glance-editor.ts +19 -11
  86. package/packages/footer/src/help.ts +1 -1
  87. package/packages/footer/src/index.ts +36 -3
  88. package/packages/footer/src/presets.ts +3 -4
  89. package/packages/footer/src/rendering/icons.ts +0 -20
  90. package/packages/footer/src/segments/compactor.ts +52 -142
  91. package/packages/footer/src/segments/status-ext.ts +0 -1
  92. package/packages/fusion/README.md +14 -4
  93. package/packages/fusion/package.json +4 -3
  94. package/packages/fusion/src/child-args.ts +1 -0
  95. package/packages/fusion/src/index.ts +161 -8
  96. package/packages/fusion/src/pi-settings.ts +57 -0
  97. package/packages/fusion/src/picker.ts +186 -51
  98. package/packages/fusion/src/preset.ts +56 -2
  99. package/packages/fusion/src/prompts.ts +1 -1
  100. package/packages/fusion/src/sidekick-runtime.ts +1 -420
  101. package/packages/fusion/src/tools.ts +107 -128
  102. package/packages/fusion/src/transcript.ts +27 -85
  103. package/packages/info-screen/package.json +2 -2
  104. package/packages/input-shortcuts/README.md +18 -30
  105. package/packages/input-shortcuts/package.json +2 -2
  106. package/packages/input-shortcuts/src/burst.ts +88 -0
  107. package/packages/input-shortcuts/src/chord-overlay.ts +20 -70
  108. package/packages/input-shortcuts/src/cleared-input.ts +97 -0
  109. package/packages/input-shortcuts/src/index.ts +99 -193
  110. package/packages/input-shortcuts/src/last-response.ts +40 -0
  111. package/packages/input-shortcuts/src/registers.ts +8 -23
  112. package/packages/input-shortcuts/src/types.ts +4 -16
  113. package/packages/input-shortcuts/src/undo-redo.ts +59 -47
  114. package/packages/kanboard/README.md +51 -47
  115. package/packages/kanboard/index.ts +293 -55
  116. package/packages/kanboard/package.json +8 -8
  117. package/packages/kanboard/skills/kanboard/SKILL.md +61 -27
  118. package/packages/kanboard/src/badges.ts +93 -0
  119. package/packages/kanboard/src/bin.ts +4 -2
  120. package/packages/kanboard/src/commands.ts +218 -84
  121. package/packages/kanboard/src/debug.ts +20 -0
  122. package/packages/kanboard/src/guard.ts +267 -109
  123. package/packages/kanboard/src/monitor.ts +330 -0
  124. package/packages/kanboard/src/notice-buffer.ts +74 -0
  125. package/packages/kanboard/src/progress.ts +27 -0
  126. package/packages/kanboard/src/reminders.ts +234 -0
  127. package/packages/kanboard/src/settings.ts +69 -15
  128. package/packages/kanboard/src/shapes.ts +5 -0
  129. package/packages/long-horizon/index.ts +190 -13
  130. package/packages/long-horizon/package.json +3 -3
  131. package/packages/long-horizon/src/commands.ts +103 -7
  132. package/packages/long-horizon/src/compaction-brief.ts +35 -0
  133. package/packages/long-horizon/src/engine/continuation.ts +84 -15
  134. package/packages/long-horizon/src/engine/goal-state.ts +64 -13
  135. package/packages/long-horizon/src/engine/nudge-stash.ts +71 -0
  136. package/packages/long-horizon/src/engine/ralph.ts +3 -2
  137. package/packages/long-horizon/src/engine/runaway.ts +68 -11
  138. package/packages/long-horizon/src/engine/verifier.ts +19 -0
  139. package/packages/long-horizon/src/gate.ts +37 -12
  140. package/packages/long-horizon/src/judge/resolve.ts +1 -0
  141. package/packages/long-horizon/src/owner.ts +35 -2
  142. package/packages/long-horizon/src/progress.ts +87 -0
  143. package/packages/long-horizon/src/prompts/goal.ts +1 -1
  144. package/packages/long-horizon/src/runtime.ts +172 -18
  145. package/packages/long-horizon/src/settings.ts +54 -39
  146. package/packages/long-horizon/src/tools/goal.ts +6 -0
  147. package/packages/long-horizon/src/tools/graph.ts +1 -1
  148. package/packages/long-horizon/src/tools/swarm.ts +3 -3
  149. package/packages/mcp/package.json +2 -2
  150. package/packages/memory/commands.ts +7 -2
  151. package/packages/memory/index.ts +210 -32
  152. package/packages/memory/package.json +3 -3
  153. package/packages/memory/save-session.ts +264 -0
  154. package/packages/memory/settings.ts +17 -0
  155. package/packages/memory/tools.ts +253 -203
  156. package/packages/notify/package.json +2 -2
  157. package/packages/skill-registry/README.md +53 -16
  158. package/packages/skill-registry/index.ts +230 -0
  159. package/packages/skill-registry/package.json +19 -8
  160. package/packages/skill-registry/src/editor.ts +206 -0
  161. package/packages/skill-registry/src/judge.ts +289 -0
  162. package/packages/skill-registry/src/registry.ts +87 -0
  163. package/packages/skill-registry/src/settings.ts +259 -0
  164. package/packages/skill-registry/src/vault.ts +80 -0
  165. package/packages/subagents/README.md +39 -119
  166. package/packages/subagents/package.json +6 -13
  167. package/packages/subagents/skills/subagents/SKILL.md +18 -42
  168. package/packages/subagents/src/agents.ts +213 -0
  169. package/packages/subagents/src/cards.ts +182 -0
  170. package/packages/subagents/src/index.ts +609 -1084
  171. package/packages/subagents/src/manager.ts +429 -0
  172. package/packages/subagents/src/profiles.ts +130 -0
  173. package/packages/subagents/src/transcript.ts +154 -0
  174. package/packages/subagents/src/ui.ts +389 -0
  175. package/packages/unipi/bundled.js +39756 -45569
  176. package/packages/unipi/index.ts +55 -10
  177. package/packages/updater/package.json +2 -2
  178. package/packages/utility/README.md +76 -69
  179. package/packages/utility/package.json +2 -2
  180. package/packages/utility/skills/image/SKILL.md +37 -0
  181. package/packages/utility/skills/utility/SKILL.md +17 -60
  182. package/packages/utility/src/answer/extract.ts +128 -0
  183. package/packages/utility/src/answer/index.ts +213 -0
  184. package/packages/utility/src/answer/reply.ts +133 -0
  185. package/packages/utility/src/answer/web.ts +167 -0
  186. package/packages/utility/src/attach/index.ts +205 -0
  187. package/packages/utility/src/commands.ts +38 -142
  188. package/packages/utility/src/diagnostics/engine.ts +50 -5
  189. package/packages/utility/src/image/index.ts +33 -0
  190. package/packages/utility/src/image/models.ts +221 -0
  191. package/packages/{image/src → utility/src/image}/recognize.ts +2 -2
  192. package/packages/utility/src/image/settings.ts +178 -0
  193. package/packages/{image/src/image-source.ts → utility/src/image/source.ts} +1 -1
  194. package/packages/utility/src/image/tools.ts +168 -0
  195. package/packages/utility/src/image/transports.ts +186 -0
  196. package/packages/utility/src/index.ts +68 -389
  197. package/packages/utility/src/lifecycle/cleanup.ts +116 -311
  198. package/packages/utility/src/rename/gate.ts +102 -0
  199. package/packages/utility/src/rename/index.ts +191 -0
  200. package/packages/utility/src/rename/session.ts +170 -0
  201. package/packages/utility/src/render/delegated.ts +285 -0
  202. package/packages/utility/src/render/harness.ts +683 -0
  203. package/packages/utility/src/render/parse.ts +156 -0
  204. package/packages/utility/src/render/pi-settings.ts +38 -0
  205. package/packages/utility/src/render/reply-bg.ts +307 -0
  206. package/packages/utility/src/render/simple.ts +724 -0
  207. package/packages/utility/src/render/spacing.ts +235 -0
  208. package/packages/utility/src/render/styled.ts +251 -0
  209. package/packages/utility/src/render/tools.ts +353 -0
  210. package/packages/utility/src/settings.ts +166 -233
  211. package/packages/utility/src/types.ts +1 -222
  212. package/packages/watchdog/index.ts +17 -6
  213. package/packages/watchdog/package.json +3 -3
  214. package/packages/watchdog/src/config.ts +3 -2
  215. package/packages/web-api/package.json +2 -2
  216. package/packages/workflow/README.md +3 -0
  217. package/packages/workflow/index.ts +0 -2
  218. package/packages/workflow/package.json +2 -2
  219. package/packages/workflow/src/permission/decide.ts +6 -4
  220. package/packages/workflow/src/permission/index.ts +17 -7
  221. package/packages/workflow/src/permission/settings.ts +39 -4
  222. package/packages/workflow/src/plan/index.ts +19 -4
  223. package/packages/background-tasks/extensions/delegate-child.ts +0 -1
  224. package/packages/background-tasks/src/context-parent-snapshot.ts +0 -142
  225. package/packages/background-tasks/src/context-token-budget.ts +0 -903
  226. package/packages/background-tasks/src/context-visible-conversation-v2.ts +0 -551
  227. package/packages/background-tasks/src/delegate/artifacts.ts +0 -487
  228. package/packages/background-tasks/src/delegate/budget.ts +0 -415
  229. package/packages/background-tasks/src/delegate/hook-contract-evidence.json +0 -18
  230. package/packages/background-tasks/src/delegate/hook-contract.ts +0 -154
  231. package/packages/background-tasks/src/delegate/launch.ts +0 -484
  232. package/packages/background-tasks/src/delegate/result-package.ts +0 -459
  233. package/packages/background-tasks/src/delegate/runner.ts +0 -430
  234. package/packages/background-tasks/src/delegate/seed.ts +0 -423
  235. package/packages/background-tasks/src/delegate/types.ts +0 -323
  236. package/packages/background-tasks/src/delegate-child-extension.ts +0 -978
  237. package/packages/background-tasks/src/delegate-extension.ts +0 -654
  238. package/packages/background-tasks/src/fixtures/delegate-context-incident.json +0 -17
  239. package/packages/compactor/skills/compactor-detail/SKILL.md +0 -116
  240. package/packages/compactor/skills/compactor-doctor/SKILL.md +0 -71
  241. package/packages/compactor/skills/compactor-stats/SKILL.md +0 -51
  242. package/packages/compactor/src/compaction/build-sections.ts +0 -76
  243. package/packages/compactor/src/compaction/extract/goals.ts +0 -36
  244. package/packages/compactor/src/compaction/extract/preferences.ts +0 -40
  245. package/packages/compactor/src/compaction/format.ts +0 -53
  246. package/packages/compactor/src/compaction/merge.ts +0 -143
  247. package/packages/compactor/src/config/presets.ts +0 -160
  248. package/packages/compactor/src/executor/executor.ts +0 -233
  249. package/packages/compactor/src/executor/runtime.ts +0 -115
  250. package/packages/compactor/src/security/evaluator.ts +0 -89
  251. package/packages/compactor/src/security/policy.ts +0 -96
  252. package/packages/compactor/src/security/scanner.ts +0 -65
  253. package/packages/compactor/src/session/auto-inject.ts +0 -60
  254. package/packages/compactor/src/session/db.ts +0 -325
  255. package/packages/compactor/src/session/extract.ts +0 -144
  256. package/packages/compactor/src/session/resume-inject.ts +0 -64
  257. package/packages/compactor/src/session/snapshot.ts +0 -327
  258. package/packages/compactor/src/tools/ctx-batch-execute.ts +0 -41
  259. package/packages/compactor/src/tools/ctx-execute-file.ts +0 -23
  260. package/packages/compactor/src/tools/ctx-execute.ts +0 -23
  261. package/packages/compactor/src/tools/ctx-stats.ts +0 -96
  262. package/packages/image/README.md +0 -99
  263. package/packages/image/package.json +0 -61
  264. package/packages/image/skills/image/SKILL.md +0 -76
  265. package/packages/image/src/generate.ts +0 -256
  266. package/packages/image/src/index.ts +0 -135
  267. package/packages/image/src/models.ts +0 -519
  268. package/packages/image/src/openai-images-api.ts +0 -282
  269. package/packages/image/src/register-providers.ts +0 -209
  270. package/packages/image/src/settings.ts +0 -173
  271. package/packages/image/src/tools.ts +0 -326
  272. package/packages/input-shortcuts/src/clipboard.ts +0 -119
  273. package/packages/kanboard/src/runner.ts +0 -817
  274. package/packages/skill-registry/skills/auto/SKILL.md +0 -465
  275. package/packages/skill-registry/skills/brainstorm/SKILL.md +0 -219
  276. package/packages/skill-registry/skills/chore-create/SKILL.md +0 -315
  277. package/packages/skill-registry/skills/chore-execute/SKILL.md +0 -314
  278. package/packages/skill-registry/skills/consolidate/SKILL.md +0 -142
  279. package/packages/skill-registry/skills/consultant/SKILL.md +0 -97
  280. package/packages/skill-registry/skills/debug/SKILL.md +0 -228
  281. package/packages/skill-registry/skills/document/SKILL.md +0 -120
  282. package/packages/skill-registry/skills/fix/SKILL.md +0 -212
  283. package/packages/skill-registry/skills/gather-context/SKILL.md +0 -145
  284. package/packages/skill-registry/skills/plan/SKILL.md +0 -231
  285. package/packages/skill-registry/skills/quick-fix/SKILL.md +0 -135
  286. package/packages/skill-registry/skills/quick-work/SKILL.md +0 -110
  287. package/packages/skill-registry/skills/research/SKILL.md +0 -251
  288. package/packages/skill-registry/skills/review-work/SKILL.md +0 -187
  289. package/packages/skill-registry/skills/scan-issues/SKILL.md +0 -195
  290. package/packages/skill-registry/skills/work/SKILL.md +0 -218
  291. package/packages/skill-registry/skills/worktree-create/SKILL.md +0 -69
  292. package/packages/skill-registry/skills/worktree-list/SKILL.md +0 -78
  293. package/packages/skill-registry/skills/worktree-merge/SKILL.md +0 -89
  294. package/packages/subagents/agents/delegate.md +0 -14
  295. package/packages/subagents/agents/oracle.md +0 -78
  296. package/packages/subagents/agents/researcher.md +0 -52
  297. package/packages/subagents/agents/reviewer.md +0 -80
  298. package/packages/subagents/agents/scout.md +0 -50
  299. package/packages/subagents/agents/worker.md +0 -59
  300. package/packages/subagents/prompts/council.md +0 -48
  301. package/packages/subagents/prompts/gather-context-and-clarify.md +0 -13
  302. package/packages/subagents/prompts/parallel-cleanup.md +0 -59
  303. package/packages/subagents/prompts/parallel-research.md +0 -50
  304. package/packages/subagents/prompts/parallel-review.md +0 -54
  305. package/packages/subagents/prompts/review-loop.md +0 -43
  306. package/packages/subagents/skills/council-mode/SKILL.md +0 -230
  307. package/packages/subagents/skills/subagents/references/constraints-and-recipes.md +0 -259
  308. package/packages/subagents/skills/subagents/references/execution-controls.md +0 -454
  309. package/packages/subagents/skills/subagents/references/management-authoring-rpc.md +0 -161
  310. package/packages/subagents/skills/subagents/references/multi-lane-orchestration.md +0 -39
  311. package/packages/subagents/skills/subagents/references/prompting-and-roles.md +0 -267
  312. package/packages/subagents/src/acceptance.ts +0 -331
  313. package/packages/subagents/src/agent-manager.ts +0 -405
  314. package/packages/subagents/src/agent-memory.ts +0 -300
  315. package/packages/subagents/src/agent-overrides.ts +0 -183
  316. package/packages/subagents/src/agent-runner.ts +0 -271
  317. package/packages/subagents/src/async-runner.ts +0 -422
  318. package/packages/subagents/src/authority-policy.ts +0 -47
  319. package/packages/subagents/src/budgets.ts +0 -285
  320. package/packages/subagents/src/child-safety.ts +0 -140
  321. package/packages/subagents/src/config.ts +0 -249
  322. package/packages/subagents/src/conversation-viewer.ts +0 -281
  323. package/packages/subagents/src/core-compat.ts +0 -94
  324. package/packages/subagents/src/custom-agents.ts +0 -343
  325. package/packages/subagents/src/file-system-retry.ts +0 -50
  326. package/packages/subagents/src/fleet-data.ts +0 -105
  327. package/packages/subagents/src/fleet-view.ts +0 -322
  328. package/packages/subagents/src/foreground-detach.ts +0 -59
  329. package/packages/subagents/src/fork-context.ts +0 -285
  330. package/packages/subagents/src/global.d.ts +0 -7
  331. package/packages/subagents/src/guide.ts +0 -129
  332. package/packages/subagents/src/mission-state.ts +0 -133
  333. package/packages/subagents/src/mission-store.ts +0 -436
  334. package/packages/subagents/src/output-limits.ts +0 -142
  335. package/packages/subagents/src/parity-types.ts +0 -315
  336. package/packages/subagents/src/pi-args.ts +0 -167
  337. package/packages/subagents/src/result-files.ts +0 -232
  338. package/packages/subagents/src/result-watcher.ts +0 -221
  339. package/packages/subagents/src/retained-children.ts +0 -176
  340. package/packages/subagents/src/run-fanout-budget.ts +0 -356
  341. package/packages/subagents/src/scheduled-runs.ts +0 -349
  342. package/packages/subagents/src/schemas.ts +0 -263
  343. package/packages/subagents/src/slash-commands.ts +0 -80
  344. package/packages/subagents/src/supervisor-channel.ts +0 -249
  345. package/packages/subagents/src/tool-handler.ts +0 -1144
  346. package/packages/subagents/src/types.ts +0 -238
  347. package/packages/subagents/src/widget.ts +0 -457
  348. package/packages/subagents/src/workflow-script.ts +0 -737
  349. package/packages/subagents/src/workflow-worker.ts +0 -384
  350. package/packages/subagents/src/worktree.ts +0 -614
  351. package/packages/utility/src/analytics/collector.ts +0 -293
  352. package/packages/utility/src/info-screen.ts +0 -80
  353. package/packages/utility/src/lifecycle/process.ts +0 -162
  354. package/packages/utility/src/prefix-cache.ts +0 -263
  355. package/packages/utility/src/skill-discovery.ts +0 -542
  356. package/packages/utility/src/tools/env.ts +0 -113
  357. package/packages/utility/src/tui/name-badge-state.ts +0 -315
  358. package/packages/utility/src/tui/name-badge.ts +0 -109
  359. /package/packages/{subagents/src → core/src/child-agent}/pi-spawn.ts +0 -0
@@ -1,53 +1,17 @@
1
1
  /**
2
- * Tool registration — register all compactor tools with Pi's ExtensionAPI
3
- *
4
- * Each tool is registered via pi.registerTool() with proper TypeBox schemas
5
- * so the LLM can discover and invoke them.
6
- *
7
- * Tool names:
8
- * compact, session_recall, sandbox, sandbox_file, sandbox_batch,
9
- * compactor_stats, compactor_doctor, context_budget
10
- *
11
- * Deprecated aliases for backward compatibility:
12
- * vcc_recall, ctx_execute, ctx_execute_file, ctx_batch_execute,
13
- * ctx_stats, ctx_doctor
2
+ * Tool registration — the compactor's agent-facing tools:
3
+ * session_recall search the full session history, including compacted-away parts
4
+ * context_budget how full the context is and what happens next
14
5
  */
15
6
 
16
7
  import { Type } from "typebox";
17
8
  import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
18
9
  import { vccRecall } from "./vcc-recall.js";
19
- import { ctxExecute, type CtxExecuteInput } from "./ctx-execute.js";
20
- import { ctxExecuteFile, type CtxExecuteFileInput } from "./ctx-execute-file.js";
21
- import { ctxBatchExecute, type BatchItem } from "./ctx-batch-execute.js";
22
- import { ctxStats, type CtxStatsResult } from "./ctx-stats.js";
23
- import { ctxDoctor, type DoctorResult } from "./ctx-doctor.js";
24
10
  import { contextBudgetTool } from "./context-budget.js";
25
11
  import { recallBlocksFromContext } from "../session/recall-blocks.js";
26
12
  import { filterNoise } from "../compaction/filter-noise.js";
27
13
  import { loadConfig } from "../config/manager.js";
28
- import type { SessionDB } from "../session/db.js";
29
- import type { Language, NormalizedBlock, RuntimeCounters } from "../types.js";
30
- import type { PolyglotExecutor } from "../executor/executor.js";
31
-
32
- // --- TypeBox Schemas for each tool ---
33
-
34
- const LanguageSchema = Type.Union([
35
- Type.Literal("javascript"),
36
- Type.Literal("typescript"),
37
- Type.Literal("python"),
38
- Type.Literal("shell"),
39
- Type.Literal("ruby"),
40
- Type.Literal("go"),
41
- Type.Literal("rust"),
42
- Type.Literal("php"),
43
- Type.Literal("perl"),
44
- Type.Literal("r"),
45
- Type.Literal("elixir"),
46
- ]);
47
-
48
- const CompactParams = Type.Object({
49
- dryRun: Type.Optional(Type.Boolean({ description: "If true, report what would be compacted without actually compacting" })),
50
- });
14
+ import type { RuntimeCounters } from "../types.js";
51
15
 
52
16
  const RecallParams = Type.Object({
53
17
  query: Type.Optional(Type.String({ description: "What to recall, in plain keywords (e.g. 'redis cache decision'). Multi-word queries are ranked by relevance. A regex pattern also works. #N:path drills into a file's content from an entry." })),
@@ -61,111 +25,17 @@ const RecallParams = Type.Object({
61
25
  })),
62
26
  });
63
27
 
64
- const SandboxParams = Type.Object({
65
- language: LanguageSchema,
66
- code: Type.String({ description: "Code to execute in the sandbox" }),
67
- timeout: Type.Optional(Type.Number({ description: "Timeout in ms (default 30000)", minimum: 1000 })),
68
- });
69
-
70
- const SandboxFileParams = Type.Object({
71
- language: LanguageSchema,
72
- path: Type.String({ description: "Path to file to execute" }),
73
- timeout: Type.Optional(Type.Number({ description: "Timeout in ms (default 30000)", minimum: 1000 })),
74
- });
75
-
76
- const SandboxBatchParams = Type.Object({
77
- items: Type.Array(
78
- Type.Union([
79
- Type.Object({
80
- type: Type.Literal("execute"),
81
- language: LanguageSchema,
82
- code: Type.String(),
83
- timeout: Type.Optional(Type.Number()),
84
- }),
85
- ]),
86
- { description: "Array of execute commands to run atomically" },
87
- ),
88
- });
89
-
90
- const StatsParams = Type.Object({});
91
-
92
- const DoctorParams = Type.Object({});
93
-
94
- // --- Helpers ---
95
-
96
- function textResult(text: string, details?: Record<string, unknown>): any {
97
- return {
98
- content: [{ type: "text", text }],
99
- details,
100
- };
101
- }
102
-
103
- function jsonResult(data: unknown, label?: string): any {
104
- const text = label ? `${label}:\n${JSON.stringify(data, null, 2)}` : JSON.stringify(data, null, 2);
105
- return {
106
- content: [{ type: "text", text }],
107
- details: data as Record<string, unknown>,
108
- };
109
- }
110
-
111
- // --- Registration ---
112
-
113
28
  export interface CompactorToolDeps {
114
- sessionDB: SessionDB;
115
- getSessionId: () => string;
116
- getBlocks: () => NormalizedBlock[];
117
- getCounters?: () => RuntimeCounters;
118
- sandbox?: {
119
- executor: PolyglotExecutor;
120
- allowedLanguages: Language[];
121
- };
29
+ counters: RuntimeCounters;
122
30
  }
123
31
 
124
- /**
125
- * Register all compactor tools with Pi's ExtensionAPI.
126
- * Call this during session_start after services are initialized.
127
- */
128
- export function registerCompactorTools(pi: ExtensionAPI, deps: CompactorToolDeps): void {
129
- // 1. compact — trigger manual compaction (with optional dryRun)
130
- pi.registerTool(({
131
- name: "compact",
132
- label: "Compact",
133
- description: "Trigger manual context compaction. Reduces session history while preserving continuity. Use dryRun:true to preview without compacting.",
134
- parameters: CompactParams,
135
- async execute(_toolCallId: string, params: any): Promise<import("@earendil-works/pi-coding-agent").AgentToolResult<unknown>> {
136
- if (params.dryRun) {
137
- const blocks = deps.getBlocks();
138
- const totalMessages = blocks.length;
139
- const estimated = Math.round(totalMessages * 0.15);
140
- return jsonResult({
141
- dryRun: true,
142
- wouldCompact: totalMessages,
143
- estimatedKept: estimated,
144
- message: `Would compact ${totalMessages} messages → ~${estimated} kept.`,
145
- }, "Dry run — no compaction performed");
146
- }
147
- const c = deps.getCounters?.();
148
- if (c) { c.compactions++; }
149
- return jsonResult({ success: true, message: "Compaction triggered. Stats will be available after next compact event." }, "Compaction triggered");
150
- },
151
- } as any));
32
+ const textResult = (text: string, details?: Record<string, unknown>): any => ({
33
+ content: [{ type: "text", text }],
34
+ details,
35
+ });
152
36
 
153
- // 2. session_recall (new) / vcc_recall (deprecated) — search session history
154
- const recallExec = async (_toolCallId: string, params: any, _signal?: AbortSignal, _onUpdate?: unknown, ctx?: ExtensionContext): Promise<import("@earendil-works/pi-coding-agent").AgentToolResult<unknown>> => {
155
- const c = deps.getCounters?.();
156
- if (c) { c.recallQueries++; }
157
- const config = loadConfig(ctx?.cwd ?? process.cwd());
158
- const liveBlocks = ctx ? filterNoise(recallBlocksFromContext(ctx), config.pipeline?.customNoisePatterns) : [];
159
- const blocks = liveBlocks.length > 0 ? liveBlocks : deps.getBlocks();
160
- const result = vccRecall(blocks, {
161
- query: params.query,
162
- scope: params.scope,
163
- mode: params.mode,
164
- page: params.page,
165
- expand: params.expand,
166
- });
167
- return textResult(result.text, { query: params.query ?? null });
168
- };
37
+ /** Register the compactor's tools (once, at extension load). */
38
+ export function registerCompactorTools(pi: ExtensionAPI, deps: CompactorToolDeps): void {
169
39
  pi.registerTool({
170
40
  name: "session_recall",
171
41
  label: "Session Recall",
@@ -177,139 +47,29 @@ export function registerCompactorTools(pi: ExtensionAPI, deps: CompactorToolDeps
177
47
  "and #N:path to drill into a file's content from an entry (#N:path:full for all lines). Only the current session is " +
178
48
  "searchable — earlier sessions are not.",
179
49
  parameters: RecallParams,
180
- execute: recallExec,
181
- } as any);
182
-
183
- // Sandbox tools are session-scoped and only registered when enabled.
184
- if (deps.sandbox) {
185
- const { executor, allowedLanguages } = deps.sandbox;
186
- const assertAllowedLanguage = (language: Language): void => {
187
- if (!allowedLanguages.includes(language)) {
188
- throw new Error(`Language "${language}" is disabled by Compactor sandbox settings. Allowed: ${allowedLanguages.join(", ") || "none"}`);
189
- }
190
- };
191
-
192
- // 3. sandbox (new) / ctx_execute (deprecated) — run code in sandbox
193
- const sandboxExec = async (_toolCallId: string, params: any): Promise<import("@earendil-works/pi-coding-agent").AgentToolResult<unknown>> => {
194
- try {
195
- const c = deps.getCounters?.();
196
- if (c) { c.sandboxRuns++; }
197
- deps.sessionDB.incrementSandboxRuns(deps.getSessionId());
198
- assertAllowedLanguage(params.language as Language);
199
- const result = await ctxExecute(params as CtxExecuteInput, executor);
200
- const parts: string[] = [];
201
- if (result.stdout) parts.push(result.stdout);
202
- if (result.stderr) parts.push(`[stderr] ${result.stderr}`);
203
- if (result.timedOut) parts.push("[timed out]");
204
- if (result.exitCode !== 0) parts.push(`[exit code: ${result.exitCode}]`);
205
- return textResult(parts.join("\n") || "(no output)", result as unknown as Record<string, unknown>);
206
- } catch (err) {
207
- return textResult(`Execution error: ${err}`, { error: true });
208
- }
209
- };
210
- pi.registerTool({ name: "sandbox", label: "Sandbox", description: "Run code in a sandboxed environment. Supports 11 languages. Only stdout enters context.", parameters: SandboxParams, execute: sandboxExec } as any);
211
-
212
- // 4. sandbox_file (new) / ctx_execute_file (deprecated) — execute file
213
- const sandboxFileExec = async (_toolCallId: string, params: any): Promise<import("@earendil-works/pi-coding-agent").AgentToolResult<unknown>> => {
214
- try {
215
- const c = deps.getCounters?.();
216
- if (c) { c.sandboxRuns++; }
217
- deps.sessionDB.incrementSandboxRuns(deps.getSessionId());
218
- assertAllowedLanguage(params.language as Language);
219
- const result = await ctxExecuteFile(params as CtxExecuteFileInput, executor);
220
- const parts: string[] = [];
221
- if (result.stdout) parts.push(result.stdout);
222
- if (result.stderr) parts.push(`[stderr] ${result.stderr}`);
223
- if (result.timedOut) parts.push("[timed out]");
224
- return textResult(parts.join("\n") || "(no output)", result as unknown as Record<string, unknown>);
225
- } catch (err) {
226
- return textResult(`Execution error: ${err}`, { error: true });
227
- }
228
- };
229
- pi.registerTool({ name: "sandbox_file", label: "Sandbox File", description: "Execute a file in the sandbox. File content is injected as FILE_CONTENT variable.", parameters: SandboxFileParams, execute: sandboxFileExec } as any);
230
-
231
- // 5. sandbox_batch (new) / ctx_batch_execute (deprecated) — atomic batch (execute only)
232
- const sandboxBatchExec = async (_toolCallId: string, params: any): Promise<import("@earendil-works/pi-coding-agent").AgentToolResult<unknown>> => {
233
- try {
234
- const c = deps.getCounters?.();
235
- if (c) { c.sandboxRuns++; }
236
- deps.sessionDB.incrementSandboxRuns(deps.getSessionId());
237
- for (const item of params.items as BatchItem[]) assertAllowedLanguage(item.language);
238
- const result = await ctxBatchExecute(params.items as BatchItem[], executor);
239
- const summaries = result.results.map((r, i) => {
240
- const s = r.result.stdout?.slice(0, 200) || "(no output)";
241
- return `[${i}] execute → ${r.result.exitCode === 0 ? "ok" : "fail"}: ${s}`;
50
+ async execute(_toolCallId: string, params: any, _signal?: AbortSignal, _onUpdate?: unknown, ctx?: ExtensionContext) {
51
+ deps.counters.recallQueries++;
52
+ const blocks = ctx ? filterNoise(recallBlocksFromContext(ctx)) : [];
53
+ const result = vccRecall(blocks, {
54
+ query: params.query,
55
+ scope: params.scope,
56
+ mode: params.mode,
57
+ page: params.page,
58
+ expand: params.expand,
242
59
  });
243
- return textResult(`Batch results (${result.results.length} items):\n${summaries.join("\n")}`, result as unknown as Record<string, unknown>);
244
- } catch (err) {
245
- return textResult(`Batch error: ${err}`, { error: true });
246
- }
247
- };
248
- pi.registerTool({ name: "sandbox_batch", label: "Sandbox Batch", description: "Run multiple code executions atomically as a batch.", parameters: SandboxBatchParams, execute: sandboxBatchExec } as any);
249
- }
250
-
251
- // 6. compactor_stats (new) / ctx_stats (deprecated) — context savings dashboard
252
- const statsExec = async (): Promise<import("@earendil-works/pi-coding-agent").AgentToolResult<unknown>> => {
253
- try {
254
- const result = await ctxStats(deps.sessionDB, deps.getSessionId(), deps.getCounters?.());
255
- const lines = [
256
- `📊 Compactor Stats`,
257
- `Session events: ${result.sessionEvents}`,
258
- `Compactions: ${result.compactions}`,
259
- `Tokens saved: ${result.tokensSaved}`,
260
- `Sandbox runs: ${result.sandboxRuns}`,
261
- `Search queries: ${result.searchQueries}`,
262
- ];
263
- return textResult(lines.join("\n"), result as unknown as Record<string, unknown>);
264
- } catch (err) {
265
- return textResult(`Stats error: ${err}`, { error: true });
266
- }
267
- };
268
- pi.registerTool({ name: "compactor_stats", label: "Compactor Stats", description: "Show context savings dashboard — session events, compactions, tool usage.", parameters: StatsParams, execute: statsExec } as any);
269
-
270
- // 7. compactor_doctor (new) / ctx_doctor (deprecated) — diagnostics checklist
271
- const doctorExec = async (): Promise<import("@earendil-works/pi-coding-agent").AgentToolResult<unknown>> => {
272
- try {
273
- const result = await ctxDoctor(deps.sessionDB);
274
- const icon = (s: string) => (s === "pass" ? "✅" : s === "warn" ? "⚠️" : "❌");
275
- const lines = [
276
- result.healthy ? "🩺 All checks passed" : "🩺 Issues found",
277
- "",
278
- ...result.checks.map((c) => `${icon(c.status)} ${c.name}: ${c.message}`),
279
- ];
280
- return jsonResult(result, lines.join("\n"));
281
- } catch (err) {
282
- return textResult(`Doctor error: ${err}`, { error: true });
283
- }
284
- };
285
- pi.registerTool({ name: "compactor_doctor", label: "Compactor Doctor", description: "Run diagnostics checklist — validate config, DB, runtimes.", parameters: DoctorParams, execute: doctorExec } as any);
60
+ return textResult(result.text, { query: params.query ?? null });
61
+ },
62
+ } as any);
286
63
 
287
- // 8. context_budget — estimate remaining context window
288
- pi.registerTool(({
64
+ pi.registerTool({
289
65
  name: "context_budget",
290
66
  label: "Context Budget",
291
- description: "Estimate remaining context window (% full, tokens left) and get advice on whether to compact.",
67
+ description: "Estimate how full the context window is (% full, tokens left). Compaction is automatic; this never needs to be acted on.",
292
68
  parameters: Type.Object({}),
293
- async execute(_toolCallId: string, _params: any, _signal?: AbortSignal, _onUpdate?: unknown, ctx?: ExtensionContext): Promise<import("@earendil-works/pi-coding-agent").AgentToolResult<unknown>> {
69
+ async execute(_toolCallId: string, _params: any, _signal?: AbortSignal, _onUpdate?: unknown, ctx?: ExtensionContext) {
294
70
  const config = loadConfig(ctx?.cwd ?? process.cwd());
295
- const liveUsage = ctx?.getContextUsage?.();
296
- let estimatedTokens: number | undefined = liveUsage?.tokens ?? undefined;
297
- let contextWindow = liveUsage?.contextWindow;
298
-
299
- if (estimatedTokens === undefined) {
300
- const blocks = deps.getBlocks();
301
- estimatedTokens = blocks.reduce((sum, b) => {
302
- const text = b.kind === "tool_call"
303
- ? `${b.name} ${JSON.stringify((b as any).args ?? {})}`
304
- : b.kind === "tool_result"
305
- ? `${b.name} ${(b as any).text ?? ""}`
306
- : (b as any).text ?? "";
307
- return sum + Math.ceil(text.length / 4);
308
- }, 0);
309
- }
310
-
311
- const message = contextBudgetTool(estimatedTokens, contextWindow, config.autoCompaction);
312
- return textResult(message);
71
+ const usage = ctx?.getContextUsage?.();
72
+ return textResult(contextBudgetTool(usage?.tokens ?? undefined, usage?.contextWindow, config));
313
73
  },
314
- } as any));
74
+ } as any);
315
75
  }
@@ -2,8 +2,6 @@
2
2
  * @pi-unipi/compactor — Shared TypeScript types
3
3
  */
4
4
 
5
- import type { Message } from "@earendil-works/pi-ai";
6
-
7
5
  // ─────────────────────────────────────────────────────────
8
6
  // Normalized blocks (from pi-vcc)
9
7
  // ─────────────────────────────────────────────────────────
@@ -23,39 +21,16 @@ export interface FileOps {
23
21
  }
24
22
 
25
23
  // ─────────────────────────────────────────────────────────
26
- // Section data (from pi-vcc)
27
- // ─────────────────────────────────────────────────────────
28
-
29
- export interface SectionData {
30
- sessionGoal: string[];
31
- filesAndChanges: string[];
32
- commits: string[];
33
- outstandingContext: string[];
34
- userPreferences: string[];
35
- briefTranscript: string;
36
- }
37
-
38
- export interface BriefLine {
39
- header: string;
40
- lines: string[];
41
- }
42
-
43
- // ─────────────────────────────────────────────────────────
44
- // Compaction input / output
24
+ // Compaction stats
45
25
  // ─────────────────────────────────────────────────────────
46
26
 
47
- export interface CompileInput {
48
- messages: Message[];
49
- previousSummary?: string;
50
- }
51
-
52
27
  export interface CompactionStats {
53
28
  summarized: number;
54
29
  kept: number;
55
30
  totalMessages?: number;
56
31
  /** Actual token count from Pi's preparation */
57
32
  tokensBefore?: number;
58
- /** Estimated tokens after compaction (proportional from kept/total chars) */
33
+ /** Estimated tokens after compaction: summary + kept tail. */
59
34
  tokensAfterEst?: number;
60
35
  keptUserTurns: number;
61
36
  totalUserTurns: number;
@@ -73,37 +48,58 @@ export interface CompactionStats {
73
48
 
74
49
  export type BudgetCutKind = "no_anchor" | "oversized_tail";
75
50
 
76
- export type OwnCutCancelReason =
77
- | "no_live_messages"
78
- | "too_few_live_messages";
79
-
80
- export type OwnCutResult =
81
- | {
82
- ok: true;
83
- messages: Message[];
84
- firstKeptEntryId: string;
85
- compactAll: boolean;
86
- keptUserTurns: number;
87
- totalUserTurns: number;
88
- requestedKeepUserTurns: number;
89
- keepFallbackToCompactAll: boolean;
90
- budgetCut?: BudgetCutKind;
91
- }
92
- | { ok: false; reason: OwnCutCancelReason };
93
-
94
51
  // ─────────────────────────────────────────────────────────
95
52
  // Configuration
96
53
  // ─────────────────────────────────────────────────────────
97
54
 
98
- export interface CompactorStrategyConfig {
99
- enabled: boolean;
100
- mode: string;
101
- autoDetect?: "git" | null;
55
+ /**
56
+ * vcc = UniPi's lossless zero-LLM summary; llm = a model-written summary.
57
+ */
58
+ export type CompactionMethod = "vcc" | "llm";
59
+
60
+ /** Summary sections that can be switched off (Advanced). */
61
+ export interface SummarySections {
62
+ activeWork: boolean;
63
+ requests: boolean;
64
+ state: boolean;
65
+ decisions: boolean;
66
+ files: boolean;
67
+ commits: boolean;
68
+ errors: boolean;
69
+ lessons: boolean;
70
+ transcript: boolean;
102
71
  }
103
72
 
104
- /** UniPi-managed percentage auto-compaction trigger settings. */
73
+ export interface CompactorConfig {
74
+ /** How automatic compactions are summarized. */
75
+ method: CompactionMethod;
76
+ /** What Pi's own /compact does: follow `method`, or force one. */
77
+ piCompact: "follow" | CompactionMethod;
78
+ /** When to compact: Pi's own context limit, or a percentage of the window. */
79
+ trigger: "pi" | "percent";
80
+ /** Context % that triggers compaction when trigger = "percent". */
81
+ thresholdPercent: number;
82
+ /** Notices when compaction runs or fails. */
83
+ notify: boolean;
84
+
85
+ // ── Advanced ──
86
+ /** Grow the kept tail when it would be tiny (≤5k tok, capped 25k). */
87
+ smartKeepTail: boolean;
88
+ /** Lossless summary budget in tokens; 0 = auto (scales with session size). */
89
+ summaryBudgetTokens: number;
90
+ sections: SummarySections;
91
+ /** Percentage trigger: minimum delay between compactions. */
92
+ cooldownMs: number;
93
+ /** Percentage trigger: new tokens needed to compact again while still above threshold. */
94
+ repeatMinGrowthTokens: number;
95
+ /** Extra instructions for model-written summaries. */
96
+ llmInstructions: string;
97
+ /** Write compaction diagnostics to /tmp/compactor-debug.json. */
98
+ debug: boolean;
99
+ }
100
+
101
+ /** Percentage auto-compaction trigger settings (decision input). */
105
102
  export interface AutoCompactionConfig {
106
- /** Enable the extension-managed percentage trigger. Disabled by default for backward compatibility. */
107
103
  enabled: boolean;
108
104
  /** Trigger when Pi reports context usage at or above this percent (0-100 scale). */
109
105
  thresholdPercent: number;
@@ -115,142 +111,7 @@ export interface AutoCompactionConfig {
115
111
  notify: boolean;
116
112
  }
117
113
 
118
- export interface CompactorConfig {
119
- // Compaction strategies
120
- sessionGoals: CompactorStrategyConfig & { mode: "full" | "brief" | "off" };
121
- filesAndChanges: CompactorStrategyConfig & { mode: "all" | "modified-only" | "off"; maxPerCategory: number };
122
- commits: CompactorStrategyConfig & { mode: "full" | "brief" | "off"; maxCommits: number };
123
- outstandingContext: CompactorStrategyConfig & { mode: "full" | "critical-only" | "off"; maxItems: number };
124
- userPreferences: CompactorStrategyConfig & { mode: "all" | "recent-only" | "off"; maxPreferences: number };
125
- briefTranscript: CompactorStrategyConfig & { mode: "full" | "compact" | "minimal" | "off"; userTokenLimit: number; assistantTokenLimit: number; toolCallLimit: number };
126
- sessionContinuity: CompactorStrategyConfig & {
127
- mode: "full" | "essential-only" | "off";
128
- /** @deprecated Category filtering was never implemented; ignored by runtime. */
129
- eventCategories: string[];
130
- };
131
- /** @deprecated Retained for config compatibility. */
132
- fts5Index: CompactorStrategyConfig & { mode: "auto" | "manual" | "off"; chunkSize: number; cacheTtlHours: number };
133
- sandboxExecution: CompactorStrategyConfig & { mode: "all" | "safe-only" | "off"; allowedLanguages: Language[]; outputLimit: number };
134
-
135
- // Pipeline features
136
- pipeline: {
137
- autoInjection: boolean;
138
- customNoisePatterns: string[];
139
- };
140
-
141
- // Auto compaction trigger
142
- autoCompaction: AutoCompactionConfig;
143
-
144
- // Global settings
145
- overrideDefaultCompaction: boolean;
146
- /** Boost default keep:1 to a larger tail when it is small (≤5k tok, capped 25k). Explicit keep:N always respected. */
147
- smartKeepTail: boolean;
148
- /** Ask the agent to continue after automatic (threshold/overflow) compaction. */
149
- continueAfterThresholdCompact: boolean;
150
- /** Write detailed compaction diagnostics to /tmp/compactor-debug.json. */
151
- debug: boolean;
152
- }
153
-
154
- export type CompactorPreset = "precise" | "balanced" | "thorough" | "lean" | "opencode" | "verbose" | "minimal" | "custom";
155
-
156
- // ─────────────────────────────────────────────────────────
157
- // Session events (from context-mode)
158
- // ─────────────────────────────────────────────────────────
159
-
160
- export interface SessionEvent {
161
- type: string;
162
- category: string;
163
- data: string;
164
- priority: number;
165
- data_hash: string;
166
- project_dir?: string;
167
- attribution_source?: string;
168
- attribution_confidence?: number;
169
- }
170
-
171
- export interface StoredEvent {
172
- id: number;
173
- session_id: string;
174
- type: string;
175
- category: string;
176
- priority: number;
177
- data: string;
178
- project_dir: string;
179
- attribution_source: string;
180
- attribution_confidence: number;
181
- source_hook: string;
182
- created_at: string;
183
- data_hash: string;
184
- }
185
-
186
- export interface SessionMeta {
187
- session_id: string;
188
- project_dir: string;
189
- started_at: string;
190
- last_event_at: string | null;
191
- event_count: number;
192
- compact_count: number;
193
- }
194
-
195
- export interface ResumeRow {
196
- snapshot: string;
197
- event_count: number;
198
- consumed: number;
199
- }
200
-
201
- export interface ResumeSnapshot {
202
- generatedAt: string;
203
- summary: string;
204
- events: SessionEvent[];
205
- }
206
-
207
- // ─────────────────────────────────────────────────────────
208
- // Execution (from context-mode)
209
- // ─────────────────────────────────────────────────────────
210
-
211
- export interface ExecResult {
212
- stdout: string;
213
- stderr: string;
214
- exitCode: number;
215
- timedOut: boolean;
216
- backgrounded?: boolean;
217
- }
218
-
219
- export type Language =
220
- | "javascript"
221
- | "typescript"
222
- | "python"
223
- | "shell"
224
- | "ruby"
225
- | "go"
226
- | "rust"
227
- | "php"
228
- | "perl"
229
- | "r"
230
- | "elixir";
231
-
232
- // ─────────────────────────────────────────────────────────
233
- // Content store — REMOVED
234
- // SearchResult, IndexResult, StoreStats types no longer needed.
235
- // ─────────────────────────────────────────────────────────
236
-
237
114
  export interface RuntimeCounters {
238
- sandboxRuns: number;
239
- searchQueries: number;
240
115
  recallQueries: number;
241
116
  compactions: number;
242
- totalTokensCompacted: number;
243
- }
244
-
245
- // ─────────────────────────────────────────────────────────
246
- // Info-screen integration
247
- // ─────────────────────────────────────────────────────────
248
-
249
- export interface CompactorInfoData {
250
- tokensSaved: { value: string; detail: string };
251
- costSaved: { value: string; detail: string };
252
- pctReduction: { value: string; detail: string };
253
- topTools: { value: string; detail: string };
254
- compactions: { value: string; detail: string };
255
- toolCalls: { value: string; detail: string };
256
117
  }
@@ -21,6 +21,31 @@ emitEvent(pi, UNIPI_EVENTS.MODULE_READY, {
21
21
  const safeName = sanitize("my/feature: branch");
22
22
  ```
23
23
 
24
+ ## Hints (Unicrab)
25
+
26
+ The hints system introduces **Unicrab**, a friendly pixel-crab mascot providing contextual onboarding and workflow guidance:
27
+
28
+ - **What shows when**:
29
+ - **Startup**: One least-shown, least-recent hint on `session_start` (whatsnew hints prioritized after version upgrades; lore and whatsnew excluded from regular startup rotation).
30
+ - **Start Screen**: If `hints.header` is enabled, a custom startup header features 22×10 (≥72 cols) or 14×6 (40–71 cols) truecolor half-block crab pixel art, colored wordmark, and random lore line.
31
+ - **Widget**: A compact single-row hint above the editor (`<crab> <text> <category · alt+h ›>`) rendered with a 7-column half-block mascot in truecolor/256-color (or opt-in Kitty image mode).
32
+ - **Events**: Contextual hints triggered by derived thresholds (`hints:context-high`, `hints:long-bash`, `hints:tool-errors`, `hints:long-prompt`, `hints:remember`, `hints:image-input`) and bus events. Capped at 4 event hints per session; never replaces a hint shown in the same turn.
33
+ - **Shortcuts**:
34
+ - `Alt+H`: Cycle to the next startup hint (ordered least-shown first).
35
+ - `Alt+Shift+H`: Navigate backward in the session hint history stack.
36
+ - **Commands**:
37
+ - `/unipi:hint`: Opens an interactive hub-kit overlay browser with live filtering, category headers, and seen/unseen/learned status tags.
38
+ - `/unipi:hint next`: Same as Alt+H.
39
+ - `/unipi:hint reset`: Resets show counts and learned state in `~/.unipi/global/hints/hints.json`.
40
+ - **Settings (`hints` namespace)**:
41
+ - `hints.enabled` (boolean, default true)
42
+ - `hints.header` (boolean, default true): Unicrab start screen banner.
43
+ - `hints.crab` (enum: `auto` | `blocks` | `image`, default `auto`): `auto` resolves to half-blocks; `image` is opt-in experimental Kitty terminal graphics.
44
+ - `hints.reset` (action): Clears hint history.
45
+ - **Lines (`src/hints/lines.ts`)**:
46
+ - Central lines file containing audited hints across command, shortcut, setting, capability, explain, trouble, whatsnew, workflow, and lore categories.
47
+ - **Rule**: Every named command, key, setting, or tool must be strictly verified against package source code before inclusion.
48
+
24
49
  ## Exports
25
50
 
26
51
  ### Constants
@@ -0,0 +1 @@
1
+ export * from "./src/child-agent/index.js";