ultimate-pi 0.1.2 → 0.1.4

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 (516) hide show
  1. package/.agents/skills/ck-search/SKILL.md +99 -0
  2. package/.agents/skills/defuddle/SKILL.md +90 -0
  3. package/.agents/skills/find-skills/SKILL.md +142 -0
  4. package/.agents/skills/firecrawl/SKILL.md +150 -0
  5. package/.agents/skills/firecrawl/rules/install.md +82 -0
  6. package/.agents/skills/firecrawl/rules/security.md +26 -0
  7. package/.agents/skills/firecrawl-agent/SKILL.md +57 -0
  8. package/.agents/skills/firecrawl-build-interact/SKILL.md +67 -0
  9. package/.agents/skills/firecrawl-build-onboarding/SKILL.md +102 -0
  10. package/.agents/skills/firecrawl-build-onboarding/references/auth-flow.md +39 -0
  11. package/.agents/skills/firecrawl-build-onboarding/references/project-setup.md +20 -0
  12. package/.agents/skills/firecrawl-build-onboarding/references/sdk-installation.md +17 -0
  13. package/.agents/skills/firecrawl-build-scrape/SKILL.md +68 -0
  14. package/.agents/skills/firecrawl-build-search/SKILL.md +68 -0
  15. package/.agents/skills/firecrawl-crawl/SKILL.md +58 -0
  16. package/.agents/skills/firecrawl-download/SKILL.md +69 -0
  17. package/.agents/skills/firecrawl-interact/SKILL.md +83 -0
  18. package/.agents/skills/firecrawl-map/SKILL.md +50 -0
  19. package/.agents/skills/firecrawl-parse/SKILL.md +61 -0
  20. package/.agents/skills/firecrawl-scrape/SKILL.md +68 -0
  21. package/.agents/skills/firecrawl-search/SKILL.md +59 -0
  22. package/.agents/skills/obsidian-bases/SKILL.md +299 -0
  23. package/.agents/skills/obsidian-markdown/SKILL.md +237 -0
  24. package/.agents/skills/posthog-analyst/SKILL.md +306 -0
  25. package/.agents/skills/posthog-analyst/evals/evals.json +23 -0
  26. package/.agents/skills/wiki/SKILL.md +215 -0
  27. package/.agents/skills/wiki/references/css-snippets.md +122 -0
  28. package/.agents/skills/wiki/references/frontmatter.md +107 -0
  29. package/.agents/skills/wiki/references/git-setup.md +58 -0
  30. package/.agents/skills/wiki/references/mcp-setup.md +149 -0
  31. package/.agents/skills/wiki/references/modes.md +259 -0
  32. package/.agents/skills/wiki/references/plugins.md +96 -0
  33. package/.agents/skills/wiki/references/rest-api.md +124 -0
  34. package/.agents/skills/wiki-autoresearch/SKILL.md +211 -0
  35. package/.agents/skills/wiki-autoresearch/references/program.md +75 -0
  36. package/.agents/skills/wiki-fold/SKILL.md +204 -0
  37. package/.agents/skills/wiki-fold/references/fold-template.md +133 -0
  38. package/.agents/skills/wiki-ingest/SKILL.md +288 -0
  39. package/.agents/skills/wiki-lint/SKILL.md +183 -0
  40. package/.agents/skills/wiki-query/SKILL.md +176 -0
  41. package/.agents/skills/wiki-save/SKILL.md +128 -0
  42. package/.ckignore +41 -0
  43. package/.env.example +9 -0
  44. package/.github/workflows/lint.yml +33 -0
  45. package/.github/workflows/publish-github-packages.yml +35 -0
  46. package/.github/workflows/publish-npm.yml +1 -1
  47. package/.pi/SYSTEM.md +107 -40
  48. package/.pi/agents/pi-pi/agent-expert.md +205 -0
  49. package/.pi/agents/pi-pi/cli-expert.md +47 -0
  50. package/.pi/agents/pi-pi/config-expert.md +67 -0
  51. package/.pi/agents/pi-pi/ext-expert.md +53 -0
  52. package/.pi/agents/pi-pi/keybinding-expert.md +123 -0
  53. package/.pi/agents/pi-pi/pi-orchestrator.md +103 -0
  54. package/.pi/agents/pi-pi/prompt-expert.md +83 -0
  55. package/.pi/agents/pi-pi/skill-expert.md +52 -0
  56. package/.pi/agents/pi-pi/theme-expert.md +46 -0
  57. package/.pi/agents/pi-pi/tui-expert.md +100 -0
  58. package/.pi/agents/rethink.md +140 -0
  59. package/.pi/agents/wiki-ingest.md +67 -0
  60. package/.pi/agents/wiki-lint.md +75 -0
  61. package/.pi/auto-commit.json +20 -0
  62. package/.pi/extensions/banner.png +0 -0
  63. package/.pi/extensions/ck-enforce.ts +216 -0
  64. package/.pi/extensions/custom-footer.ts +308 -0
  65. package/.pi/extensions/custom-header.ts +116 -0
  66. package/.pi/extensions/dotenv-loader.ts +170 -0
  67. package/.pi/internal/cursor-sdk-transcript-parser.ts +59 -0
  68. package/.pi/model-router.json +95 -0
  69. package/.pi/npm/.gitignore +2 -0
  70. package/.pi/prompts/git-sync.md +124 -0
  71. package/.pi/prompts/harness-setup.md +509 -0
  72. package/.pi/prompts/save.md +16 -0
  73. package/.pi/prompts/wiki-autoresearch.md +19 -0
  74. package/.pi/prompts/wiki.md +23 -0
  75. package/.pi/providers/cursor-sdk-provider.test.mjs +476 -0
  76. package/.pi/providers/cursor-sdk-provider.ts +1085 -0
  77. package/.pi/settings.json +14 -4
  78. package/.pi/skills/agent-router/SKILL.md +174 -0
  79. package/.pi/sounds/alert/1-kaching-track.mp3 +0 -0
  80. package/.pi/sounds/error/1-ksi-wth-track.mp3 +0 -0
  81. package/.pi/sounds/error/2-smash-track.mp3 +0 -0
  82. package/.pi/sounds/error/3-buzzer-track.mp3 +0 -0
  83. package/.pi/sounds/notification/1-soft-notification-track.mp3 +0 -0
  84. package/.pi/sounds/project-sounds.json +25 -0
  85. package/.pi/sounds/reminder/1-soft-notification-track.mp3 +0 -0
  86. package/.pi/sounds/success/1-tada-track.mp3 +0 -0
  87. package/.pi/sounds/success/2-jobs-done-track.mp3 +0 -0
  88. package/.pi/sounds/success/3-yay-track.mp3 +0 -0
  89. package/CONTRIBUTING.md +116 -0
  90. package/README.md +32 -39
  91. package/biome.json +34 -0
  92. package/firecrawl/.env.template +58 -0
  93. package/firecrawl/README.md +49 -0
  94. package/firecrawl/docker-compose.yaml +201 -0
  95. package/firecrawl/searxng/searxng.env +3 -0
  96. package/firecrawl/searxng/settings.yml +85 -0
  97. package/lefthook.yml +8 -0
  98. package/package.json +55 -24
  99. package/vault/AGENTS.md +37 -0
  100. package/vault/wiki/_templates/comparison.md +39 -0
  101. package/vault/wiki/_templates/concept.md +40 -0
  102. package/vault/wiki/_templates/decision.md +21 -0
  103. package/vault/wiki/_templates/entity.md +32 -0
  104. package/vault/wiki/_templates/flow.md +14 -0
  105. package/vault/wiki/_templates/module.md +18 -0
  106. package/vault/wiki/_templates/question.md +31 -0
  107. package/vault/wiki/_templates/source.md +39 -0
  108. package/vault/wiki/concepts/AST-Aware Code Chunking.md +44 -0
  109. package/vault/wiki/concepts/Build-Time Prompt Compilation.md +107 -0
  110. package/vault/wiki/concepts/Context Engine (AI Coding).md +47 -0
  111. package/vault/wiki/concepts/Context-Aware System Reminders.md +61 -0
  112. package/vault/wiki/concepts/Contextualized Text Embedding.md +42 -0
  113. package/vault/wiki/concepts/Contractor vs Employee AI Model.md +55 -0
  114. package/vault/wiki/concepts/Dual-Model Agent Architecture.md +65 -0
  115. package/vault/wiki/concepts/Late Chunking vs Early Chunking.md +43 -0
  116. package/vault/wiki/concepts/Majority Vote Ensembling.md +68 -0
  117. package/vault/wiki/concepts/Meta-Harness.md +16 -0
  118. package/vault/wiki/concepts/Multi-Agent AI Coding Architecture.md +75 -0
  119. package/vault/wiki/concepts/Prompt Enhancement.md +90 -0
  120. package/vault/wiki/concepts/Prompt Renderer.md +89 -0
  121. package/vault/wiki/concepts/Semantic Codebase Indexing.md +67 -0
  122. package/vault/wiki/concepts/additive-config-hierarchy.md +16 -0
  123. package/vault/wiki/concepts/agent-artifacts-verifiable-deliverables.md +71 -0
  124. package/vault/wiki/concepts/agent-browser-browser-automation.md +99 -0
  125. package/vault/wiki/concepts/agent-codebase-interface.md +43 -0
  126. package/vault/wiki/concepts/agent-harness-architecture.md +67 -0
  127. package/vault/wiki/concepts/agent-loop-detection-patterns.md +133 -0
  128. package/vault/wiki/concepts/agent-search-enforcement.md +126 -0
  129. package/vault/wiki/concepts/agent-skills-ecosystem.md +74 -0
  130. package/vault/wiki/concepts/agent-skills-pattern.md +68 -0
  131. package/vault/wiki/concepts/agentic-harness-context-enforcement.md +91 -0
  132. package/vault/wiki/concepts/agentic-harness.md +34 -0
  133. package/vault/wiki/concepts/agentic-orchestration-pipeline.md +56 -0
  134. package/vault/wiki/concepts/agentic-search-no-embeddings.md +18 -0
  135. package/vault/wiki/concepts/anthropic-context-engineering.md +13 -0
  136. package/vault/wiki/concepts/antigravity-agent-first-architecture.md +61 -0
  137. package/vault/wiki/concepts/ast-compression.md +19 -0
  138. package/vault/wiki/concepts/ast-truncation.md +66 -0
  139. package/vault/wiki/concepts/barrel-files.md +37 -0
  140. package/vault/wiki/concepts/browser-harness-agent.md +41 -0
  141. package/vault/wiki/concepts/browser-subagent-visual-verification.md +82 -0
  142. package/vault/wiki/concepts/codebase-intelligence-ecosystem-comparison.md +192 -0
  143. package/vault/wiki/concepts/codebase-intelligence-harness-integration.md +161 -0
  144. package/vault/wiki/concepts/codebase-to-context-ingestion.md +46 -0
  145. package/vault/wiki/concepts/codex-harness-innovations.md +147 -0
  146. package/vault/wiki/concepts/consensus-debate-flow.md +17 -0
  147. package/vault/wiki/concepts/consensus-debate.md +206 -0
  148. package/vault/wiki/concepts/content-addressed-spec-identity.md +166 -0
  149. package/vault/wiki/concepts/context-anxiety.md +57 -0
  150. package/vault/wiki/concepts/context-compression-techniques.md +19 -0
  151. package/vault/wiki/concepts/context-continuity.md +22 -0
  152. package/vault/wiki/concepts/context-drift-in-agents.md +106 -0
  153. package/vault/wiki/concepts/context-engineering.md +62 -0
  154. package/vault/wiki/concepts/context-folding.md +67 -0
  155. package/vault/wiki/concepts/context-mode.md +38 -0
  156. package/vault/wiki/concepts/cursor-harness-innovations.md +107 -0
  157. package/vault/wiki/concepts/deterministic-session-compaction.md +79 -0
  158. package/vault/wiki/concepts/drift-detection-unified.md +296 -0
  159. package/vault/wiki/concepts/execution-feedback-loop.md +46 -0
  160. package/vault/wiki/concepts/feedforward-feedback-harness.md +60 -0
  161. package/vault/wiki/concepts/five-root-cause-metrics-sentrux.md +40 -0
  162. package/vault/wiki/concepts/fork-safe-spec-storage.md +89 -0
  163. package/vault/wiki/concepts/fts5-sandbox.md +19 -0
  164. package/vault/wiki/concepts/fuzzy-edit-matching.md +71 -0
  165. package/vault/wiki/concepts/gemini-cli-architecture.md +104 -0
  166. package/vault/wiki/concepts/generator-evaluator-architecture.md +64 -0
  167. package/vault/wiki/concepts/guardian-agent-pattern.md +67 -0
  168. package/vault/wiki/concepts/harness-configuration-layers.md +89 -0
  169. package/vault/wiki/concepts/harness-control-frameworks.md +155 -0
  170. package/vault/wiki/concepts/harness-engineering-first-principles.md +90 -0
  171. package/vault/wiki/concepts/harness-h-formalism.md +53 -0
  172. package/vault/wiki/concepts/hybrid-code-search.md +61 -0
  173. package/vault/wiki/concepts/inline-post-edit-validation.md +112 -0
  174. package/vault/wiki/concepts/legendary-engineering-patterns-harness.md +110 -0
  175. package/vault/wiki/concepts/lifecycle-hooks.md +94 -0
  176. package/vault/wiki/concepts/mcp-tool-routing.md +102 -0
  177. package/vault/wiki/concepts/memory-system-of-record-vs-ephemeral-cache.md +47 -0
  178. package/vault/wiki/concepts/meta-agent-context-pruning.md +151 -0
  179. package/vault/wiki/concepts/model-adaptive-harness.md +122 -0
  180. package/vault/wiki/concepts/model-routing-agents.md +101 -0
  181. package/vault/wiki/concepts/monorepo-architecture.md +45 -0
  182. package/vault/wiki/concepts/multi-agent-specialization.md +61 -0
  183. package/vault/wiki/concepts/permission-subsystem.md +16 -0
  184. package/vault/wiki/concepts/pi-messenger-analysis.md +243 -0
  185. package/vault/wiki/concepts/pi-vscode-extension-landscape.md +37 -0
  186. package/vault/wiki/concepts/policy-engine-pattern.md +78 -0
  187. package/vault/wiki/concepts/progressive-disclosure-agents.md +53 -0
  188. package/vault/wiki/concepts/progressive-skill-disclosure.md +17 -0
  189. package/vault/wiki/concepts/provider-native-prompting.md +203 -0
  190. package/vault/wiki/concepts/quality-signal-sentrux.md +37 -0
  191. package/vault/wiki/concepts/repo-map-ranking.md +42 -0
  192. package/vault/wiki/concepts/result-monad-error-handling.md +47 -0
  193. package/vault/wiki/concepts/safety-defense-in-depth.md +83 -0
  194. package/vault/wiki/concepts/sandbox-os-enforcement.md +18 -0
  195. package/vault/wiki/concepts/selective-debate-routing.md +70 -0
  196. package/vault/wiki/concepts/self-evolving-harness.md +60 -0
  197. package/vault/wiki/concepts/sentrux-mcp-integration.md +36 -0
  198. package/vault/wiki/concepts/sentrux-rules-engine.md +49 -0
  199. package/vault/wiki/concepts/shell-pattern-compression.md +24 -0
  200. package/vault/wiki/concepts/skill-first-architecture.md +166 -0
  201. package/vault/wiki/concepts/structured-compaction.md +78 -0
  202. package/vault/wiki/concepts/subagent-orchestration.md +17 -0
  203. package/vault/wiki/concepts/subagent-worktree-isolation.md +68 -0
  204. package/vault/wiki/concepts/superpowers-methodology.md +78 -0
  205. package/vault/wiki/concepts/think-in-code.md +73 -0
  206. package/vault/wiki/concepts/ts-execution-layer.md +100 -0
  207. package/vault/wiki/concepts/typescript-strict-mode.md +37 -0
  208. package/vault/wiki/concepts/vcc-conversation-compaction-for-pi.md +51 -0
  209. package/vault/wiki/concepts/verification-drift-detection.md +19 -0
  210. package/vault/wiki/consensus/consensus-records.md +58 -0
  211. package/vault/wiki/decisions/2026-04-30-pi-lean-ctx-native.md +122 -0
  212. package/vault/wiki/decisions/adr-008.md +40 -0
  213. package/vault/wiki/decisions/adr-009.md +46 -0
  214. package/vault/wiki/decisions/adr-010.md +55 -0
  215. package/vault/wiki/decisions/adr-011.md +165 -0
  216. package/vault/wiki/decisions/adr-012.md +102 -0
  217. package/vault/wiki/decisions/adr-013.md +59 -0
  218. package/vault/wiki/decisions/adr-014.md +73 -0
  219. package/vault/wiki/decisions/adr-015.md +81 -0
  220. package/vault/wiki/decisions/adr-016.md +91 -0
  221. package/vault/wiki/decisions/adr-017.md +79 -0
  222. package/vault/wiki/decisions/adr-018.md +100 -0
  223. package/vault/wiki/decisions/adr-019.md +75 -0
  224. package/vault/wiki/decisions/adr-020.md +106 -0
  225. package/vault/wiki/decisions/adr-021.md +86 -0
  226. package/vault/wiki/decisions/adr-022.md +113 -0
  227. package/vault/wiki/decisions/adr-023.md +113 -0
  228. package/vault/wiki/decisions/adr-024.md +73 -0
  229. package/vault/wiki/decisions/adr-025.md +130 -0
  230. package/vault/wiki/decisions/adr-026.md +56 -0
  231. package/vault/wiki/decisions/colocate-wiki.md +34 -0
  232. package/vault/wiki/entities/Anders Hejlsberg.md +29 -0
  233. package/vault/wiki/entities/Anthropic.md +17 -0
  234. package/vault/wiki/entities/Augment Code.md +49 -0
  235. package/vault/wiki/entities/Bjarne Stroustrup.md +26 -0
  236. package/vault/wiki/entities/Bolt.new (StackBlitz).md +39 -0
  237. package/vault/wiki/entities/Boris Cherny.md +11 -0
  238. package/vault/wiki/entities/Claude Code.md +19 -0
  239. package/vault/wiki/entities/Dennis Ritchie.md +26 -0
  240. package/vault/wiki/entities/Emergent Labs.md +32 -0
  241. package/vault/wiki/entities/Google Cloud.md +16 -0
  242. package/vault/wiki/entities/Guido van Rossum.md +28 -0
  243. package/vault/wiki/entities/Ken Thompson.md +28 -0
  244. package/vault/wiki/entities/Lee et al.md +16 -0
  245. package/vault/wiki/entities/Linus Torvalds.md +28 -0
  246. package/vault/wiki/entities/Lovable (company).md +40 -0
  247. package/vault/wiki/entities/Martin Fowler.md +16 -0
  248. package/vault/wiki/entities/Meng et al.md +16 -0
  249. package/vault/wiki/entities/OpenAI.md +16 -0
  250. package/vault/wiki/entities/Rocket.new.md +38 -0
  251. package/vault/wiki/entities/VILA-Lab.md +15 -0
  252. package/vault/wiki/entities/autodev-codebase.md +18 -0
  253. package/vault/wiki/entities/ck-tool.md +59 -0
  254. package/vault/wiki/entities/codesearch.md +18 -0
  255. package/vault/wiki/entities/disler-indydevdan.md +33 -0
  256. package/vault/wiki/entities/gsd-get-shit-done.md +56 -0
  257. package/vault/wiki/entities/javascript-runtimes.md +48 -0
  258. package/vault/wiki/entities/jesse-vincent.md +38 -0
  259. package/vault/wiki/entities/lean-ctx.md +32 -0
  260. package/vault/wiki/entities/opendev.md +41 -0
  261. package/vault/wiki/entities/ops-codegraph-tool.md +18 -0
  262. package/vault/wiki/entities/pi-coding-agent.md +53 -0
  263. package/vault/wiki/entities/sentrux.md +54 -0
  264. package/vault/wiki/entities/vgrep-tool.md +57 -0
  265. package/vault/wiki/entities/vitest.md +41 -0
  266. package/vault/wiki/flows/harness-wiki-pipeline.md +204 -0
  267. package/vault/wiki/hot.md +932 -0
  268. package/vault/wiki/index.md +437 -0
  269. package/vault/wiki/log.md +418 -0
  270. package/vault/wiki/meta/dashboard.md +30 -0
  271. package/vault/wiki/meta/lint-report-2026-04-30.md +86 -0
  272. package/vault/wiki/meta/lint-report-2026-05-02.md +251 -0
  273. package/vault/wiki/meta/overview.canvas +43 -0
  274. package/vault/wiki/modules/adversarial-verification.md +57 -0
  275. package/vault/wiki/modules/automated-observability.md +54 -0
  276. package/vault/wiki/modules/bench.md +20 -0
  277. package/vault/wiki/modules/extensions.md +23 -0
  278. package/vault/wiki/modules/grounding-checkpoints.md +62 -0
  279. package/vault/wiki/modules/harness-implementation-plan.md +345 -0
  280. package/vault/wiki/modules/harness-wiki-skill-mapping.md +135 -0
  281. package/vault/wiki/modules/harness.md +86 -0
  282. package/vault/wiki/modules/persistent-memory.md +85 -0
  283. package/vault/wiki/modules/schema-orchestration.md +68 -0
  284. package/vault/wiki/modules/skills.md +27 -0
  285. package/vault/wiki/modules/spec-hardening.md +58 -0
  286. package/vault/wiki/modules/structured-planning.md +53 -0
  287. package/vault/wiki/modules/think-in-code-enforcement.md +153 -0
  288. package/vault/wiki/modules/wiki-query-interface.md +64 -0
  289. package/vault/wiki/overview.md +51 -0
  290. package/vault/wiki/questions/Research-pi-vs-claude-code-agentic-orchestration-pipeline.md +87 -0
  291. package/vault/wiki/questions/Research-sentrux-dev.md +123 -0
  292. package/vault/wiki/questions/Research-superpowers-skill-for-agentic-coding-agents.md +164 -0
  293. package/vault/wiki/questions/Research: Augment Code Context Engine.md +244 -0
  294. package/vault/wiki/questions/Research: Automating Software Engineering - Lovable, Bolt, Emergent, Rocket.md +112 -0
  295. package/vault/wiki/questions/Research: Claude Code State-of-the-Art Harness Improvements.md +209 -0
  296. package/vault/wiki/questions/Research: Codex State-of-the-Art Harness Improvements.md +99 -0
  297. package/vault/wiki/questions/Research: Engineering Workflows of Legendary Programmers and AI Harness Mapping.md +107 -0
  298. package/vault/wiki/questions/Research: Fallow Codebase Intelligence Harness Integration.md +72 -0
  299. package/vault/wiki/questions/Research: Gemini CLI SOTA Harness Integration.md +166 -0
  300. package/vault/wiki/questions/Research: GitHub Issues as Harness Spec Storage.md +188 -0
  301. package/vault/wiki/questions/Research: Google Antigravity Harness Integration.md +120 -0
  302. package/vault/wiki/questions/Research: Meta-Agent Context Drift Detection.md +236 -0
  303. package/vault/wiki/questions/Research: Model-Adaptive Agent Harness Design.md +95 -0
  304. package/vault/wiki/questions/Research: Model-Specific Prompting Guides.md +165 -0
  305. package/vault/wiki/questions/Research: Prompt Renderer for Multi-Model Agent Harness.md +216 -0
  306. package/vault/wiki/questions/Research: Skill-First Harness Architecture.md +91 -0
  307. package/vault/wiki/questions/Research: TypeScript Best Practices and Codebase Structure.md +88 -0
  308. package/vault/wiki/questions/Research: TypeScript Execution Layer for Agent Tool Calling.md +81 -0
  309. package/vault/wiki/questions/Research: claude-mem over Obsidian for Harness Layer.md +71 -0
  310. 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 +80 -0
  311. package/vault/wiki/questions/Research: context-mode vs lean-ctx.md +72 -0
  312. package/vault/wiki/questions/Research: cursor.sh Harness Innovations.md +92 -0
  313. package/vault/wiki/questions/Research: executor.sh Harness Integration.md +170 -0
  314. package/vault/wiki/questions/Research: how GSD fits into our coding harness setup.md +97 -0
  315. 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 +80 -0
  316. package/vault/wiki/questions/Research: pi-vcc.md +113 -0
  317. package/vault/wiki/questions/Research: semantic code search tools.md +69 -0
  318. package/vault/wiki/questions/Research: vcc extension for pi coding agent.md +73 -0
  319. package/vault/wiki/questions/how-to-enable-semantic-code-search-now.md +111 -0
  320. package/vault/wiki/questions/mvp-implementation-blueprint.md +552 -0
  321. package/vault/wiki/questions/research-agent-first-codebase-exploration.md +199 -0
  322. package/vault/wiki/questions/research-agentic-coding-harness-latest-papers.md +142 -0
  323. package/vault/wiki/questions/research-gitingest-gitreverse-integration.md +100 -0
  324. package/vault/wiki/questions/research-wozcode-token-reduction.md +67 -0
  325. package/vault/wiki/questions/resolved-context-pruning-inplace-vs-restart.md +95 -0
  326. package/vault/wiki/questions/resolved-context-window-economics.md +167 -0
  327. package/vault/wiki/questions/resolved-imad-debate-gating-transfer.md +126 -0
  328. package/vault/wiki/questions/resolved-mcp-tool-preference.md +112 -0
  329. package/vault/wiki/questions/resolved-small-model-meta-agents.md +107 -0
  330. package/vault/wiki/questions/resolved-treesitter-dynamic-languages.md +95 -0
  331. package/vault/wiki/sources/Auggie Context MCP Server.md +63 -0
  332. package/vault/wiki/sources/Augment Code Codacy AI Giants.md +61 -0
  333. package/vault/wiki/sources/Augment Code MCP SiliconAngle.md +49 -0
  334. package/vault/wiki/sources/Augment Code WorkOS ERC 2025.md +55 -0
  335. package/vault/wiki/sources/Augment Context Engine Official.md +71 -0
  336. package/vault/wiki/sources/Augment SWE-bench Agent GitHub.md +74 -0
  337. package/vault/wiki/sources/Augment SWE-bench Pro Blog.md +58 -0
  338. package/vault/wiki/sources/Source: AgentBus Jinja2 Prompt Pipelines.md +75 -0
  339. package/vault/wiki/sources/Source: Arxiv /342/200/224 Don't Break the Cache.md" +85 -0
  340. package/vault/wiki/sources/Source: Augment - Harness Engineering for AI Coding Agents.md +58 -0
  341. package/vault/wiki/sources/Source: Blake Crosley Agent Architecture Guide.md +100 -0
  342. package/vault/wiki/sources/Source: Bolt.new Architecture & Case Study.md +75 -0
  343. package/vault/wiki/sources/Source: Build-Time Prompt Compilation Architecture.md +107 -0
  344. package/vault/wiki/sources/Source: Claude API Agent Skills Overview.md +70 -0
  345. package/vault/wiki/sources/Source: Gemini CLI Changelogs.md +88 -0
  346. package/vault/wiki/sources/Source: Google Blog - Gemini CLI Announcement.md +57 -0
  347. package/vault/wiki/sources/Source: Google Gemini CLI Architecture Docs.md +53 -0
  348. package/vault/wiki/sources/Source: LangChain - Anatomy of Agent Harness.md +65 -0
  349. package/vault/wiki/sources/Source: Lovable Architecture & Clone Analysis.md +83 -0
  350. package/vault/wiki/sources/Source: Martin Fowler - Harness Engineering.md +70 -0
  351. package/vault/wiki/sources/Source: OpenAI Harness Engineering Five Principles.md +58 -0
  352. package/vault/wiki/sources/Source: OpenAI Harness Engineering /342/200/224 0 Lines of Human Code.md" +101 -0
  353. package/vault/wiki/sources/Source: OpenDev /342/200/224 Building AI Coding Agents for the Terminal.md" +100 -0
  354. package/vault/wiki/sources/Source: Render AI Coding Agents Benchmark 2025.md +53 -0
  355. package/vault/wiki/sources/Source: Rocket.new /342/200/224 Vibe Solutioning Platform.md" +70 -0
  356. package/vault/wiki/sources/Source: SwirlAI Agent Skills Progressive Disclosure.md +71 -0
  357. package/vault/wiki/sources/Source: TianPan Prompt Caching Architecture.md +89 -0
  358. package/vault/wiki/sources/Source: Vercel Labs agent-browser.md +155 -0
  359. package/vault/wiki/sources/Source: browser-harness CDP Harness.md +126 -0
  360. package/vault/wiki/sources/agent-drift-academic-paper.md +79 -0
  361. package/vault/wiki/sources/aider-repomap-tree-sitter.md +42 -0
  362. package/vault/wiki/sources/anthropic-compaction-api.md +58 -0
  363. package/vault/wiki/sources/anthropic-effective-harnesses.md +42 -0
  364. package/vault/wiki/sources/anthropic-prompt-best-practices.md +100 -0
  365. package/vault/wiki/sources/anthropic2026-harness-design.md +63 -0
  366. package/vault/wiki/sources/barrel-files-tkdodo.md +38 -0
  367. package/vault/wiki/sources/birth-of-unix-kernighan-interview.md +57 -0
  368. package/vault/wiki/sources/bockeler2026-harness-engineering.md +69 -0
  369. package/vault/wiki/sources/cast-code-chunking-paper.md +50 -0
  370. package/vault/wiki/sources/ck-semantic-search.md +78 -0
  371. package/vault/wiki/sources/claude-code-architecture-karaxai-2026.md +71 -0
  372. package/vault/wiki/sources/claude-code-architecture-qubytes-2026.md +50 -0
  373. package/vault/wiki/sources/claude-code-architecture-vila-lab-2026.md +64 -0
  374. package/vault/wiki/sources/claude-code-security-architecture-penligent-2026.md +70 -0
  375. package/vault/wiki/sources/claude-context-editing-docs.md +13 -0
  376. package/vault/wiki/sources/cloudflare-codemode.md +63 -0
  377. package/vault/wiki/sources/code-chunk-library-supermemory.md +63 -0
  378. package/vault/wiki/sources/codeact-apple-2024.md +62 -0
  379. package/vault/wiki/sources/codex-dsc-rfc-8573.md +41 -0
  380. package/vault/wiki/sources/codex-open-source-agent-2026.md +110 -0
  381. package/vault/wiki/sources/coir-code-retrieval-benchmark.md +51 -0
  382. package/vault/wiki/sources/colinmcnamara-context-optimization-codemode.md +48 -0
  383. package/vault/wiki/sources/context-folding-paper.md +61 -0
  384. package/vault/wiki/sources/context-mode-website.md +63 -0
  385. package/vault/wiki/sources/cursor-agent-best-practices-2026.md +62 -0
  386. package/vault/wiki/sources/cursor-fork-29b-2025.md +50 -0
  387. package/vault/wiki/sources/cursor-harness-april-2026.md +76 -0
  388. package/vault/wiki/sources/cursor-instant-apply-2024.md +45 -0
  389. package/vault/wiki/sources/cursor-shadow-workspace-2024.md +52 -0
  390. package/vault/wiki/sources/cursor-shipped-coding-agent-2026.md +53 -0
  391. package/vault/wiki/sources/cursor-vs-antigravity-2026.md +51 -0
  392. package/vault/wiki/sources/disler-pi-vs-claude-code.md +69 -0
  393. package/vault/wiki/sources/distill-deterministic-context-compression.md +53 -0
  394. package/vault/wiki/sources/embedding-models-benchmark-supermemory-2025.md +48 -0
  395. package/vault/wiki/sources/executor-rhyssullivan.md +122 -0
  396. package/vault/wiki/sources/fallow-rs-codebase-intelligence.md +125 -0
  397. package/vault/wiki/sources/fan2025-imad.md +60 -0
  398. package/vault/wiki/sources/forgecode-gpt5-agent-improvements.md +63 -0
  399. package/vault/wiki/sources/gemini-3-prompting-guide.md +78 -0
  400. package/vault/wiki/sources/gh-cli-sub-issue-rfc.md +50 -0
  401. package/vault/wiki/sources/gh-sub-issue-extension.md +72 -0
  402. package/vault/wiki/sources/github-fork-issues-discussion.md +44 -0
  403. package/vault/wiki/sources/github-issue-dependencies-docs.md +49 -0
  404. package/vault/wiki/sources/github-sub-issues-docs.md +51 -0
  405. package/vault/wiki/sources/gitingest.md +91 -0
  406. package/vault/wiki/sources/gitreverse.md +63 -0
  407. package/vault/wiki/sources/google-antigravity-official-blog.md +47 -0
  408. package/vault/wiki/sources/google-antigravity-wikipedia.md +53 -0
  409. package/vault/wiki/sources/gsd-codecentric-deep-dive.md +57 -0
  410. package/vault/wiki/sources/gsd-github-repo.md +51 -0
  411. package/vault/wiki/sources/gsd-hn-discussion.md +59 -0
  412. package/vault/wiki/sources/guido-python-design-philosophy.md +56 -0
  413. package/vault/wiki/sources/hejlsberg-7-learnings.md +48 -0
  414. package/vault/wiki/sources/ironclaw-drift-monitor.md +80 -0
  415. package/vault/wiki/sources/langsight-loop-detection.md +80 -0
  416. package/vault/wiki/sources/leanctx-website.md +69 -0
  417. package/vault/wiki/sources/lee2026-meta-harness.md +59 -0
  418. package/vault/wiki/sources/linux-kernel-coding-workflow.md +50 -0
  419. package/vault/wiki/sources/lou2026-autoharness.md +53 -0
  420. package/vault/wiki/sources/martin-fowler-harness-engineering.md +73 -0
  421. package/vault/wiki/sources/mcp-architecture-docs.md +13 -0
  422. package/vault/wiki/sources/meng2026-agent-harness-survey.md +79 -0
  423. package/vault/wiki/sources/mindstudio-four-agent-types.md +68 -0
  424. package/vault/wiki/sources/ms-chat-history-management.md +13 -0
  425. package/vault/wiki/sources/openai-prompt-guidance.md +104 -0
  426. package/vault/wiki/sources/openclaw-session-pruning.md +13 -0
  427. package/vault/wiki/sources/opencode-dcp.md +13 -0
  428. package/vault/wiki/sources/opendev-arxiv-2603.05344v1.md +79 -0
  429. package/vault/wiki/sources/openhands-platform.md +39 -0
  430. package/vault/wiki/sources/oss-guide-codebase-exploration.md +53 -0
  431. package/vault/wiki/sources/pi-compaction-extensions-ecosystem.md +102 -0
  432. package/vault/wiki/sources/pi-context-prune-github-repo.md +38 -0
  433. package/vault/wiki/sources/pi-mono-compaction-docs.md +38 -0
  434. package/vault/wiki/sources/pi-omni-compact-github-repo.md +50 -0
  435. package/vault/wiki/sources/pi-rtk-optimizer-github-repo.md +45 -0
  436. package/vault/wiki/sources/pi-vcc-github-repo.md +69 -0
  437. package/vault/wiki/sources/pi-vscode-marketplace.md +41 -0
  438. package/vault/wiki/sources/pi-vscode-model-provider-marketplace.md +39 -0
  439. package/vault/wiki/sources/py-tree-sitter.md +13 -0
  440. package/vault/wiki/sources/sentrux-dev-landing.md +40 -0
  441. package/vault/wiki/sources/sentrux-docs-pro-architecture.md +75 -0
  442. package/vault/wiki/sources/sentrux-docs-quality-signal.md +46 -0
  443. package/vault/wiki/sources/sentrux-docs-root-cause-metrics.md +57 -0
  444. package/vault/wiki/sources/sentrux-docs-rules-engine.md +58 -0
  445. package/vault/wiki/sources/sentrux-github-repo.md +56 -0
  446. package/vault/wiki/sources/superpowers-github-repo.md +56 -0
  447. package/vault/wiki/sources/superpowers-release-blog.md +54 -0
  448. package/vault/wiki/sources/superpowers-termdock-analysis.md +45 -0
  449. package/vault/wiki/sources/swe-agent-aci.md +42 -0
  450. package/vault/wiki/sources/swe-bench.md +45 -0
  451. package/vault/wiki/sources/swe-pruner-context-pruning.md +13 -0
  452. package/vault/wiki/sources/think-in-code-blog.md +48 -0
  453. package/vault/wiki/sources/tree-sitter-docs.md +13 -0
  454. package/vault/wiki/sources/ts-best-practices-2025-devto.md +42 -0
  455. package/vault/wiki/sources/ts-folder-structure-mingyang.md +58 -0
  456. package/vault/wiki/sources/ts-monorepo-koerselman.md +44 -0
  457. package/vault/wiki/sources/ts-result-error-handling-kkalamarski.md +52 -0
  458. package/vault/wiki/sources/ts-runtimes-comparison-betterstack.md +42 -0
  459. package/vault/wiki/sources/ts-strict-mode-rishikc.md +43 -0
  460. package/vault/wiki/sources/unix-philosophy.md +48 -0
  461. package/vault/wiki/sources/vectara-chunking-vs-embedding-naacl2025.md +39 -0
  462. package/vault/wiki/sources/vectara-guardian-agents.md +79 -0
  463. package/vault/wiki/sources/vgrep-semantic-search.md +76 -0
  464. package/vault/wiki/sources/vitest-official.md +41 -0
  465. package/vault/wiki/sources/vscode-pi-community-extension.md +40 -0
  466. package/vault/wiki/sources/wozcode.md +79 -0
  467. package/.agents/skills/compress/SKILL.md +0 -111
  468. package/.agents/skills/compress/scripts/__init__.py +0 -9
  469. package/.agents/skills/compress/scripts/__main__.py +0 -3
  470. package/.agents/skills/compress/scripts/benchmark.py +0 -78
  471. package/.agents/skills/compress/scripts/cli.py +0 -73
  472. package/.agents/skills/compress/scripts/compress.py +0 -227
  473. package/.agents/skills/compress/scripts/detect.py +0 -121
  474. package/.agents/skills/compress/scripts/validate.py +0 -189
  475. package/.agents/skills/emil-design-eng/SKILL.md +0 -679
  476. package/.agents/skills/lean-ctx/SKILL.md +0 -149
  477. package/.agents/skills/lean-ctx/scripts/install.sh +0 -95
  478. package/.agents/skills/scrapling-official/LICENSE.txt +0 -28
  479. package/.agents/skills/scrapling-official/SKILL.md +0 -390
  480. package/.agents/skills/scrapling-official/examples/01_fetcher_session.py +0 -26
  481. package/.agents/skills/scrapling-official/examples/02_dynamic_session.py +0 -26
  482. package/.agents/skills/scrapling-official/examples/03_stealthy_session.py +0 -26
  483. package/.agents/skills/scrapling-official/examples/04_spider.py +0 -58
  484. package/.agents/skills/scrapling-official/examples/README.md +0 -45
  485. package/.agents/skills/scrapling-official/references/fetching/choosing.md +0 -78
  486. package/.agents/skills/scrapling-official/references/fetching/dynamic.md +0 -352
  487. package/.agents/skills/scrapling-official/references/fetching/static.md +0 -432
  488. package/.agents/skills/scrapling-official/references/fetching/stealthy.md +0 -255
  489. package/.agents/skills/scrapling-official/references/mcp-server.md +0 -214
  490. package/.agents/skills/scrapling-official/references/migrating_from_beautifulsoup.md +0 -86
  491. package/.agents/skills/scrapling-official/references/parsing/adaptive.md +0 -212
  492. package/.agents/skills/scrapling-official/references/parsing/main_classes.md +0 -586
  493. package/.agents/skills/scrapling-official/references/parsing/selection.md +0 -494
  494. package/.agents/skills/scrapling-official/references/spiders/advanced.md +0 -344
  495. package/.agents/skills/scrapling-official/references/spiders/architecture.md +0 -94
  496. package/.agents/skills/scrapling-official/references/spiders/getting-started.md +0 -164
  497. package/.agents/skills/scrapling-official/references/spiders/proxy-blocking.md +0 -235
  498. package/.agents/skills/scrapling-official/references/spiders/requests-responses.md +0 -196
  499. package/.agents/skills/scrapling-official/references/spiders/sessions.md +0 -205
  500. package/PLAN.md +0 -11
  501. package/extensions/lean-ctx-enforce.ts +0 -166
  502. package/skills-lock.json +0 -35
  503. package/wiki/README.md +0 -19
  504. package/wiki/decisions/0001-establish-project-wiki-and-decision-record-format.md +0 -25
  505. package/wiki/decisions/0002-add-project-banner-to-readme.md +0 -26
  506. package/wiki/decisions/0003-remove-redundant-readme-title-heading.md +0 -26
  507. package/wiki/decisions/0004-publish-package-to-npm-as-ultimate-pi.md +0 -26
  508. package/wiki/decisions/0005-automate-npm-publish-with-github-actions.md +0 -27
  509. package/wiki/decisions/0006-switch-to-npm-trusted-publishing.md +0 -26
  510. package/wiki/decisions/0007-use-absolute-banner-url-for-npm-readme-rendering.md +0 -26
  511. package/wiki/decisions/0008-rename-banner-asset-for-cache-busting.md +0 -26
  512. package/wiki/decisions/0009-force-oidc-path-by-clearing-node-auth-token-in-publish-step.md +0 -25
  513. package/wiki/decisions/0010-simplify-setup-node-for-npm-trusted-publishing.md +0 -26
  514. package/wiki/decisions/0011-add-noop-workflow-change-to-force-fresh-publish-run.md +0 -25
  515. package/wiki/decisions/0012-align-workflow-runtime-with-npm-trusted-publishing-requirements.md +0 -26
  516. package/wiki/decisions/0013-add-package-repository-url-for-provenance-validation.md +0 -25
