ultimate-pi 0.1.7 → 0.2.2

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 (524) hide show
  1. package/.agents/skills/graphify/.graphify_version +1 -0
  2. package/.agents/skills/graphify/SKILL.md +1204 -0
  3. package/.agents/skills/wiki-autoresearch/SKILL.md +225 -97
  4. package/.agents/skills/wiki-autoresearch/references/program.md +28 -62
  5. package/.agents/skills/wiki-autoresearch/references/quality-sites.md +32 -0
  6. package/.env.example +5 -1
  7. package/.gitattributes +1 -0
  8. package/.github/workflows/publish-github-packages.yml +1 -1
  9. package/.pi/SYSTEM.md +72 -18
  10. package/.pi/agents/harness/adversary.md +32 -0
  11. package/.pi/agents/harness/evaluator.md +32 -0
  12. package/.pi/agents/harness/executor.md +34 -0
  13. package/.pi/agents/harness/meta-optimizer.md +33 -0
  14. package/.pi/agents/harness/planner.md +33 -0
  15. package/.pi/agents/harness/tie-breaker.md +35 -0
  16. package/.pi/agents/harness/trace-librarian.md +32 -0
  17. package/.pi/extensions/banner.png +0 -0
  18. package/.pi/extensions/budget-guard.ts +265 -0
  19. package/.pi/extensions/custom-footer.ts +194 -22
  20. package/.pi/extensions/custom-header.ts +47 -9
  21. package/.pi/extensions/debate-orchestrator.ts +479 -0
  22. package/.pi/extensions/harness-live-widget.ts +438 -0
  23. package/.pi/extensions/policy-gate.ts +349 -0
  24. package/.pi/extensions/review-integrity.ts +198 -0
  25. package/.pi/extensions/test-diff-integrity.ts +240 -0
  26. package/.pi/extensions/trace-recorder.ts +315 -0
  27. package/.pi/harness/README.md +23 -0
  28. package/.pi/harness/router/README.md +35 -0
  29. package/.pi/harness/router/apply-router-proposal.mjs +153 -0
  30. package/.pi/harness/router/propose-router-tuning.mjs +149 -0
  31. package/.pi/harness/specs/README.md +37 -0
  32. package/.pi/harness/specs/adversary-report.schema.json +53 -0
  33. package/.pi/harness/specs/budget-exhausted-event.schema.json +93 -0
  34. package/.pi/harness/specs/consensus-packet.schema.json +175 -0
  35. package/.pi/harness/specs/eval-verdict.schema.json +59 -0
  36. package/.pi/harness/specs/incident-record.schema.json +84 -0
  37. package/.pi/harness/specs/plan-packet.schema.json +90 -0
  38. package/.pi/harness/specs/round-result.schema.json +126 -0
  39. package/.pi/harness/specs/router-tuning-proposal.schema.json +114 -0
  40. package/.pi/harness/specs/run-trace.schema.json +107 -0
  41. package/.pi/lib/harness-ui-state.ts +311 -0
  42. package/.pi/mcp.json +4 -0
  43. package/.pi/model-router.json +93 -93
  44. package/.pi/prompts/graphify.md +23 -0
  45. package/.pi/prompts/harness-abort.md +41 -0
  46. package/.pi/prompts/harness-auto.md +83 -0
  47. package/.pi/prompts/harness-critic.md +52 -0
  48. package/.pi/prompts/harness-eval.md +51 -0
  49. package/.pi/prompts/harness-incident.md +51 -0
  50. package/.pi/prompts/harness-plan.md +64 -0
  51. package/.pi/prompts/harness-review.md +52 -0
  52. package/.pi/prompts/harness-router-tune.md +74 -0
  53. package/.pi/prompts/harness-run.md +59 -0
  54. package/.pi/prompts/harness-setup.md +316 -216
  55. package/.pi/prompts/harness-trace.md +51 -0
  56. package/.pi/prompts/wiki-autoresearch.md +9 -7
  57. package/.pi/prompts/wiki-save.md +20 -0
  58. package/.pi/skills/agent-router/SKILL.md +2 -4
  59. package/.pi/skills/ast-grep/SKILL.md +354 -0
  60. package/.pi/sounds/project-sounds.json +18 -24
  61. package/AGENTS.md +30 -0
  62. package/CHANGELOG.md +89 -0
  63. package/CONTRIBUTING.md +51 -1
  64. package/README.md +264 -20
  65. package/biome.json +8 -2
  66. package/lefthook.yml +3 -2
  67. package/node_modules/@sting8k/pi-vcc/README.md +200 -0
  68. package/node_modules/@sting8k/pi-vcc/index.ts +14 -0
  69. package/node_modules/@sting8k/pi-vcc/package.json +26 -0
  70. package/node_modules/@sting8k/pi-vcc/scripts/audit-sessions.ts +88 -0
  71. package/node_modules/@sting8k/pi-vcc/scripts/benchmark-real-sessions.ts +25 -0
  72. package/node_modules/@sting8k/pi-vcc/scripts/compare-before-after.ts +36 -0
  73. package/node_modules/@sting8k/pi-vcc/scripts/dump-branch-output.ts +20 -0
  74. package/node_modules/@sting8k/pi-vcc/src/commands/pi-vcc.ts +36 -0
  75. package/node_modules/@sting8k/pi-vcc/src/commands/vcc-recall.ts +65 -0
  76. package/node_modules/@sting8k/pi-vcc/src/core/brief.ts +381 -0
  77. package/node_modules/@sting8k/pi-vcc/src/core/build-sections.ts +79 -0
  78. package/node_modules/@sting8k/pi-vcc/src/core/content.ts +60 -0
  79. package/node_modules/@sting8k/pi-vcc/src/core/filter-noise.ts +42 -0
  80. package/node_modules/@sting8k/pi-vcc/src/core/format-recall.ts +27 -0
  81. package/node_modules/@sting8k/pi-vcc/src/core/format.ts +49 -0
  82. package/node_modules/@sting8k/pi-vcc/src/core/lineage.ts +26 -0
  83. package/node_modules/@sting8k/pi-vcc/src/core/load-messages.ts +41 -0
  84. package/node_modules/@sting8k/pi-vcc/src/core/normalize.ts +66 -0
  85. package/node_modules/@sting8k/pi-vcc/src/core/recall-scope.ts +14 -0
  86. package/node_modules/@sting8k/pi-vcc/src/core/render-entries.ts +55 -0
  87. package/node_modules/@sting8k/pi-vcc/src/core/report.ts +237 -0
  88. package/node_modules/@sting8k/pi-vcc/src/core/sanitize.ts +5 -0
  89. package/node_modules/@sting8k/pi-vcc/src/core/search-entries.ts +221 -0
  90. package/node_modules/@sting8k/pi-vcc/src/core/settings.ts +77 -0
  91. package/node_modules/@sting8k/pi-vcc/src/core/skill-collapse.ts +35 -0
  92. package/node_modules/@sting8k/pi-vcc/src/core/summarize.ts +157 -0
  93. package/node_modules/@sting8k/pi-vcc/src/core/tool-args.ts +14 -0
  94. package/node_modules/@sting8k/pi-vcc/src/details.ts +7 -0
  95. package/node_modules/@sting8k/pi-vcc/src/extract/commits.ts +69 -0
  96. package/node_modules/@sting8k/pi-vcc/src/extract/files.ts +80 -0
  97. package/node_modules/@sting8k/pi-vcc/src/extract/goals.ts +79 -0
  98. package/node_modules/@sting8k/pi-vcc/src/extract/preferences.ts +55 -0
  99. package/node_modules/@sting8k/pi-vcc/src/hooks/before-compact.ts +322 -0
  100. package/node_modules/@sting8k/pi-vcc/src/sections.ts +12 -0
  101. package/node_modules/@sting8k/pi-vcc/src/tools/recall.ts +109 -0
  102. package/node_modules/@sting8k/pi-vcc/src/types.ts +14 -0
  103. package/node_modules/@sting8k/pi-vcc/tests/before-compact-hook.test.ts +181 -0
  104. package/node_modules/@sting8k/pi-vcc/tests/before-compact.test.ts +140 -0
  105. package/node_modules/@sting8k/pi-vcc/tests/brief.test.ts +206 -0
  106. package/node_modules/@sting8k/pi-vcc/tests/build-sections.test.ts +59 -0
  107. package/node_modules/@sting8k/pi-vcc/tests/compile.test.ts +80 -0
  108. package/node_modules/@sting8k/pi-vcc/tests/content.test.ts +31 -0
  109. package/node_modules/@sting8k/pi-vcc/tests/extract-goals.test.ts +86 -0
  110. package/node_modules/@sting8k/pi-vcc/tests/extract-preferences.test.ts +30 -0
  111. package/node_modules/@sting8k/pi-vcc/tests/filter-noise.test.ts +61 -0
  112. package/node_modules/@sting8k/pi-vcc/tests/fixtures.ts +61 -0
  113. package/node_modules/@sting8k/pi-vcc/tests/format-recall.test.ts +30 -0
  114. package/node_modules/@sting8k/pi-vcc/tests/format.test.ts +62 -0
  115. package/node_modules/@sting8k/pi-vcc/tests/lineage.test.ts +33 -0
  116. package/node_modules/@sting8k/pi-vcc/tests/load-messages.test.ts +51 -0
  117. package/node_modules/@sting8k/pi-vcc/tests/normalize.test.ts +97 -0
  118. package/node_modules/@sting8k/pi-vcc/tests/real-sessions.test.ts +38 -0
  119. package/node_modules/@sting8k/pi-vcc/tests/recall-expand.test.ts +15 -0
  120. package/node_modules/@sting8k/pi-vcc/tests/recall-scope.test.ts +32 -0
  121. package/node_modules/@sting8k/pi-vcc/tests/recall-tool-scope.test.ts +67 -0
  122. package/node_modules/@sting8k/pi-vcc/tests/render-entries.test.ts +62 -0
  123. package/node_modules/@sting8k/pi-vcc/tests/report.test.ts +44 -0
  124. package/node_modules/@sting8k/pi-vcc/tests/sanitize.test.ts +24 -0
  125. package/node_modules/@sting8k/pi-vcc/tests/search-entries.test.ts +144 -0
  126. package/node_modules/@sting8k/pi-vcc/tests/support/load-session.ts +23 -0
  127. package/node_modules/@sting8k/pi-vcc/tests/support/real-sessions.ts +51 -0
  128. package/package.json +15 -4
  129. package/scripts/__pycache__/merge_graphify_corpora.cpython-314.pyc +0 -0
  130. package/scripts/index_youtube_urls.py +376 -0
  131. package/scripts/merge_graphify_corpora.py +398 -0
  132. package/scripts/regen_graphify_html.py +46 -0
  133. package/.agents/skills/defuddle/SKILL.md +0 -90
  134. package/.agents/skills/wiki/SKILL.md +0 -215
  135. package/.agents/skills/wiki/references/css-snippets.md +0 -122
  136. package/.agents/skills/wiki/references/frontmatter.md +0 -107
  137. package/.agents/skills/wiki/references/git-setup.md +0 -58
  138. package/.agents/skills/wiki/references/mcp-setup.md +0 -149
  139. package/.agents/skills/wiki/references/modes.md +0 -259
  140. package/.agents/skills/wiki/references/plugins.md +0 -96
  141. package/.agents/skills/wiki/references/rest-api.md +0 -124
  142. package/.agents/skills/wiki-fold/SKILL.md +0 -204
  143. package/.agents/skills/wiki-fold/references/fold-template.md +0 -133
  144. package/.agents/skills/wiki-ingest/SKILL.md +0 -288
  145. package/.agents/skills/wiki-lint/SKILL.md +0 -183
  146. package/.agents/skills/wiki-query/SKILL.md +0 -176
  147. package/.pi/agents/rethink.md +0 -140
  148. package/.pi/agents/wiki-ingest.md +0 -67
  149. package/.pi/agents/wiki-lint.md +0 -75
  150. package/.pi/internal/cursor-sdk-transcript-parser.ts +0 -59
  151. package/.pi/prompts/save.md +0 -16
  152. package/.pi/prompts/wiki.md +0 -23
  153. package/.pi/providers/cursor-sdk-provider.test.mjs +0 -476
  154. package/.pi/providers/cursor-sdk-provider.ts +0 -1085
  155. package/vault/AGENTS.md +0 -37
  156. package/vault/wiki/_templates/comparison.md +0 -39
  157. package/vault/wiki/_templates/concept.md +0 -40
  158. package/vault/wiki/_templates/decision.md +0 -21
  159. package/vault/wiki/_templates/entity.md +0 -32
  160. package/vault/wiki/_templates/flow.md +0 -14
  161. package/vault/wiki/_templates/module.md +0 -18
  162. package/vault/wiki/_templates/question.md +0 -31
  163. package/vault/wiki/_templates/source.md +0 -39
  164. package/vault/wiki/concepts/AST-Aware Code Chunking.md +0 -44
  165. package/vault/wiki/concepts/Build-Time Prompt Compilation.md +0 -107
  166. package/vault/wiki/concepts/Context Engine (AI Coding).md +0 -47
  167. package/vault/wiki/concepts/Context-Aware System Reminders.md +0 -61
  168. package/vault/wiki/concepts/Contextualized Text Embedding.md +0 -42
  169. package/vault/wiki/concepts/Contractor vs Employee AI Model.md +0 -55
  170. package/vault/wiki/concepts/Dual-Model Agent Architecture.md +0 -65
  171. package/vault/wiki/concepts/Late Chunking vs Early Chunking.md +0 -43
  172. package/vault/wiki/concepts/Majority Vote Ensembling.md +0 -68
  173. package/vault/wiki/concepts/Meta-Harness.md +0 -16
  174. package/vault/wiki/concepts/Multi-Agent AI Coding Architecture.md +0 -75
  175. package/vault/wiki/concepts/Prompt Enhancement.md +0 -90
  176. package/vault/wiki/concepts/Prompt Renderer.md +0 -89
  177. package/vault/wiki/concepts/Semantic Codebase Indexing.md +0 -67
  178. package/vault/wiki/concepts/additive-config-hierarchy.md +0 -16
  179. package/vault/wiki/concepts/agent-artifacts-verifiable-deliverables.md +0 -71
  180. package/vault/wiki/concepts/agent-browser-browser-automation.md +0 -99
  181. package/vault/wiki/concepts/agent-codebase-interface.md +0 -43
  182. package/vault/wiki/concepts/agent-harness-architecture.md +0 -67
  183. package/vault/wiki/concepts/agent-loop-detection-patterns.md +0 -133
  184. package/vault/wiki/concepts/agent-search-enforcement.md +0 -126
  185. package/vault/wiki/concepts/agent-skills-ecosystem.md +0 -74
  186. package/vault/wiki/concepts/agent-skills-pattern.md +0 -68
  187. package/vault/wiki/concepts/agentic-harness-context-enforcement.md +0 -91
  188. package/vault/wiki/concepts/agentic-harness.md +0 -34
  189. package/vault/wiki/concepts/agentic-orchestration-pipeline.md +0 -56
  190. package/vault/wiki/concepts/agentic-search-no-embeddings.md +0 -18
  191. package/vault/wiki/concepts/anthropic-context-engineering.md +0 -13
  192. package/vault/wiki/concepts/antigravity-agent-first-architecture.md +0 -61
  193. package/vault/wiki/concepts/ast-compression.md +0 -19
  194. package/vault/wiki/concepts/ast-truncation.md +0 -66
  195. package/vault/wiki/concepts/barrel-files.md +0 -37
  196. package/vault/wiki/concepts/browser-harness-agent.md +0 -41
  197. package/vault/wiki/concepts/browser-subagent-visual-verification.md +0 -82
  198. package/vault/wiki/concepts/codebase-intelligence-ecosystem-comparison.md +0 -192
  199. package/vault/wiki/concepts/codebase-intelligence-harness-integration.md +0 -161
  200. package/vault/wiki/concepts/codebase-to-context-ingestion.md +0 -46
  201. package/vault/wiki/concepts/codex-harness-innovations.md +0 -147
  202. package/vault/wiki/concepts/consensus-debate-flow.md +0 -17
  203. package/vault/wiki/concepts/consensus-debate.md +0 -206
  204. package/vault/wiki/concepts/content-addressed-spec-identity.md +0 -166
  205. package/vault/wiki/concepts/context-anxiety.md +0 -57
  206. package/vault/wiki/concepts/context-compression-techniques.md +0 -19
  207. package/vault/wiki/concepts/context-continuity.md +0 -22
  208. package/vault/wiki/concepts/context-drift-in-agents.md +0 -106
  209. package/vault/wiki/concepts/context-engineering.md +0 -62
  210. package/vault/wiki/concepts/context-folding.md +0 -67
  211. package/vault/wiki/concepts/context-mode.md +0 -38
  212. package/vault/wiki/concepts/cursor-harness-innovations.md +0 -107
  213. package/vault/wiki/concepts/deterministic-session-compaction.md +0 -79
  214. package/vault/wiki/concepts/drift-detection-unified.md +0 -296
  215. package/vault/wiki/concepts/execution-feedback-loop.md +0 -46
  216. package/vault/wiki/concepts/feedforward-feedback-harness.md +0 -60
  217. package/vault/wiki/concepts/five-root-cause-metrics-sentrux.md +0 -40
  218. package/vault/wiki/concepts/fork-safe-spec-storage.md +0 -89
  219. package/vault/wiki/concepts/fts5-sandbox.md +0 -19
  220. package/vault/wiki/concepts/fuzzy-edit-matching.md +0 -71
  221. package/vault/wiki/concepts/gemini-cli-architecture.md +0 -104
  222. package/vault/wiki/concepts/generator-evaluator-architecture.md +0 -64
  223. package/vault/wiki/concepts/guardian-agent-pattern.md +0 -67
  224. package/vault/wiki/concepts/harness-configuration-layers.md +0 -89
  225. package/vault/wiki/concepts/harness-control-frameworks.md +0 -155
  226. package/vault/wiki/concepts/harness-engineering-first-principles.md +0 -90
  227. package/vault/wiki/concepts/harness-h-formalism.md +0 -53
  228. package/vault/wiki/concepts/hybrid-code-search.md +0 -61
  229. package/vault/wiki/concepts/inline-post-edit-validation.md +0 -112
  230. package/vault/wiki/concepts/legendary-engineering-patterns-harness.md +0 -110
  231. package/vault/wiki/concepts/lifecycle-hooks.md +0 -94
  232. package/vault/wiki/concepts/mcp-tool-routing.md +0 -102
  233. package/vault/wiki/concepts/memory-system-of-record-vs-ephemeral-cache.md +0 -47
  234. package/vault/wiki/concepts/meta-agent-context-pruning.md +0 -151
  235. package/vault/wiki/concepts/model-adaptive-harness.md +0 -122
  236. package/vault/wiki/concepts/model-routing-agents.md +0 -101
  237. package/vault/wiki/concepts/monorepo-architecture.md +0 -45
  238. package/vault/wiki/concepts/multi-agent-specialization.md +0 -61
  239. package/vault/wiki/concepts/permission-subsystem.md +0 -16
  240. package/vault/wiki/concepts/pi-messenger-analysis.md +0 -243
  241. package/vault/wiki/concepts/pi-vscode-extension-landscape.md +0 -37
  242. package/vault/wiki/concepts/policy-engine-pattern.md +0 -78
  243. package/vault/wiki/concepts/progressive-disclosure-agents.md +0 -53
  244. package/vault/wiki/concepts/progressive-skill-disclosure.md +0 -17
  245. package/vault/wiki/concepts/provider-native-prompting.md +0 -203
  246. package/vault/wiki/concepts/quality-signal-sentrux.md +0 -37
  247. package/vault/wiki/concepts/repo-map-ranking.md +0 -42
  248. package/vault/wiki/concepts/result-monad-error-handling.md +0 -47
  249. package/vault/wiki/concepts/safety-defense-in-depth.md +0 -83
  250. package/vault/wiki/concepts/sandbox-os-enforcement.md +0 -18
  251. package/vault/wiki/concepts/selective-debate-routing.md +0 -70
  252. package/vault/wiki/concepts/self-evolving-harness.md +0 -60
  253. package/vault/wiki/concepts/sentrux-mcp-integration.md +0 -36
  254. package/vault/wiki/concepts/sentrux-rules-engine.md +0 -49
  255. package/vault/wiki/concepts/shell-pattern-compression.md +0 -24
  256. package/vault/wiki/concepts/skill-first-architecture.md +0 -166
  257. package/vault/wiki/concepts/structured-compaction.md +0 -78
  258. package/vault/wiki/concepts/subagent-orchestration.md +0 -17
  259. package/vault/wiki/concepts/subagent-worktree-isolation.md +0 -68
  260. package/vault/wiki/concepts/superpowers-methodology.md +0 -78
  261. package/vault/wiki/concepts/think-in-code.md +0 -73
  262. package/vault/wiki/concepts/ts-execution-layer.md +0 -100
  263. package/vault/wiki/concepts/typescript-strict-mode.md +0 -37
  264. package/vault/wiki/concepts/vcc-conversation-compaction-for-pi.md +0 -53
  265. package/vault/wiki/concepts/verification-drift-detection.md +0 -19
  266. package/vault/wiki/consensus/consensus-records.md +0 -58
  267. package/vault/wiki/decisions/2026-04-30-pi-lean-ctx-native.md +0 -122
  268. package/vault/wiki/decisions/2026-05-07-replace-lean-ctx-with-context-mode.md +0 -59
  269. package/vault/wiki/decisions/adr-008.md +0 -40
  270. package/vault/wiki/decisions/adr-009.md +0 -46
  271. package/vault/wiki/decisions/adr-010.md +0 -55
  272. package/vault/wiki/decisions/adr-011.md +0 -165
  273. package/vault/wiki/decisions/adr-012.md +0 -102
  274. package/vault/wiki/decisions/adr-013.md +0 -59
  275. package/vault/wiki/decisions/adr-014.md +0 -73
  276. package/vault/wiki/decisions/adr-015.md +0 -81
  277. package/vault/wiki/decisions/adr-016.md +0 -91
  278. package/vault/wiki/decisions/adr-017.md +0 -79
  279. package/vault/wiki/decisions/adr-018.md +0 -100
  280. package/vault/wiki/decisions/adr-019.md +0 -75
  281. package/vault/wiki/decisions/adr-020.md +0 -106
  282. package/vault/wiki/decisions/adr-021.md +0 -86
  283. package/vault/wiki/decisions/adr-022.md +0 -113
  284. package/vault/wiki/decisions/adr-023.md +0 -113
  285. package/vault/wiki/decisions/adr-024.md +0 -73
  286. package/vault/wiki/decisions/adr-025.md +0 -130
  287. package/vault/wiki/decisions/adr-026.md +0 -56
  288. package/vault/wiki/decisions/adr-027.md +0 -94
  289. package/vault/wiki/decisions/colocate-wiki.md +0 -34
  290. package/vault/wiki/entities/Anders Hejlsberg.md +0 -29
  291. package/vault/wiki/entities/Anthropic.md +0 -17
  292. package/vault/wiki/entities/Augment Code.md +0 -49
  293. package/vault/wiki/entities/Bjarne Stroustrup.md +0 -26
  294. package/vault/wiki/entities/Bolt.new (StackBlitz).md +0 -39
  295. package/vault/wiki/entities/Boris Cherny.md +0 -11
  296. package/vault/wiki/entities/Claude Code.md +0 -19
  297. package/vault/wiki/entities/Dennis Ritchie.md +0 -26
  298. package/vault/wiki/entities/Emergent Labs.md +0 -32
  299. package/vault/wiki/entities/Google Cloud.md +0 -16
  300. package/vault/wiki/entities/Guido van Rossum.md +0 -28
  301. package/vault/wiki/entities/Ken Thompson.md +0 -28
  302. package/vault/wiki/entities/Lee et al.md +0 -16
  303. package/vault/wiki/entities/Linus Torvalds.md +0 -28
  304. package/vault/wiki/entities/Lovable (company).md +0 -40
  305. package/vault/wiki/entities/Martin Fowler.md +0 -16
  306. package/vault/wiki/entities/Meng et al.md +0 -16
  307. package/vault/wiki/entities/OpenAI.md +0 -16
  308. package/vault/wiki/entities/Rocket.new.md +0 -38
  309. package/vault/wiki/entities/VILA-Lab.md +0 -15
  310. package/vault/wiki/entities/autodev-codebase.md +0 -18
  311. package/vault/wiki/entities/ck-tool.md +0 -59
  312. package/vault/wiki/entities/codesearch.md +0 -18
  313. package/vault/wiki/entities/disler-indydevdan.md +0 -33
  314. package/vault/wiki/entities/gsd-get-shit-done.md +0 -56
  315. package/vault/wiki/entities/javascript-runtimes.md +0 -48
  316. package/vault/wiki/entities/jesse-vincent.md +0 -38
  317. package/vault/wiki/entities/lean-ctx.md +0 -32
  318. package/vault/wiki/entities/opendev.md +0 -41
  319. package/vault/wiki/entities/ops-codegraph-tool.md +0 -18
  320. package/vault/wiki/entities/pi-coding-agent.md +0 -53
  321. package/vault/wiki/entities/sentrux.md +0 -54
  322. package/vault/wiki/entities/vgrep-tool.md +0 -57
  323. package/vault/wiki/entities/vitest.md +0 -41
  324. package/vault/wiki/flows/harness-wiki-pipeline.md +0 -204
  325. package/vault/wiki/hot.md +0 -932
  326. package/vault/wiki/index.md +0 -437
  327. package/vault/wiki/log.md +0 -422
  328. package/vault/wiki/meta/dashboard.md +0 -30
  329. package/vault/wiki/meta/lint-report-2026-04-30.md +0 -86
  330. package/vault/wiki/meta/lint-report-2026-05-02.md +0 -251
  331. package/vault/wiki/meta/overview.canvas +0 -43
  332. package/vault/wiki/modules/adversarial-verification.md +0 -57
  333. package/vault/wiki/modules/automated-observability.md +0 -54
  334. package/vault/wiki/modules/bench.md +0 -20
  335. package/vault/wiki/modules/extensions.md +0 -23
  336. package/vault/wiki/modules/grounding-checkpoints.md +0 -62
  337. package/vault/wiki/modules/harness-implementation-plan.md +0 -345
  338. package/vault/wiki/modules/harness-wiki-skill-mapping.md +0 -135
  339. package/vault/wiki/modules/harness.md +0 -86
  340. package/vault/wiki/modules/persistent-memory.md +0 -85
  341. package/vault/wiki/modules/schema-orchestration.md +0 -68
  342. package/vault/wiki/modules/skills.md +0 -27
  343. package/vault/wiki/modules/spec-hardening.md +0 -58
  344. package/vault/wiki/modules/structured-planning.md +0 -53
  345. package/vault/wiki/modules/think-in-code-enforcement.md +0 -153
  346. package/vault/wiki/modules/wiki-query-interface.md +0 -64
  347. package/vault/wiki/overview.md +0 -51
  348. package/vault/wiki/questions/Research-pi-vs-claude-code-agentic-orchestration-pipeline.md +0 -87
  349. package/vault/wiki/questions/Research-sentrux-dev.md +0 -123
  350. package/vault/wiki/questions/Research-superpowers-skill-for-agentic-coding-agents.md +0 -164
  351. package/vault/wiki/questions/Research: Augment Code Context Engine.md +0 -244
  352. package/vault/wiki/questions/Research: Automating Software Engineering - Lovable, Bolt, Emergent, Rocket.md +0 -112
  353. package/vault/wiki/questions/Research: Claude Code State-of-the-Art Harness Improvements.md +0 -209
  354. package/vault/wiki/questions/Research: Codex State-of-the-Art Harness Improvements.md +0 -99
  355. package/vault/wiki/questions/Research: Engineering Workflows of Legendary Programmers and AI Harness Mapping.md +0 -107
  356. package/vault/wiki/questions/Research: Fallow Codebase Intelligence Harness Integration.md +0 -72
  357. package/vault/wiki/questions/Research: Gemini CLI SOTA Harness Integration.md +0 -166
  358. package/vault/wiki/questions/Research: GitHub Issues as Harness Spec Storage.md +0 -188
  359. package/vault/wiki/questions/Research: Google Antigravity Harness Integration.md +0 -120
  360. package/vault/wiki/questions/Research: Meta-Agent Context Drift Detection.md +0 -236
  361. package/vault/wiki/questions/Research: Model-Adaptive Agent Harness Design.md +0 -95
  362. package/vault/wiki/questions/Research: Model-Specific Prompting Guides.md +0 -165
  363. package/vault/wiki/questions/Research: Prompt Renderer for Multi-Model Agent Harness.md +0 -216
  364. package/vault/wiki/questions/Research: Skill-First Harness Architecture.md +0 -91
  365. package/vault/wiki/questions/Research: TypeScript Best Practices and Codebase Structure.md +0 -88
  366. package/vault/wiki/questions/Research: TypeScript Execution Layer for Agent Tool Calling.md +0 -81
  367. package/vault/wiki/questions/Research: claude-mem over Obsidian for Harness Layer.md +0 -71
  368. package/vault/wiki/questions/Research: claude-mem over obsidian wiki as the knowledge base for our agentic harness pipeline. think from first principles. does this replace or complement our current setup? no hard feelings about previous decisions. gimme accurate points.md +0 -80
  369. package/vault/wiki/questions/Research: context-mode vs lean-ctx.md +0 -72
  370. package/vault/wiki/questions/Research: cursor.sh Harness Innovations.md +0 -92
  371. package/vault/wiki/questions/Research: executor.sh Harness Integration.md +0 -170
  372. package/vault/wiki/questions/Research: how GSD fits into our coding harness setup.md +0 -97
  373. package/vault/wiki/questions/Research: how claude-mem fits into our workflow. and whether it should replace obsidian in the codebase. no hard feelings about previous actions, rethink from first principles always.md +0 -80
  374. package/vault/wiki/questions/Research: pi-vcc.md +0 -113
  375. package/vault/wiki/questions/Research: semantic code search tools.md +0 -69
  376. package/vault/wiki/questions/Research: vcc extension for pi coding agent.md +0 -73
  377. package/vault/wiki/questions/how-to-enable-semantic-code-search-now.md +0 -111
  378. package/vault/wiki/questions/mvp-implementation-blueprint.md +0 -552
  379. package/vault/wiki/questions/research-agent-first-codebase-exploration.md +0 -199
  380. package/vault/wiki/questions/research-agentic-coding-harness-latest-papers.md +0 -142
  381. package/vault/wiki/questions/research-gitingest-gitreverse-integration.md +0 -100
  382. package/vault/wiki/questions/research-wozcode-token-reduction.md +0 -67
  383. package/vault/wiki/questions/resolved-context-pruning-inplace-vs-restart.md +0 -95
  384. package/vault/wiki/questions/resolved-context-window-economics.md +0 -167
  385. package/vault/wiki/questions/resolved-imad-debate-gating-transfer.md +0 -126
  386. package/vault/wiki/questions/resolved-mcp-tool-preference.md +0 -112
  387. package/vault/wiki/questions/resolved-small-model-meta-agents.md +0 -107
  388. package/vault/wiki/questions/resolved-treesitter-dynamic-languages.md +0 -95
  389. package/vault/wiki/sources/Auggie Context MCP Server.md +0 -63
  390. package/vault/wiki/sources/Augment Code Codacy AI Giants.md +0 -61
  391. package/vault/wiki/sources/Augment Code MCP SiliconAngle.md +0 -49
  392. package/vault/wiki/sources/Augment Code WorkOS ERC 2025.md +0 -55
  393. package/vault/wiki/sources/Augment Context Engine Official.md +0 -71
  394. package/vault/wiki/sources/Augment SWE-bench Agent GitHub.md +0 -74
  395. package/vault/wiki/sources/Augment SWE-bench Pro Blog.md +0 -58
  396. package/vault/wiki/sources/Source: AgentBus Jinja2 Prompt Pipelines.md +0 -75
  397. package/vault/wiki/sources/Source: Arxiv /342/200/224 Don't Break the Cache.md" +0 -85
  398. package/vault/wiki/sources/Source: Augment - Harness Engineering for AI Coding Agents.md +0 -58
  399. package/vault/wiki/sources/Source: Blake Crosley Agent Architecture Guide.md +0 -100
  400. package/vault/wiki/sources/Source: Bolt.new Architecture & Case Study.md +0 -75
  401. package/vault/wiki/sources/Source: Build-Time Prompt Compilation Architecture.md +0 -107
  402. package/vault/wiki/sources/Source: Claude API Agent Skills Overview.md +0 -70
  403. package/vault/wiki/sources/Source: Gemini CLI Changelogs.md +0 -88
  404. package/vault/wiki/sources/Source: Google Blog - Gemini CLI Announcement.md +0 -57
  405. package/vault/wiki/sources/Source: Google Gemini CLI Architecture Docs.md +0 -53
  406. package/vault/wiki/sources/Source: LangChain - Anatomy of Agent Harness.md +0 -65
  407. package/vault/wiki/sources/Source: Lovable Architecture & Clone Analysis.md +0 -83
  408. package/vault/wiki/sources/Source: Martin Fowler - Harness Engineering.md +0 -70
  409. package/vault/wiki/sources/Source: OpenAI Harness Engineering Five Principles.md +0 -58
  410. package/vault/wiki/sources/Source: OpenAI Harness Engineering /342/200/224 0 Lines of Human Code.md" +0 -101
  411. package/vault/wiki/sources/Source: OpenDev /342/200/224 Building AI Coding Agents for the Terminal.md" +0 -100
  412. package/vault/wiki/sources/Source: Render AI Coding Agents Benchmark 2025.md +0 -53
  413. package/vault/wiki/sources/Source: Rocket.new /342/200/224 Vibe Solutioning Platform.md" +0 -70
  414. package/vault/wiki/sources/Source: SwirlAI Agent Skills Progressive Disclosure.md +0 -71
  415. package/vault/wiki/sources/Source: TianPan Prompt Caching Architecture.md +0 -89
  416. package/vault/wiki/sources/Source: Vercel Labs agent-browser.md +0 -155
  417. package/vault/wiki/sources/Source: browser-harness CDP Harness.md +0 -126
  418. package/vault/wiki/sources/agent-drift-academic-paper.md +0 -79
  419. package/vault/wiki/sources/aider-repomap-tree-sitter.md +0 -42
  420. package/vault/wiki/sources/anthropic-compaction-api.md +0 -58
  421. package/vault/wiki/sources/anthropic-effective-harnesses.md +0 -42
  422. package/vault/wiki/sources/anthropic-prompt-best-practices.md +0 -100
  423. package/vault/wiki/sources/anthropic2026-harness-design.md +0 -63
  424. package/vault/wiki/sources/barrel-files-tkdodo.md +0 -38
  425. package/vault/wiki/sources/birth-of-unix-kernighan-interview.md +0 -57
  426. package/vault/wiki/sources/bockeler2026-harness-engineering.md +0 -69
  427. package/vault/wiki/sources/cast-code-chunking-paper.md +0 -50
  428. package/vault/wiki/sources/ck-semantic-search.md +0 -78
  429. package/vault/wiki/sources/claude-code-architecture-karaxai-2026.md +0 -71
  430. package/vault/wiki/sources/claude-code-architecture-qubytes-2026.md +0 -50
  431. package/vault/wiki/sources/claude-code-architecture-vila-lab-2026.md +0 -64
  432. package/vault/wiki/sources/claude-code-security-architecture-penligent-2026.md +0 -70
  433. package/vault/wiki/sources/claude-context-editing-docs.md +0 -13
  434. package/vault/wiki/sources/cloudflare-codemode.md +0 -63
  435. package/vault/wiki/sources/code-chunk-library-supermemory.md +0 -63
  436. package/vault/wiki/sources/codeact-apple-2024.md +0 -62
  437. package/vault/wiki/sources/codex-dsc-rfc-8573.md +0 -41
  438. package/vault/wiki/sources/codex-open-source-agent-2026.md +0 -110
  439. package/vault/wiki/sources/coir-code-retrieval-benchmark.md +0 -51
  440. package/vault/wiki/sources/colinmcnamara-context-optimization-codemode.md +0 -48
  441. package/vault/wiki/sources/context-folding-paper.md +0 -61
  442. package/vault/wiki/sources/context-mode-website.md +0 -63
  443. package/vault/wiki/sources/cursor-agent-best-practices-2026.md +0 -62
  444. package/vault/wiki/sources/cursor-fork-29b-2025.md +0 -50
  445. package/vault/wiki/sources/cursor-harness-april-2026.md +0 -76
  446. package/vault/wiki/sources/cursor-instant-apply-2024.md +0 -45
  447. package/vault/wiki/sources/cursor-shadow-workspace-2024.md +0 -52
  448. package/vault/wiki/sources/cursor-shipped-coding-agent-2026.md +0 -53
  449. package/vault/wiki/sources/cursor-vs-antigravity-2026.md +0 -51
  450. package/vault/wiki/sources/disler-pi-vs-claude-code.md +0 -69
  451. package/vault/wiki/sources/distill-deterministic-context-compression.md +0 -53
  452. package/vault/wiki/sources/embedding-models-benchmark-supermemory-2025.md +0 -48
  453. package/vault/wiki/sources/executor-rhyssullivan.md +0 -122
  454. package/vault/wiki/sources/fallow-rs-codebase-intelligence.md +0 -125
  455. package/vault/wiki/sources/fan2025-imad.md +0 -60
  456. package/vault/wiki/sources/forgecode-gpt5-agent-improvements.md +0 -63
  457. package/vault/wiki/sources/gemini-3-prompting-guide.md +0 -78
  458. package/vault/wiki/sources/gh-cli-sub-issue-rfc.md +0 -50
  459. package/vault/wiki/sources/gh-sub-issue-extension.md +0 -72
  460. package/vault/wiki/sources/github-fork-issues-discussion.md +0 -44
  461. package/vault/wiki/sources/github-issue-dependencies-docs.md +0 -49
  462. package/vault/wiki/sources/github-sub-issues-docs.md +0 -51
  463. package/vault/wiki/sources/gitingest.md +0 -91
  464. package/vault/wiki/sources/gitreverse.md +0 -63
  465. package/vault/wiki/sources/google-antigravity-official-blog.md +0 -47
  466. package/vault/wiki/sources/google-antigravity-wikipedia.md +0 -53
  467. package/vault/wiki/sources/gsd-codecentric-deep-dive.md +0 -57
  468. package/vault/wiki/sources/gsd-github-repo.md +0 -51
  469. package/vault/wiki/sources/gsd-hn-discussion.md +0 -59
  470. package/vault/wiki/sources/guido-python-design-philosophy.md +0 -56
  471. package/vault/wiki/sources/hejlsberg-7-learnings.md +0 -48
  472. package/vault/wiki/sources/ironclaw-drift-monitor.md +0 -80
  473. package/vault/wiki/sources/langsight-loop-detection.md +0 -80
  474. package/vault/wiki/sources/leanctx-website.md +0 -69
  475. package/vault/wiki/sources/lee2026-meta-harness.md +0 -59
  476. package/vault/wiki/sources/linux-kernel-coding-workflow.md +0 -50
  477. package/vault/wiki/sources/lou2026-autoharness.md +0 -53
  478. package/vault/wiki/sources/martin-fowler-harness-engineering.md +0 -73
  479. package/vault/wiki/sources/mcp-architecture-docs.md +0 -13
  480. package/vault/wiki/sources/meng2026-agent-harness-survey.md +0 -79
  481. package/vault/wiki/sources/mindstudio-four-agent-types.md +0 -68
  482. package/vault/wiki/sources/ms-chat-history-management.md +0 -13
  483. package/vault/wiki/sources/openai-prompt-guidance.md +0 -104
  484. package/vault/wiki/sources/openclaw-session-pruning.md +0 -13
  485. package/vault/wiki/sources/opencode-dcp.md +0 -13
  486. package/vault/wiki/sources/opendev-arxiv-2603.05344v1.md +0 -79
  487. package/vault/wiki/sources/openhands-platform.md +0 -39
  488. package/vault/wiki/sources/oss-guide-codebase-exploration.md +0 -53
  489. package/vault/wiki/sources/pi-compaction-extensions-ecosystem.md +0 -102
  490. package/vault/wiki/sources/pi-context-prune-github-repo.md +0 -38
  491. package/vault/wiki/sources/pi-mono-compaction-docs.md +0 -38
  492. package/vault/wiki/sources/pi-omni-compact-github-repo.md +0 -50
  493. package/vault/wiki/sources/pi-rtk-optimizer-github-repo.md +0 -45
  494. package/vault/wiki/sources/pi-vcc-github-repo.md +0 -69
  495. package/vault/wiki/sources/pi-vscode-marketplace.md +0 -41
  496. package/vault/wiki/sources/pi-vscode-model-provider-marketplace.md +0 -39
  497. package/vault/wiki/sources/py-tree-sitter.md +0 -13
  498. package/vault/wiki/sources/sentrux-dev-landing.md +0 -40
  499. package/vault/wiki/sources/sentrux-docs-pro-architecture.md +0 -75
  500. package/vault/wiki/sources/sentrux-docs-quality-signal.md +0 -46
  501. package/vault/wiki/sources/sentrux-docs-root-cause-metrics.md +0 -57
  502. package/vault/wiki/sources/sentrux-docs-rules-engine.md +0 -58
  503. package/vault/wiki/sources/sentrux-github-repo.md +0 -56
  504. package/vault/wiki/sources/superpowers-github-repo.md +0 -56
  505. package/vault/wiki/sources/superpowers-release-blog.md +0 -54
  506. package/vault/wiki/sources/superpowers-termdock-analysis.md +0 -45
  507. package/vault/wiki/sources/swe-agent-aci.md +0 -42
  508. package/vault/wiki/sources/swe-bench.md +0 -45
  509. package/vault/wiki/sources/swe-pruner-context-pruning.md +0 -13
  510. package/vault/wiki/sources/think-in-code-blog.md +0 -48
  511. package/vault/wiki/sources/tree-sitter-docs.md +0 -13
  512. package/vault/wiki/sources/ts-best-practices-2025-devto.md +0 -42
  513. package/vault/wiki/sources/ts-folder-structure-mingyang.md +0 -58
  514. package/vault/wiki/sources/ts-monorepo-koerselman.md +0 -44
  515. package/vault/wiki/sources/ts-result-error-handling-kkalamarski.md +0 -52
  516. package/vault/wiki/sources/ts-runtimes-comparison-betterstack.md +0 -42
  517. package/vault/wiki/sources/ts-strict-mode-rishikc.md +0 -43
  518. package/vault/wiki/sources/unix-philosophy.md +0 -48
  519. package/vault/wiki/sources/vectara-chunking-vs-embedding-naacl2025.md +0 -39
  520. package/vault/wiki/sources/vectara-guardian-agents.md +0 -79
  521. package/vault/wiki/sources/vgrep-semantic-search.md +0 -76
  522. package/vault/wiki/sources/vitest-official.md +0 -41
  523. package/vault/wiki/sources/vscode-pi-community-extension.md +0 -40
  524. package/vault/wiki/sources/wozcode.md +0 -79