@@ -0,0 +1,308 @@
1
+ /**
2
+ * Custom Footer Extension — single-line footer with context bar, session cost,
3
+ * model name, provider, thinking level, working directory, and git branch.
4
+ *
5
+ * ~/project (main) ↑12k ↓8k $0.042 [████████░░] 72% anthropic • claude-sonnet-4-20250514 • xhigh
6
+ */
7
+
8
+ import type { ExtensionAPI, ExtensionContext } from "@mariozechner/pi-coding-agent";
9
+ import type { TUI } from "@mariozechner/pi-tui";
10
+ import { Box, Text, truncateToWidth, visibleWidth } from "@mariozechner/pi-tui";
11
+
12
+ // ── token formatting ──────────────────────────────────────────────
13
+
14
+ function fmtTokens(count: number): string {
15
+ if (count < 1000) return count.toString();
16
+ if (count < 10000) return `${(count / 1000).toFixed(1)}k`;
17
+ if (count < 1_000_000) return `${Math.round(count / 1000)}k`;
18
+ if (count < 10_000_000) return `${(count / 1_000_000).toFixed(1)}M`;
19
+ return `${Math.round(count / 1_000_000)}M`;
20
+ }
21
+
22
+ // ── bar builder ───────────────────────────────────────────────────
23
+
24
+ const BAR_FILLED = "█";
25
+ const BAR_EMPTY = "░";
26
+ const BAR_COUNT = 10;
27
+
28
+ type BarColor = "success" | "warning" | "error";
29
+
30
+ function barColor(percent: number): BarColor {
31
+ if (percent < 50) return "success";
32
+ if (percent < 80) return "warning";
33
+ return "error";
34
+ }
35
+
36
+ /** Build colored bar segment — returns filled and empty strings separately. */
37
+ function buildBar(percent: number): { filled: string; empty: string } {
38
+ const filled = Math.round((Math.min(percent, 100) / 100) * BAR_COUNT);
39
+ const empty = BAR_COUNT - filled;
40
+ return {
41
+ filled: BAR_FILLED.repeat(filled),
42
+ empty: BAR_EMPTY.repeat(empty),
43
+ };
44
+ }
45
+
46
+ // ── cost computation ──────────────────────────────────────────────
47
+
48
+ interface CostSnapshot {
49
+ input: number;
50
+ output: number;
51
+ cacheRead: number;
52
+ cacheWrite: number;
53
+ cost: number;
54
+ }
55
+
56
+ function computeCost(ctx: ExtensionContext): CostSnapshot {
57
+ let input = 0;
58
+ let output = 0;
59
+ let cacheRead = 0;
60
+ let cacheWrite = 0;
61
+ let cost = 0;
62
+
63
+ for (const entry of ctx.sessionManager.getEntries()) {
64
+ if (entry.type === "message" && entry.message.role === "assistant") {
65
+ const u = entry.message.usage;
66
+ input += u.input ?? 0;
67
+ output += u.output ?? 0;
68
+ cacheRead += u.cacheRead ?? 0;
69
+ cacheWrite += u.cacheWrite ?? 0;
70
+ cost += u.cost?.total ?? 0;
71
+ }
72
+ }
73
+
74
+ return { input, output, cacheRead, cacheWrite, cost };
75
+ }
76
+
77
+ // ── model info ────────────────────────────────────────────────────
78
+
79
+ interface ModelInfo {
80
+ id: string;
81
+ provider: string;
82
+ reasoning: boolean;
83
+ }
84
+
85
+ function modelInfo(ctx: ExtensionContext): ModelInfo {
86
+ const m = ctx.model;
87
+ if (!m) return { id: "no-model", provider: "unknown", reasoning: false };
88
+ return { id: m.id, provider: m.provider, reasoning: m.reasoning };
89
+ }
90
+
91
+ // ── thinking label ────────────────────────────────────────────────
92
+
93
+ /** Returns thinking level display string, or null if model doesn't support reasoning. */
94
+ function thinkingLabel(level: string | null, reasoning: boolean): string | null {
95
+ if (!reasoning || level == null) return null;
96
+ if (level === "minimal") return "off";
97
+ return level;
98
+ }
99
+
100
+ // ── cwd + branch ──────────────────────────────────────────────────
101
+
102
+ function pathLabel(cwd: string, branch: string | null): { cwd: string; branch: string | null } {
103
+ let pwd = cwd;
104
+ const home = process.env.HOME || process.env.USERPROFILE;
105
+ if (home && pwd.startsWith(home)) {
106
+ pwd = `~${pwd.slice(home.length)}`;
107
+ }
108
+ return { cwd: pwd, branch };
109
+ }
110
+
111
+ // ── extension ─────────────────────────────────────────────────────
112
+
113
+ export default function customFooter(pi: ExtensionAPI) {
114
+ let unsubBranch: (() => void) | null = null;
115
+
116
+ const state: {
117
+ tui: TUI | null;
118
+ box: Box | null;
119
+ textLine: Text | null;
120
+ percent: number | null;
121
+ cost: CostSnapshot;
122
+ cwd: string;
123
+ modelId: string;
124
+ modelProvider: string;
125
+ modelReasoning: boolean;
126
+ thinkingLevel: string | null;
127
+ branch: string | null;
128
+ } = {
129
+ tui: null,
130
+ box: null,
131
+ textLine: null,
132
+ percent: null,
133
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0 },
134
+ cwd: process.cwd(),
135
+ modelId: "…",
136
+ modelProvider: "…",
137
+ modelReasoning: false,
138
+ thinkingLevel: null,
139
+ branch: null,
140
+ };
141
+
142
+ function invalidate() {
143
+ state.box?.invalidate();
144
+ state.textLine?.invalidate();
145
+ state.tui?.requestRender();
146
+ }
147
+
148
+ function refreshModelAndThinking(ctx: ExtensionContext) {
149
+ const mi = modelInfo(ctx);
150
+ state.modelId = mi.id;
151
+ state.modelProvider = mi.provider;
152
+ state.modelReasoning = mi.reasoning;
153
+ state.thinkingLevel = pi.getThinkingLevel();
154
+ }
155
+
156
+ pi.on("session_start", (_event, ctx) => {
157
+ state.cwd = ctx.cwd;
158
+ refreshModelAndThinking(ctx);
159
+ state.cost = computeCost(ctx);
160
+
161
+ ctx.ui.setFooter((tui, theme, footerData) => {
162
+ if (unsubBranch) { unsubBranch(); unsubBranch = null; }
163
+
164
+ state.tui = tui;
165
+ state.branch = footerData.getGitBranch();
166
+
167
+ unsubBranch = footerData.onBranchChange(() => {
168
+ state.branch = footerData.getGitBranch();
169
+ invalidate();
170
+ });
171
+
172
+ const box = new Box(1, 0);
173
+ const textLine = new Text("", 0, 0);
174
+ box.addChild(textLine);
175
+
176
+ state.box = box;
177
+ state.textLine = textLine;
178
+
179
+ return {
180
+ dispose() {
181
+ if (unsubBranch) { unsubBranch(); unsubBranch = null; }
182
+ state.tui = null;
183
+ state.box = null;
184
+ state.textLine = null;
185
+ },
186
+
187
+ invalidate() {
188
+ box.invalidate();
189
+ textLine.invalidate();
190
+ },
191
+
192
+ render(width: number): string[] {
193
+ const dim = (s: string) => theme.fg("dim", s);
194
+ const c = state.cost;
195
+ const pct = state.percent;
196
+
197
+ // Available text width: Box paddingX=1 on each side → subtract 2,
198
+ // then subtract safety margin so we never overflow on edge-case terminals
199
+ const SAFETY_MARGIN = 2;
200
+ const innerW = Math.max(1, width - 2 - SAFETY_MARGIN);
201
+
202
+ // ── left: cwd/branch tokens cost ──
203
+ const { cwd: cwdPath, branch: gitBranch } = pathLabel(state.cwd, state.branch);
204
+ const pathDisplay = gitBranch
205
+ ? `${cwdPath} (${theme.fg("error", gitBranch)})`
206
+ : cwdPath;
207
+ const leftParts: string[] = [pathDisplay];
208
+ if (c.input > 0 || c.output > 0) {
209
+ leftParts.push(`↑${fmtTokens(c.input)} ↓${fmtTokens(c.output)}`);
210
+ }
211
+ if (c.cost > 0) {
212
+ leftParts.push(`$${c.cost.toFixed(4)}`);
213
+ }
214
+ const leftStr = leftParts.join(" ");
215
+
216
+ // ── bar: [████████░░] 72% ──
217
+ const safePct = pct ?? 0;
218
+ const { filled, empty } = buildBar(safePct);
219
+ const barColorName = barColor(safePct);
220
+ const barInner = theme.fg(barColorName, filled) + empty;
221
+ const barFull = `[${barInner}] ${Math.round(safePct)}%`;
222
+
223
+ // ── right: provider • modelId thinkingLevel ──
224
+ const tl = thinkingLabel(state.thinkingLevel, state.modelReasoning);
225
+ const modelDisplay = tl ? `${state.modelId} ${tl}` : state.modelId;
226
+ const rightParts: string[] = [state.modelProvider, modelDisplay];
227
+ const rightStr = rightParts.join(" • ");
228
+
229
+ // ── compose single line ──
230
+ const colLeft = leftStr;
231
+ const dimRight = dim(rightStr);
232
+ const lw = visibleWidth(colLeft);
233
+ const rw = visibleWidth(dimRight);
234
+ const bw = visibleWidth(barFull);
235
+ const gap = 2;
236
+
237
+ if (lw + gap + bw + gap + rw <= innerW) {
238
+ const pad = innerW - lw - gap - bw - gap - rw;
239
+ const line = colLeft + " ".repeat(gap + pad) + barFull + " ".repeat(gap) + dimRight;
240
+ textLine.setText(truncateToWidth(line, innerW));
241
+ } else {
242
+ // Priority: keep bar visible, keep left (cwd) intact, truncate modelId first
243
+ const tlNow = thinkingLabel(state.thinkingLevel, state.modelReasoning);
244
+ const buildRight = (mid: string) => {
245
+ const modelPart = tlNow ? `${mid} ${tlNow}` : mid;
246
+ const parts: string[] = [state.modelProvider];
247
+ if (modelPart) parts.push(modelPart);
248
+ return dim(parts.join(" • "));
249
+ };
250
+
251
+ let truncMid = state.modelId;
252
+ let dimR = buildRight(truncMid);
253
+ let rwNow = visibleWidth(dimR);
254
+
255
+ while (truncMid.length > 0 && lw + gap + bw + gap + rwNow > innerW) {
256
+ truncMid = truncMid.slice(0, -1);
257
+ dimR = buildRight(truncMid);
258
+ rwNow = visibleWidth(dimR);
259
+ }
260
+
261
+ if (lw + gap + bw + gap + rwNow <= innerW) {
262
+ const pad = innerW - lw - gap - bw - gap - rwNow;
263
+ const line = colLeft + " ".repeat(gap + pad) + barFull + " ".repeat(gap) + dimR;
264
+ textLine.setText(truncateToWidth(line, innerW));
265
+ } else {
266
+ // ModelId gone, still overflows: truncate leftStr
267
+ const avail = innerW - bw - rwNow - gap - gap;
268
+ if (avail < 1) {
269
+ textLine.setText(truncateToWidth(dimR, innerW));
270
+ } else {
271
+ const truncLeft = truncateToWidth(colLeft, Math.max(1, avail));
272
+ const line = truncLeft + " ".repeat(gap) + barFull + " ".repeat(gap) + dimR;
273
+ textLine.setText(truncateToWidth(line, innerW));
274
+ }
275
+ }
276
+ }
277
+
278
+ return box.render(width);
279
+ },
280
+ };
281
+ });
282
+ });
283
+
284
+ // Update context usage + cost before each LLM call
285
+ pi.on("context", (_event, ctx) => {
286
+ const usage = ctx.getContextUsage();
287
+ state.percent = usage?.percent ?? null;
288
+ state.cost = computeCost(ctx);
289
+ refreshModelAndThinking(ctx);
290
+ invalidate();
291
+ });
292
+
293
+ // Track model changes
294
+ pi.on("model_select", (event) => {
295
+ state.modelId = event.model?.id ?? "…";
296
+ state.modelProvider = event.model?.provider ?? "…";
297
+ state.modelReasoning = event.model?.reasoning ?? false;
298
+ state.thinkingLevel = pi.getThinkingLevel();
299
+ invalidate();
300
+ });
301
+
302
+ // Catch thinking level changes between turns (e.g. /thinking command)
303
+ pi.on("turn_start", (_event, ctx) => {
304
+ state.thinkingLevel = pi.getThinkingLevel();
305
+ refreshModelAndThinking(ctx);
306
+ invalidate();
307
+ });
308
+ }
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Custom Startup Header Extension for Ultimate Pi
3
+ *
4
+ * Renders .github/banner-v2.png as true-color block ASCII art using Jimp.
5
+ * Uses Unicode lower-half-block characters with per-pixel ANSI 24-bit color,
6
+ * doubling vertical resolution in the same terminal footprint.
7
+ */
8
+
9
+ import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
10
+ import { truncateToWidth } from "@mariozechner/pi-tui";
11
+ import Jimp from "jimp";
12
+ import { join } from "node:path";
13
+
14
+ const imagePath = join(process.cwd(), ".pi", "extensions", "banner.png");
15
+
16
+ // Terminal footprint — keep a safety margin so we never crash on narrow terminals
17
+ const SAFETY_MARGIN = 2;
18
+ const TERM_WIDTH = 120;
19
+ const TERM_HEIGHT = 24;
20
+
21
+ // Pixel grid: 1 char wide × 2 pixels tall (half-block)
22
+ const PIXEL_WIDTH = TERM_WIDTH;
23
+ const PIXEL_HEIGHT = TERM_HEIGHT * 2;
24
+
25
+ const HALF_BLOCK = "\u2584"; // lower half block: fg = bottom, bg = top
26
+
27
+ let cachedBanner: string[] | null = null;
28
+ let loadPromise: Promise<string[]> | null = null;
29
+
30
+ function ansiCell(
31
+ top: { r: number; g: number; b: number; a: number },
32
+ bottom: { r: number; g: number; b: number; a: number }
33
+ ): string {
34
+ const topTransparent = top.a < 128;
35
+ const bottomTransparent = bottom.a < 128;
36
+ if (topTransparent && bottomTransparent) {
37
+ return " ";
38
+ }
39
+ if (topTransparent) {
40
+ return `\x1b[38;2;${bottom.r};${bottom.g};${bottom.b};48;2;${bottom.r};${bottom.g};${bottom.b}m${HALF_BLOCK}\x1b[0m`;
41
+ }
42
+ if (bottomTransparent) {
43
+ return `\x1b[38;2;${top.r};${top.g};${top.b};48;2;${top.r};${top.g};${top.b}m${HALF_BLOCK}\x1b[0m`;
44
+ }
45
+ return `\x1b[38;2;${bottom.r};${bottom.g};${bottom.b};48;2;${top.r};${top.g};${top.b}m${HALF_BLOCK}\x1b[0m`;
46
+ }
47
+
48
+ async function loadBanner(): Promise<string[]> {
49
+ const image = await Jimp.read(imagePath);
50
+ image.resize(PIXEL_WIDTH, PIXEL_HEIGHT);
51
+
52
+ const lines: string[] = [];
53
+ for (let row = 0; row < PIXEL_HEIGHT; row += 2) {
54
+ let line = "";
55
+ for (let col = 0; col < PIXEL_WIDTH; col++) {
56
+ const top = Jimp.intToRGBA(image.getPixelColor(col, row));
57
+ const bottom = Jimp.intToRGBA(image.getPixelColor(col, row + 1));
58
+ line += ansiCell(top, bottom);
59
+ }
60
+ lines.push(line);
61
+ }
62
+ return lines;
63
+ }
64
+
65
+ function getBanner(): Promise<string[]> {
66
+ if (cachedBanner) {
67
+ return Promise.resolve(cachedBanner);
68
+ }
69
+ if (loadPromise) {
70
+ return loadPromise;
71
+ }
72
+ loadPromise = loadBanner()
73
+ .then((lines) => {
74
+ cachedBanner = lines;
75
+ return lines;
76
+ })
77
+ .catch((err) => {
78
+ console.error("Failed to render banner:", err);
79
+ cachedBanner = [];
80
+ return [];
81
+ });
82
+ return loadPromise;
83
+ }
84
+
85
+ export default function (pi: ExtensionAPI) {
86
+ pi.on("session_start", async (_event, ctx) => {
87
+ if (!ctx.hasUI) {
88
+ return;
89
+ }
90
+
91
+ await getBanner();
92
+
93
+ ctx.ui.setHeader((_tui, _theme) => {
94
+ return {
95
+ render(width: number): string[] {
96
+ if (!cachedBanner || cachedBanner.length === 0) {
97
+ return [];
98
+ }
99
+ const maxW = Math.max(0, width - SAFETY_MARGIN);
100
+ return cachedBanner.map((line) => truncateToWidth(line, maxW));
101
+ },
102
+ invalidate() {
103
+ return false;
104
+ },
105
+ };
106
+ });
107
+ });
108
+
109
+ pi.registerCommand("builtin-header", {
110
+ description: "Restore built-in header with keybinding hints",
111
+ handler: async (_args, ctx) => {
112
+ ctx.ui.setHeader(undefined);
113
+ ctx.ui.notify("Built-in header restored", "info");
114
+ },
115
+ });
116
+ }
@@ -0,0 +1,170 @@
1
+ /**
2
+ * dotenv-loader — loads .env files into process.env before other extensions read config.
3
+ *
4
+ * Runs synchronously in the extension factory so vars are available immediately.
5
+ * Also reloads on session_start (reload/resume) to pick up file changes.
6
+ *
7
+ * Config (env vars, since .env isn't loaded yet):
8
+ * ENV_LOADER_FILES — comma-separated .env paths, default: ".env"
9
+ * ENV_LOADER_OVERRIDE — "true" to overwrite existing vars, default: "false"
10
+ * ENV_LOADER_SILENT — "true" to suppress all output, default: "false"
11
+ * ENV_LOADER_ENCODING — file encoding, default: "utf-8"
12
+ */
13
+
14
+ import { existsSync, readFileSync } from "node:fs";
15
+ import { resolve } from "node:path";
16
+ import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
17
+
18
+ // ── .env parser ──────────────────────────────────────────────────
19
+
20
+ function parseEnv(content: string): Map<string, string> {
21
+ const vars = new Map<string, string>();
22
+ for (const raw of content.split("\n")) {
23
+ const line = raw.trim();
24
+ if (!line || line.startsWith("#")) continue;
25
+
26
+ const eq = line.indexOf("=");
27
+ if (eq === -1) continue;
28
+
29
+ const key = line.slice(0, eq).trim();
30
+ let val = line.slice(eq + 1).trim();
31
+
32
+ // Strip surrounding quotes
33
+ if (
34
+ (val.startsWith('"') && val.endsWith('"')) ||
35
+ (val.startsWith("'") && val.endsWith("'"))
36
+ ) {
37
+ val = val.slice(1, -1);
38
+ }
39
+
40
+ // Expand ${VAR} and $VAR references from current process.env
41
+ val = val.replace(/\$\{([^}]+)\}/g, (_, name) => process.env[name] ?? "");
42
+ val = val.replace(
43
+ /\$([A-Za-z_][A-Za-z0-9_]*)/g,
44
+ (_, name) => process.env[name] ?? "",
45
+ );
46
+
47
+ if (key.length > 0) {
48
+ vars.set(key, val);
49
+ }
50
+ }
51
+ return vars;
52
+ }
53
+
54
+ // ── Load & apply ─────────────────────────────────────────────────
55
+
56
+ interface LoadResult {
57
+ loaded: number;
58
+ skipped: number;
59
+ files: Array<{ path: string; existed: boolean; vars: number }>;
60
+ }
61
+
62
+ function loadEnvFiles(cwd: string): LoadResult {
63
+ const filesStr = process.env.ENV_LOADER_FILES || ".env";
64
+ const override = process.env.ENV_LOADER_OVERRIDE === "true";
65
+ const encoding =
66
+ (process.env.ENV_LOADER_ENCODING as BufferEncoding) || "utf-8";
67
+
68
+ const filePaths = filesStr.split(",").map((f) => resolve(cwd, f.trim()));
69
+ const result: LoadResult = { loaded: 0, skipped: 0, files: [] };
70
+
71
+ for (const fp of filePaths) {
72
+ const existed = existsSync(fp);
73
+ let varsCount = 0;
74
+
75
+ if (!existed) {
76
+ result.files.push({ path: fp, existed: false, vars: 0 });
77
+ continue;
78
+ }
79
+
80
+ try {
81
+ const content = readFileSync(fp, { encoding });
82
+ const vars = parseEnv(content);
83
+
84
+ for (const [key, value] of vars) {
85
+ if (!override && key in process.env) {
86
+ result.skipped++;
87
+ continue;
88
+ }
89
+ process.env[key] = value;
90
+ result.loaded++;
91
+ varsCount++;
92
+ }
93
+
94
+ result.files.push({ path: fp, existed: true, vars: varsCount });
95
+ } catch (_err) {
96
+ result.files.push({ path: fp, existed: true, vars: 0 });
97
+ }
98
+ }
99
+
100
+ return result;
101
+ }
102
+
103
+ // ── Extension ────────────────────────────────────────────────────
104
+
105
+ export default function dotenvLoader(pi: ExtensionAPI) {
106
+ const silent = process.env.ENV_LOADER_SILENT === "true";
107
+ const cwd = process.cwd();
108
+
109
+ // Load immediately in factory — before other extensions' factories run.
110
+ const result = loadEnvFiles(cwd);
111
+
112
+ if (!silent) {
113
+ const summary = result.files
114
+ .filter((f) => f.existed)
115
+ .map((f) => ` ${f.path}: ${f.vars} vars applied`)
116
+ .join("\n");
117
+
118
+ if (summary) {
119
+ console.log(
120
+ `[dotenv-loader] Loaded ${result.loaded} vars, skipped ${result.skipped} (override=false).\n${summary}`,
121
+ );
122
+ } else {
123
+ const missing = result.files
124
+ .filter((f) => !f.existed)
125
+ .map((f) => f.path)
126
+ .join(", ");
127
+ console.log(`[dotenv-loader] No .env files found. Checked: ${missing}`);
128
+ }
129
+ }
130
+
131
+ // Reload on session_start (covers reload/resume/new)
132
+ pi.on("session_start", () => {
133
+ const reloadResult = loadEnvFiles(cwd);
134
+
135
+ // Only log if something changed
136
+ if (!silent && reloadResult.loaded > 0) {
137
+ console.log(
138
+ `[dotenv-loader] Reloaded ${reloadResult.loaded} vars from .env files.`,
139
+ );
140
+ }
141
+ });
142
+
143
+ // Status command
144
+ pi.registerCommand("env-loader-status", {
145
+ description: "Show dotenv-loader status and loaded .env files",
146
+ handler: async (_args, ctx) => {
147
+ const filesStr = process.env.ENV_LOADER_FILES || ".env";
148
+ const override = process.env.ENV_LOADER_OVERRIDE === "true";
149
+ const paths = filesStr.split(",").map((f) => resolve(cwd, f.trim()));
150
+
151
+ const lines = [
152
+ "dotenv-loader status:",
153
+ ` cwd: ${cwd}`,
154
+ ` files: ${paths.join(", ")}`,
155
+ ` override: ${override}`,
156
+ ` silent: ${silent}`,
157
+ ` encoding: ${process.env.ENV_LOADER_ENCODING || "utf-8"}`,
158
+ "",
159
+ "Last load result:",
160
+ ` loaded: ${result.loaded}`,
161
+ ` skipped: ${result.skipped}`,
162
+ ...result.files.map(
163
+ (f) => ` ${f.path}: ${f.existed ? `${f.vars} vars` : "not found"}`,
164
+ ),
165
+ ];
166
+
167
+ ctx.ui.notify(lines.join("\n"), "info");
168
+ },
169
+ });
170
+ }
@@ -0,0 +1,59 @@
1
+ type ToolLike = { name: string };
2
+ type ContextLike = { tools?: ToolLike[] };
3
+
4
+ export function parseCursorTranscriptToolCalls(
5
+ text: string,
6
+ context: ContextLike,
7
+ ): Array<{ name: string; arguments: Record<string, unknown> }> {
8
+ const tools = context.tools;
9
+ if (!tools || tools.length === 0) {
10
+ return [];
11
+ }
12
+
13
+ const normalizeToolName = (raw: string): string | undefined => {
14
+ const trimmed = raw.trim().toLowerCase();
15
+ const aliases: Record<string, string[]> = {
16
+ read: ["ReadFile", "Read", "readfile", "read"],
17
+ write: ["Write", "write"],
18
+ edit: ["Edit", "edit", "ApplyPatch", "applypatch"],
19
+ glob: ["Glob", "glob"],
20
+ grep: ["rg", "RG", "Grep", "grep"],
21
+ shell: ["Shell", "shell", "bash", "Bash"],
22
+ bash: ["Shell", "shell", "bash", "Bash"],
23
+ };
24
+ const candidates = aliases[trimmed] ?? [raw];
25
+ for (const candidate of candidates) {
26
+ const exact = tools.find((tool) => tool.name === candidate);
27
+ if (exact) return exact.name;
28
+ const insensitive = tools.find((tool) => tool.name.toLowerCase() === candidate.toLowerCase());
29
+ if (insensitive) return insensitive.name;
30
+ }
31
+ return undefined;
32
+ };
33
+
34
+ const blockRegex = /⏺\s*([a-zA-Z0-9._-]+)[\s\S]*?```json\s*([\s\S]*?)```/g;
35
+ let match: RegExpExecArray | null = null;
36
+ const parsedCalls: Array<{ name: string; arguments: Record<string, unknown> }> = [];
37
+ while ((match = blockRegex.exec(text)) !== null) {
38
+ const rawToolName = match[1] ?? "";
39
+ const mappedName = normalizeToolName(rawToolName);
40
+ if (!mappedName) continue;
41
+ const rawArgs = (match[2] ?? "").trim();
42
+ if (!rawArgs) {
43
+ parsedCalls.push({ name: mappedName, arguments: {} });
44
+ continue;
45
+ }
46
+ try {
47
+ const parsed = JSON.parse(rawArgs);
48
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
49
+ parsedCalls.push({ name: mappedName, arguments: {} });
50
+ continue;
51
+ }
52
+ parsedCalls.push({ name: mappedName, arguments: parsed as Record<string, unknown> });
53
+ } catch {
54
+ parsedCalls.push({ name: mappedName, arguments: {} });
55
+ }
56
+ }
57
+
58
+ return parsedCalls;
59
+ }