@@ -0,0 +1,322 @@
1
+ import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
2
+ import { convertToLlm } from "@mariozechner/pi-coding-agent";
3
+ import { writeFileSync } from "fs";
4
+ import { compile } from "../core/summarize";
5
+ import { loadSettings, type PiVccSettings } from "../core/settings";
6
+ import type { PiVccCompactionDetails } from "../details";
7
+
8
+ export const PI_VCC_COMPACT_INSTRUCTION = "__pi_vcc__";
9
+
10
+ export interface CompactionStats {
11
+ summarized: number;
12
+ kept: number;
13
+ keptTokensEst: number;
14
+ }
15
+
16
+ let lastStats: CompactionStats | null = null;
17
+ let lastCompactWasPiVcc = false;
18
+ export const getLastCompactionStats = () => lastStats;
19
+
20
+ const formatTokens = (n: number): string => {
21
+ if (n >= 1000) return `${(n / 1000).toFixed(1)}k`;
22
+ return String(n);
23
+ };
24
+
25
+ const dbg = (settings: PiVccSettings, data: Record<string, unknown>) => {
26
+ if (!settings.debug) return;
27
+ try { writeFileSync("/tmp/pi-vcc-debug.json", JSON.stringify(data, null, 2)); } catch {}
28
+ };
29
+
30
+ const previewContent = (content: unknown): string => {
31
+ if (typeof content === "string") return content.slice(0, 300);
32
+ if (Array.isArray(content)) {
33
+ return content
34
+ .map((c: any) => {
35
+ if (c?.type === "text") return c.text ?? "";
36
+ if (c?.type === "toolCall") return `[toolCall:${c.name}]`;
37
+ if (c?.type === "thinking") return `[thinking]`;
38
+ if (c?.type === "image") return `[image:${c.mimeType}]`;
39
+ return `[${c?.type ?? "unknown"}]`;
40
+ })
41
+ .join("\n")
42
+ .slice(0, 300);
43
+ }
44
+ return "";
45
+ };
46
+
47
+ interface EntryWithMessage {
48
+ entry: { id: string; type: string };
49
+ message: { role: string; content: unknown };
50
+ }
51
+
52
+ export type OwnCutCancelReason =
53
+ | "no_live_messages"
54
+ | "too_few_live_messages"
55
+ | "no_user_message";
56
+
57
+ export type OwnCutResult =
58
+ | { ok: true; messages: any[]; firstKeptEntryId: string; compactAll: boolean }
59
+ | { ok: false; reason: OwnCutCancelReason };
60
+
61
+ export function buildOwnCut(branchEntries: any[]): OwnCutResult {
62
+ // Find the last compaction entry and its firstKeptEntryId
63
+ let lastCompactionIdx = -1;
64
+ let lastKeptId: string | undefined;
65
+ for (let i = branchEntries.length - 1; i >= 0; i--) {
66
+ if (branchEntries[i].type === "compaction") {
67
+ lastCompactionIdx = i;
68
+ lastKeptId = branchEntries[i].firstKeptEntryId;
69
+ break;
70
+ }
71
+ }
72
+
73
+ // Orphan recovery: triggers when lastKeptId is set to "" (sentinel from prior
74
+ // compact-all) OR set to an id that no longer exists in the branch. In both cases,
75
+ // start collecting from right after the last compaction entry.
76
+ const hasPriorCompaction = lastCompactionIdx >= 0;
77
+ const hasValidKeptId = !!lastKeptId && branchEntries.some((e: any) => e.id === lastKeptId);
78
+ const orphanRecovery = hasPriorCompaction && !hasValidKeptId;
79
+
80
+ // Collect live messages
81
+ const liveMessages: EntryWithMessage[] = [];
82
+ if (orphanRecovery) {
83
+ for (let i = lastCompactionIdx + 1; i < branchEntries.length; i++) {
84
+ const e = branchEntries[i];
85
+ if (e.type === "compaction") continue;
86
+ if (e.type === "message" && e.message) {
87
+ liveMessages.push({ entry: e, message: e.message });
88
+ }
89
+ }
90
+ } else {
91
+ let foundKept = !lastKeptId; // if no prior compaction, start collecting immediately
92
+ for (const e of branchEntries) {
93
+ if (!foundKept && e.id === lastKeptId) foundKept = true;
94
+ if (!foundKept) continue;
95
+ if (e.type === "compaction") continue;
96
+ if (e.type === "message" && e.message) {
97
+ liveMessages.push({ entry: e, message: e.message });
98
+ }
99
+ }
100
+ }
101
+
102
+ if (liveMessages.length === 0) return { ok: false, reason: "no_live_messages" };
103
+ if (liveMessages.length <= 2) return { ok: false, reason: "too_few_live_messages" };
104
+
105
+ // Summarize all messages, keep only the last user message as context
106
+ let cutIdx = liveMessages.length - 1;
107
+ while (cutIdx > 0 && liveMessages[cutIdx].message.role !== "user") {
108
+ cutIdx--;
109
+ }
110
+
111
+ if (cutIdx <= 0) {
112
+ // Single user prompt scenario (or no user at all).
113
+ // If there's at least one user message, compact EVERYTHING and keep no tail.
114
+ // firstKeptEntryId="" is a sentinel: pi-core's buildSessionContext won't match it
115
+ // (so 0 kept from pre-compaction), and next buildOwnCut triggers orphan recovery.
116
+ const hasUser = liveMessages.some((m) => m.message.role === "user");
117
+ if (!hasUser) return { ok: false, reason: "no_user_message" };
118
+ return {
119
+ ok: true,
120
+ messages: liveMessages.map((e) => e.message),
121
+ firstKeptEntryId: "",
122
+ compactAll: true,
123
+ };
124
+ }
125
+
126
+ return {
127
+ ok: true,
128
+ messages: liveMessages.slice(0, cutIdx).map((e) => e.message),
129
+ firstKeptEntryId: liveMessages[cutIdx].entry.id,
130
+ compactAll: false,
131
+ };
132
+ }
133
+
134
+ const REASON_MESSAGES: Record<OwnCutCancelReason, string> = {
135
+ no_live_messages: "pi-vcc: Nothing to compact (no live messages)",
136
+ too_few_live_messages: "pi-vcc: Too few messages to compact",
137
+ no_user_message: "pi-vcc: Cannot compact — no user message found",
138
+ };
139
+
140
+ export const registerBeforeCompactHook = (pi: ExtensionAPI) => {
141
+ pi.on("session_before_compact", (event, ctx) => {
142
+ const { preparation, branchEntries, customInstructions } = event;
143
+ const settings = loadSettings();
144
+
145
+ // Always handle explicit /pi-vcc marker.
146
+ // Otherwise, only handle when user opted in via settings.
147
+ const isPiVcc = customInstructions === PI_VCC_COMPACT_INSTRUCTION;
148
+ if (!isPiVcc && !settings.overrideDefaultCompaction) return;
149
+
150
+ const ownCut = buildOwnCut(branchEntries as any[]);
151
+ if (!ownCut.ok) {
152
+ const lastComp = [...branchEntries].reverse().find((e: any) => e.type === "compaction");
153
+ const lastCompIdx = lastComp ? (branchEntries as any[]).indexOf(lastComp) : -1;
154
+
155
+ // Recompute liveMessages view (same logic as buildOwnCut) for diagnostic
156
+ const lastKeptId: string | undefined = lastComp?.firstKeptEntryId;
157
+ const hasPriorCompaction = lastCompIdx >= 0;
158
+ const hasValidKeptId = !!lastKeptId && (branchEntries as any[]).some((e: any) => e.id === lastKeptId);
159
+ const diagOrphan = hasPriorCompaction && !hasValidKeptId;
160
+ const liveRoles: string[] = [];
161
+ if (diagOrphan) {
162
+ for (let i = lastCompIdx + 1; i < branchEntries.length; i++) {
163
+ const e = (branchEntries as any[])[i];
164
+ if (e.type === "compaction") continue;
165
+ if (e.type === "message" && e.message) liveRoles.push(e.message.role);
166
+ }
167
+ } else {
168
+ let foundKept = !lastKeptId;
169
+ for (const e of branchEntries as any[]) {
170
+ if (!foundKept && e.id === lastKeptId) foundKept = true;
171
+ if (!foundKept) continue;
172
+ if (e.type === "compaction") continue;
173
+ if (e.type === "message" && e.message) liveRoles.push(e.message.role);
174
+ }
175
+ }
176
+ const userIndices = liveRoles.reduce<number[]>((acc, r, i) => (r === "user" ? (acc.push(i), acc) : acc), []);
177
+
178
+ dbg(settings, {
179
+ cancelled: true,
180
+ reason: ownCut.reason,
181
+ isPiVcc,
182
+ counts: {
183
+ total: branchEntries.length,
184
+ messages: (branchEntries as any[]).filter((e: any) => e.type === "message").length,
185
+ compactions: (branchEntries as any[]).filter((e: any) => e.type === "compaction").length,
186
+ entriesAfterLastCompaction: lastCompIdx >= 0 ? branchEntries.length - lastCompIdx - 1 : null,
187
+ },
188
+ liveMessages: {
189
+ count: liveRoles.length,
190
+ userCount: userIndices.length,
191
+ firstUserIdx: userIndices[0] ?? null,
192
+ lastUserIdx: userIndices[userIndices.length - 1] ?? null,
193
+ roleSequence: liveRoles.length <= 30
194
+ ? liveRoles
195
+ : [...liveRoles.slice(0, 10), "...", ...liveRoles.slice(-10)],
196
+ },
197
+ lastCompaction: lastComp ? {
198
+ hasFirstKeptEntryId: !!lastComp.firstKeptEntryId,
199
+ foundInBranch: lastComp.firstKeptEntryId
200
+ ? (branchEntries as any[]).some((e: any) => e.id === lastComp.firstKeptEntryId)
201
+ : null,
202
+ } : null,
203
+ tail: (branchEntries as any[]).slice(-5).map((e: any) => ({
204
+ type: e.type,
205
+ role: e.type === "message" ? e.message?.role : undefined,
206
+ hasContent: e.type === "message" ? e.message?.content != null : undefined,
207
+ })),
208
+ });
209
+
210
+ try {
211
+ ctx?.ui?.notify?.(REASON_MESSAGES[ownCut.reason], "warning");
212
+ } catch {}
213
+ return { cancel: true };
214
+ }
215
+
216
+ const agentMessages = ownCut.messages;
217
+ const firstKeptEntryId = ownCut.firstKeptEntryId;
218
+ const messages = convertToLlm(agentMessages);
219
+
220
+ // Count kept messages and estimate tokens
221
+ const keptIdx = (branchEntries as any[]).findIndex((e: any) => e.id === firstKeptEntryId);
222
+ const keptEntries = keptIdx >= 0
223
+ ? (branchEntries as any[]).slice(keptIdx).filter((e: any) => e.type === "message")
224
+ : [];
225
+ const keptChars = keptEntries.reduce((sum: number, e: any) => {
226
+ const c = e.message?.content;
227
+ if (typeof c === "string") return sum + c.length;
228
+ if (Array.isArray(c)) return sum + c.reduce((s: number, p: any) => {
229
+ if (p.text) return s + p.text.length;
230
+ if (p.type === "toolCall") return s + (p.name?.length ?? 0) + (typeof p.input === "string" ? p.input.length : JSON.stringify(p.input ?? "").length);
231
+ if (p.type === "toolResult") return s + (typeof p.content === "string" ? p.content.length : JSON.stringify(p.content ?? "").length);
232
+ return s;
233
+ }, 0);
234
+ return sum;
235
+ }, 0);
236
+ lastStats = {
237
+ summarized: agentMessages.length,
238
+ kept: keptEntries.length,
239
+ keptTokensEst: Math.round(keptChars / 4),
240
+ };
241
+
242
+ const config = settings;
243
+
244
+ const summary = compile({
245
+ messages,
246
+ previousSummary: preparation.previousSummary,
247
+ fileOps: {
248
+ readFiles: [...preparation.fileOps.read],
249
+ modifiedFiles: [...preparation.fileOps.written, ...preparation.fileOps.edited],
250
+ },
251
+ });
252
+
253
+ const branchIds = branchEntries.map((e: any) => e.id);
254
+ const cutIdx = branchIds.indexOf(firstKeptEntryId);
255
+ const cutWindow = cutIdx >= 0
256
+ ? branchEntries.slice(Math.max(0, cutIdx - 3), Math.min(branchEntries.length, cutIdx + 3)).map((e: any) => ({
257
+ id: e.id,
258
+ type: e.type,
259
+ role: e.type === "message" ? e.message?.role : undefined,
260
+ preview: e.type === "message" ? previewContent(e.message?.content) : undefined,
261
+ }))
262
+ : [];
263
+
264
+ dbg(config, {
265
+ usedOwnCut: true,
266
+ messagesToSummarize: agentMessages.length,
267
+ messagesPreviewHead: agentMessages.slice(0, 3).map((m: any) => ({ role: m.role, preview: previewContent(m.content) })),
268
+ messagesPreviewTail: agentMessages.slice(-3).map((m: any) => ({ role: m.role, preview: previewContent(m.content) })),
269
+ convertedMessages: messages.length,
270
+ firstKeptEntryId,
271
+ cutWindow,
272
+ tokensBefore: preparation.tokensBefore,
273
+ summaryLength: summary.length,
274
+ summaryPreview: summary.slice(0, 500),
275
+ sections: [...summary.matchAll(/^\[(.+?)\]/gm)].map((m) => m[1]),
276
+ });
277
+
278
+ const details: PiVccCompactionDetails = {
279
+ compactor: "pi-vcc",
280
+ version: 1,
281
+ sections: [...summary.matchAll(/^\[(.+?)\]/gm)].map((m) => m[1]),
282
+ sourceMessageCount: agentMessages.length,
283
+ previousSummaryUsed: Boolean(preparation.previousSummary),
284
+ };
285
+
286
+ lastCompactWasPiVcc = isPiVcc;
287
+
288
+ // Auto-compaction continuation fix: when pi-vcc handles auto-compaction
289
+ // (not manual /pi-vcc), the LLM may stop after session reload because the
290
+ // kept tail can look like a completed turn. Append a continuation directive
291
+ // to ensure the model keeps working.
292
+ const finalSummary = isPiVcc
293
+ ? summary
294
+ : summary + "\n\n[Continue]\nContinue working on the current task. The user's request is not yet complete. Use vcc_recall if you need context from earlier in the session.";
295
+
296
+ return {
297
+ compaction: {
298
+ summary: finalSummary,
299
+ details,
300
+ tokensBefore: preparation.tokensBefore,
301
+ firstKeptEntryId,
302
+ },
303
+ };
304
+ });
305
+
306
+ // Fire success toast for /compact path only (delayed to let UI settle).
307
+ // /pi-vcc path uses its own onComplete callback in the command handler.
308
+ pi.on("session_compact", (event, ctx) => {
309
+ if (!event.fromExtension) return;
310
+ if (lastCompactWasPiVcc) return; // /pi-vcc handles its own toast via onComplete
311
+ const stats = lastStats;
312
+ if (!stats) return;
313
+ setTimeout(() => {
314
+ try {
315
+ ctx?.ui?.notify?.(
316
+ `pi-vcc: ${stats.summarized} source entries processed; tail kept ${stats.kept} (~${formatTokens(stats.keptTokensEst)} tok).`,
317
+ "info",
318
+ );
319
+ } catch {}
320
+ }, 500);
321
+ });
322
+ };
@@ -0,0 +1,12 @@
1
+ import type { TranscriptEntry } from "./core/brief";
2
+
3
+ export interface SectionData {
4
+ sessionGoal: string[];
5
+ outstandingContext: string[];
6
+ filesAndChanges: string[];
7
+ commits: string[];
8
+ userPreferences: string[];
9
+ briefTranscript: string;
10
+ /** Structured transcript entries (verbose object format) */
11
+ transcriptEntries: TranscriptEntry[];
12
+ }
@@ -0,0 +1,109 @@
1
+ import { Type } from "@sinclair/typebox";
2
+ import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
3
+ import { loadAllMessages } from "../core/load-messages";
4
+ import { searchEntries } from "../core/search-entries";
5
+ import { formatRecallOutput } from "../core/format-recall";
6
+ import { getActiveLineageEntryIds } from "../core/lineage";
7
+ import { normalizeRecallScope } from "../core/recall-scope";
8
+
9
+ const DEFAULT_RECENT = 25;
10
+ const PAGE_SIZE = 5;
11
+
12
+ export const invalidExpandIndices = (requested: number[], available: Set<number>): number[] =>
13
+ requested.filter((i) => !Number.isInteger(i) || !available.has(i));
14
+
15
+ export const registerRecallTool = (pi: ExtensionAPI) => {
16
+ pi.registerTool({
17
+ name: "vcc_recall",
18
+ label: "VCC Recall",
19
+ description:
20
+ "Search session history. Defaults to active lineage; use scope:'all' to include off-lineage branches." +
21
+ " Supports regex queries, paging, and expand indices.",
22
+ promptSnippet:
23
+ "vcc_recall: Search history; default scope is active lineage. Use scope:'all' for off-lineage branches.",
24
+ parameters: Type.Object({
25
+ query: Type.Optional(
26
+ Type.String({ description: "Search terms or regex pattern (e.g. 'hook|inject', 'fail.*build'). Multi-word = OR ranked by relevance." }),
27
+ ),
28
+ expand: Type.Optional(
29
+ Type.Array(Type.Number(), { description: "Entry indices to return full untruncated content for" }),
30
+ ),
31
+ page: Type.Optional(
32
+ Type.Number({ description: "Page number (1-based) for paginated search results. Default: 1." }),
33
+ ),
34
+ scope: Type.Optional(
35
+ Type.Union([
36
+ Type.Literal("lineage"),
37
+ Type.Literal("all"),
38
+ ], { description: "Search scope. Default: lineage; all includes off-lineage branches." }),
39
+ ),
40
+ }),
41
+ async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
42
+ const sessionFile = ctx.sessionManager.getSessionFile();
43
+ if (!sessionFile) {
44
+ return {
45
+ content: [{ type: "text", text: "No session file available." }],
46
+ details: undefined,
47
+ };
48
+ }
49
+
50
+ const scope = normalizeRecallScope(params.scope);
51
+ const lineageEntryIds = scope === "lineage"
52
+ ? getActiveLineageEntryIds(ctx.sessionManager)
53
+ : undefined;
54
+ const expandSet = new Set(params.expand ?? []);
55
+ const hasExpand = expandSet.size > 0;
56
+
57
+ if (hasExpand && !params.query) {
58
+ const { rendered: fullMsgs } = loadAllMessages(sessionFile, true, lineageEntryIds);
59
+ const requested = [...expandSet];
60
+ const byIndex = new Map(fullMsgs.map((m) => [m.index, m]));
61
+ const invalid = invalidExpandIndices(requested, new Set(byIndex.keys()));
62
+ if (invalid.length > 0) {
63
+ return {
64
+ content: [{ type: "text", text: `Cannot expand indices outside ${scope === "all" ? "session history" : "active lineage"}: ${invalid.join(", ")}` }],
65
+ details: undefined,
66
+ };
67
+ }
68
+
69
+ const expanded = requested.map((i) => byIndex.get(i)).filter((m): m is NonNullable<typeof m> => Boolean(m));
70
+ const output = (scope === "all" ? "Scope: all\n\n" : "") + formatRecallOutput(expanded);
71
+ return {
72
+ content: [{ type: "text", text: output }],
73
+ details: undefined,
74
+ };
75
+ }
76
+
77
+ const { rendered: msgs, rawMessages } = loadAllMessages(sessionFile, false, lineageEntryIds);
78
+ const allResults = params.query?.trim()
79
+ ? searchEntries(msgs, rawMessages, params.query)
80
+ : msgs.slice(-DEFAULT_RECENT);
81
+
82
+ if (params.query?.trim()) {
83
+ const page = Math.max(1, params.page ?? 1);
84
+ const start = (page - 1) * PAGE_SIZE;
85
+ const pageResults = allResults.slice(start, start + PAGE_SIZE);
86
+ const totalPages = Math.ceil(allResults.length / PAGE_SIZE);
87
+ const scopeSuffix = scope === "all" ? " (scope: all)" : "";
88
+ const header = totalPages > 1
89
+ ? `Page ${page}/${totalPages} (${allResults.length} total matches${scopeSuffix})`
90
+ : `${allResults.length} matches${scopeSuffix}`;
91
+ const footer = page < totalPages
92
+ ? `\n--- Use page:${page + 1}${scope === "all" ? " with scope:'all'" : ""} for more results ---`
93
+ : "";
94
+ const output = formatRecallOutput(pageResults, params.query, header) + footer;
95
+ return {
96
+ content: [{ type: "text", text: output }],
97
+ details: undefined,
98
+ };
99
+ }
100
+
101
+ const output = (scope === "all" ? "Scope: all\n\n" : "") + formatRecallOutput(allResults, params.query);
102
+ return {
103
+ content: [{ type: "text", text: output }],
104
+ details: undefined,
105
+ };
106
+ },
107
+ });
108
+ };
109
+
@@ -0,0 +1,14 @@
1
+ import type { Message } from "@mariozechner/pi-ai";
2
+
3
+ export interface FileOps {
4
+ readFiles?: string[];
5
+ modifiedFiles?: string[];
6
+ createdFiles?: string[];
7
+ }
8
+
9
+ export type NormalizedBlock =
10
+ | { kind: "user"; text: string; sourceIndex?: number }
11
+ | { kind: "assistant"; text: string; sourceIndex?: number }
12
+ | { kind: "tool_call"; name: string; args: Record<string, unknown>; sourceIndex?: number }
13
+ | { kind: "tool_result"; name: string; text: string; isError: boolean; sourceIndex?: number }
14
+ | { kind: "thinking"; text: string; redacted: boolean; sourceIndex?: number };
@@ -0,0 +1,181 @@
1
+ import { describe, test, expect, beforeEach, afterEach, beforeAll, afterAll } from "bun:test";
2
+ import { existsSync, unlinkSync, writeFileSync, readFileSync, mkdtempSync, rmSync } from "fs";
3
+ import { tmpdir } from "os";
4
+ import { join } from "path";
5
+ import { registerBeforeCompactHook, PI_VCC_COMPACT_INSTRUCTION } from "../src/hooks/before-compact";
6
+
7
+ let tmpDir: string;
8
+ let CONFIG_PATH: string;
9
+ const DEBUG_PATH = "/tmp/pi-vcc-debug.json";
10
+
11
+ beforeAll(() => {
12
+ tmpDir = mkdtempSync(join(tmpdir(), "pi-vcc-test-"));
13
+ CONFIG_PATH = join(tmpDir, "pi-vcc-config.json");
14
+ process.env.PI_VCC_CONFIG_PATH = CONFIG_PATH;
15
+ });
16
+
17
+ afterAll(() => {
18
+ delete process.env.PI_VCC_CONFIG_PATH;
19
+ rmSync(tmpDir, { recursive: true, force: true });
20
+ });
21
+
22
+ // Minimal ExtensionAPI stub: capture handler + provide ctx with mocked ui.notify
23
+ function createMockPi() {
24
+ let handler: ((event: any, ctx: any) => any) | undefined;
25
+ const notifyCalls: Array<{ msg: string; level: string }> = [];
26
+ const ctx = {
27
+ hasUI: true,
28
+ ui: {
29
+ notify: (msg: string, level: string) => {
30
+ notifyCalls.push({ msg, level });
31
+ },
32
+ },
33
+ };
34
+ return {
35
+ pi: {
36
+ on: (eventName: string, h: (e: any, c: any) => any) => {
37
+ if (eventName === "session_before_compact") handler = h;
38
+ },
39
+ } as any,
40
+ invoke: (event: any) => handler!(event, ctx),
41
+ notifyCalls,
42
+ };
43
+ }
44
+
45
+ function setConfig(cfg: Record<string, unknown>) {
46
+ writeFileSync(CONFIG_PATH, JSON.stringify(cfg));
47
+ }
48
+
49
+ function makeEvent(branchEntries: any[], customInstructions?: string) {
50
+ return {
51
+ type: "session_before_compact",
52
+ customInstructions,
53
+ branchEntries,
54
+ preparation: {
55
+ previousSummary: undefined,
56
+ fileOps: { read: [], written: [], edited: [] },
57
+ tokensBefore: 1000,
58
+ },
59
+ signal: new AbortController().signal,
60
+ };
61
+ }
62
+
63
+ const msg = (id: string, role: "user" | "assistant" | "toolResult", content = "x") => ({
64
+ id,
65
+ type: "message",
66
+ message: { role, content },
67
+ });
68
+ const comp = (id: string, firstKeptEntryId?: string) => ({ id, type: "compaction", firstKeptEntryId });
69
+
70
+ describe("registerBeforeCompactHook: cancel paths", () => {
71
+ beforeEach(() => {
72
+ if (existsSync(DEBUG_PATH)) unlinkSync(DEBUG_PATH);
73
+ });
74
+ afterEach(() => {
75
+ if (existsSync(CONFIG_PATH)) unlinkSync(CONFIG_PATH);
76
+ if (existsSync(DEBUG_PATH)) unlinkSync(DEBUG_PATH);
77
+ });
78
+
79
+ test("/pi-vcc with too few live messages cancels and notifies warning", () => {
80
+ setConfig({ debug: false, overrideDefaultCompaction: false });
81
+ const { pi, invoke, notifyCalls } = createMockPi();
82
+ registerBeforeCompactHook(pi);
83
+
84
+ const entries = [msg("m1", "user"), msg("m2", "assistant")];
85
+ expect(invoke(makeEvent(entries, PI_VCC_COMPACT_INSTRUCTION))).toEqual({ cancel: true });
86
+ expect(notifyCalls).toHaveLength(1);
87
+ expect(notifyCalls[0].level).toBe("warning");
88
+ expect(notifyCalls[0].msg).toContain("Too few messages");
89
+ });
90
+
91
+ test("/pi-vcc with no user message cancels with no_user_message reason", () => {
92
+ setConfig({ debug: false, overrideDefaultCompaction: false });
93
+ const { pi, invoke, notifyCalls } = createMockPi();
94
+ registerBeforeCompactHook(pi);
95
+
96
+ const entries = [msg("m1", "assistant"), msg("m2", "assistant"), msg("m3", "assistant")];
97
+ expect(invoke(makeEvent(entries, PI_VCC_COMPACT_INSTRUCTION))).toEqual({ cancel: true });
98
+ expect(notifyCalls[0].msg).toContain("no user message");
99
+ });
100
+
101
+ test("/compact with override=true cancels and notifies (NEW: was silent before)", () => {
102
+ setConfig({ debug: false, overrideDefaultCompaction: true });
103
+ const { pi, invoke, notifyCalls } = createMockPi();
104
+ registerBeforeCompactHook(pi);
105
+
106
+ const entries = [msg("m1", "user"), msg("m2", "assistant")];
107
+ expect(invoke(makeEvent(entries, undefined))).toEqual({ cancel: true });
108
+ expect(notifyCalls).toHaveLength(1);
109
+ expect(notifyCalls[0].level).toBe("warning");
110
+ });
111
+
112
+ test("/compact with override=false short-circuits (no notify, returns undefined)", () => {
113
+ setConfig({ debug: false, overrideDefaultCompaction: false });
114
+ const { pi, invoke, notifyCalls } = createMockPi();
115
+ registerBeforeCompactHook(pi);
116
+
117
+ const entries = [msg("m1", "user"), msg("m2", "assistant")];
118
+ expect(invoke(makeEvent(entries, undefined))).toBeUndefined();
119
+ expect(notifyCalls).toHaveLength(0);
120
+ });
121
+
122
+ test("debug:true writes metrics-only snapshot with no content leakage", () => {
123
+ setConfig({ debug: true, overrideDefaultCompaction: false });
124
+ const { pi, invoke } = createMockPi();
125
+ registerBeforeCompactHook(pi);
126
+
127
+ const entries = [
128
+ msg("m1", "assistant", "SECRET_TOKEN_abc123"),
129
+ msg("m2", "assistant", "sensitive response"),
130
+ msg("m3", "assistant", "more text"),
131
+ ];
132
+ expect(invoke(makeEvent(entries, PI_VCC_COMPACT_INSTRUCTION))).toEqual({ cancel: true });
133
+
134
+ expect(existsSync(DEBUG_PATH)).toBe(true);
135
+ const snapshot = JSON.parse(readFileSync(DEBUG_PATH, "utf-8"));
136
+ expect(snapshot.cancelled).toBe(true);
137
+ expect(snapshot.reason).toBe("no_user_message");
138
+ expect(snapshot.isPiVcc).toBe(true);
139
+
140
+ // No content leakage
141
+ const serialized = JSON.stringify(snapshot);
142
+ expect(serialized).not.toContain("SECRET_TOKEN_abc123");
143
+ expect(serialized).not.toContain("sensitive response");
144
+ });
145
+
146
+ test("debug:false does NOT write snapshot", () => {
147
+ setConfig({ debug: false, overrideDefaultCompaction: false });
148
+ const { pi, invoke } = createMockPi();
149
+ registerBeforeCompactHook(pi);
150
+ const entries = [msg("m1", "user"), msg("m2", "assistant")];
151
+ expect(invoke(makeEvent(entries, PI_VCC_COMPACT_INSTRUCTION))).toEqual({ cancel: true });
152
+ expect(existsSync(DEBUG_PATH)).toBe(false);
153
+ });
154
+ });
155
+
156
+ describe("registerBeforeCompactHook: compact-all path", () => {
157
+ beforeEach(() => {
158
+ if (existsSync(DEBUG_PATH)) unlinkSync(DEBUG_PATH);
159
+ });
160
+ afterEach(() => {
161
+ if (existsSync(CONFIG_PATH)) unlinkSync(CONFIG_PATH);
162
+ if (existsSync(DEBUG_PATH)) unlinkSync(DEBUG_PATH);
163
+ });
164
+
165
+ test("single-user + autonomous tail → returns compaction with empty firstKeptEntryId", () => {
166
+ setConfig({ debug: false, overrideDefaultCompaction: false });
167
+ const { pi, invoke, notifyCalls } = createMockPi();
168
+ registerBeforeCompactHook(pi);
169
+
170
+ const entries = [
171
+ msg("m1", "user", "go"),
172
+ msg("m2", "assistant", "calling tool"),
173
+ msg("m3", "toolResult", "result"),
174
+ msg("m4", "assistant", "done"),
175
+ ];
176
+ const result = invoke(makeEvent(entries, PI_VCC_COMPACT_INSTRUCTION));
177
+ expect(result.compaction).toBeDefined();
178
+ expect(result.compaction.firstKeptEntryId).toBe("");
179
+ expect(notifyCalls).toHaveLength(0); // no cancel notify on success
180
+ });
181
+ });