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.
- package/.agents/skills/graphify/.graphify_version +1 -0
- package/.agents/skills/graphify/SKILL.md +1204 -0
- package/.agents/skills/wiki-autoresearch/SKILL.md +225 -97
- package/.agents/skills/wiki-autoresearch/references/program.md +28 -62
- package/.agents/skills/wiki-autoresearch/references/quality-sites.md +32 -0
- package/.env.example +5 -1
- package/.gitattributes +1 -0
- package/.github/workflows/publish-github-packages.yml +1 -1
- package/.pi/SYSTEM.md +72 -18
- package/.pi/agents/harness/adversary.md +32 -0
- package/.pi/agents/harness/evaluator.md +32 -0
- package/.pi/agents/harness/executor.md +34 -0
- package/.pi/agents/harness/meta-optimizer.md +33 -0
- package/.pi/agents/harness/planner.md +33 -0
- package/.pi/agents/harness/tie-breaker.md +35 -0
- package/.pi/agents/harness/trace-librarian.md +32 -0
- package/.pi/extensions/banner.png +0 -0
- package/.pi/extensions/budget-guard.ts +265 -0
- package/.pi/extensions/custom-footer.ts +194 -22
- package/.pi/extensions/custom-header.ts +47 -9
- package/.pi/extensions/debate-orchestrator.ts +479 -0
- package/.pi/extensions/harness-live-widget.ts +438 -0
- package/.pi/extensions/policy-gate.ts +349 -0
- package/.pi/extensions/review-integrity.ts +198 -0
- package/.pi/extensions/test-diff-integrity.ts +240 -0
- package/.pi/extensions/trace-recorder.ts +315 -0
- package/.pi/harness/README.md +23 -0
- package/.pi/harness/router/README.md +35 -0
- package/.pi/harness/router/apply-router-proposal.mjs +153 -0
- package/.pi/harness/router/propose-router-tuning.mjs +149 -0
- package/.pi/harness/specs/README.md +37 -0
- package/.pi/harness/specs/adversary-report.schema.json +53 -0
- package/.pi/harness/specs/budget-exhausted-event.schema.json +93 -0
- package/.pi/harness/specs/consensus-packet.schema.json +175 -0
- package/.pi/harness/specs/eval-verdict.schema.json +59 -0
- package/.pi/harness/specs/incident-record.schema.json +84 -0
- package/.pi/harness/specs/plan-packet.schema.json +90 -0
- package/.pi/harness/specs/round-result.schema.json +126 -0
- package/.pi/harness/specs/router-tuning-proposal.schema.json +114 -0
- package/.pi/harness/specs/run-trace.schema.json +107 -0
- package/.pi/lib/harness-ui-state.ts +311 -0
- package/.pi/mcp.json +4 -0
- package/.pi/model-router.json +93 -93
- package/.pi/prompts/graphify.md +23 -0
- package/.pi/prompts/harness-abort.md +41 -0
- package/.pi/prompts/harness-auto.md +83 -0
- package/.pi/prompts/harness-critic.md +52 -0
- package/.pi/prompts/harness-eval.md +51 -0
- package/.pi/prompts/harness-incident.md +51 -0
- package/.pi/prompts/harness-plan.md +64 -0
- package/.pi/prompts/harness-review.md +52 -0
- package/.pi/prompts/harness-router-tune.md +74 -0
- package/.pi/prompts/harness-run.md +59 -0
- package/.pi/prompts/harness-setup.md +316 -216
- package/.pi/prompts/harness-trace.md +51 -0
- package/.pi/prompts/wiki-autoresearch.md +9 -7
- package/.pi/prompts/wiki-save.md +20 -0
- package/.pi/skills/agent-router/SKILL.md +2 -4
- package/.pi/skills/ast-grep/SKILL.md +354 -0
- package/.pi/sounds/project-sounds.json +18 -24
- package/AGENTS.md +30 -0
- package/CHANGELOG.md +89 -0
- package/CONTRIBUTING.md +51 -1
- package/README.md +264 -20
- package/biome.json +8 -2
- package/lefthook.yml +3 -2
- package/node_modules/@sting8k/pi-vcc/README.md +200 -0
- package/node_modules/@sting8k/pi-vcc/index.ts +14 -0
- package/node_modules/@sting8k/pi-vcc/package.json +26 -0
- package/node_modules/@sting8k/pi-vcc/scripts/audit-sessions.ts +88 -0
- package/node_modules/@sting8k/pi-vcc/scripts/benchmark-real-sessions.ts +25 -0
- package/node_modules/@sting8k/pi-vcc/scripts/compare-before-after.ts +36 -0
- package/node_modules/@sting8k/pi-vcc/scripts/dump-branch-output.ts +20 -0
- package/node_modules/@sting8k/pi-vcc/src/commands/pi-vcc.ts +36 -0
- package/node_modules/@sting8k/pi-vcc/src/commands/vcc-recall.ts +65 -0
- package/node_modules/@sting8k/pi-vcc/src/core/brief.ts +381 -0
- package/node_modules/@sting8k/pi-vcc/src/core/build-sections.ts +79 -0
- package/node_modules/@sting8k/pi-vcc/src/core/content.ts +60 -0
- package/node_modules/@sting8k/pi-vcc/src/core/filter-noise.ts +42 -0
- package/node_modules/@sting8k/pi-vcc/src/core/format-recall.ts +27 -0
- package/node_modules/@sting8k/pi-vcc/src/core/format.ts +49 -0
- package/node_modules/@sting8k/pi-vcc/src/core/lineage.ts +26 -0
- package/node_modules/@sting8k/pi-vcc/src/core/load-messages.ts +41 -0
- package/node_modules/@sting8k/pi-vcc/src/core/normalize.ts +66 -0
- package/node_modules/@sting8k/pi-vcc/src/core/recall-scope.ts +14 -0
- package/node_modules/@sting8k/pi-vcc/src/core/render-entries.ts +55 -0
- package/node_modules/@sting8k/pi-vcc/src/core/report.ts +237 -0
- package/node_modules/@sting8k/pi-vcc/src/core/sanitize.ts +5 -0
- package/node_modules/@sting8k/pi-vcc/src/core/search-entries.ts +221 -0
- package/node_modules/@sting8k/pi-vcc/src/core/settings.ts +77 -0
- package/node_modules/@sting8k/pi-vcc/src/core/skill-collapse.ts +35 -0
- package/node_modules/@sting8k/pi-vcc/src/core/summarize.ts +157 -0
- package/node_modules/@sting8k/pi-vcc/src/core/tool-args.ts +14 -0
- package/node_modules/@sting8k/pi-vcc/src/details.ts +7 -0
- package/node_modules/@sting8k/pi-vcc/src/extract/commits.ts +69 -0
- package/node_modules/@sting8k/pi-vcc/src/extract/files.ts +80 -0
- package/node_modules/@sting8k/pi-vcc/src/extract/goals.ts +79 -0
- package/node_modules/@sting8k/pi-vcc/src/extract/preferences.ts +55 -0
- package/node_modules/@sting8k/pi-vcc/src/hooks/before-compact.ts +322 -0
- package/node_modules/@sting8k/pi-vcc/src/sections.ts +12 -0
- package/node_modules/@sting8k/pi-vcc/src/tools/recall.ts +109 -0
- package/node_modules/@sting8k/pi-vcc/src/types.ts +14 -0
- package/node_modules/@sting8k/pi-vcc/tests/before-compact-hook.test.ts +181 -0
- package/node_modules/@sting8k/pi-vcc/tests/before-compact.test.ts +140 -0
- package/node_modules/@sting8k/pi-vcc/tests/brief.test.ts +206 -0
- package/node_modules/@sting8k/pi-vcc/tests/build-sections.test.ts +59 -0
- package/node_modules/@sting8k/pi-vcc/tests/compile.test.ts +80 -0
- package/node_modules/@sting8k/pi-vcc/tests/content.test.ts +31 -0
- package/node_modules/@sting8k/pi-vcc/tests/extract-goals.test.ts +86 -0
- package/node_modules/@sting8k/pi-vcc/tests/extract-preferences.test.ts +30 -0
- package/node_modules/@sting8k/pi-vcc/tests/filter-noise.test.ts +61 -0
- package/node_modules/@sting8k/pi-vcc/tests/fixtures.ts +61 -0
- package/node_modules/@sting8k/pi-vcc/tests/format-recall.test.ts +30 -0
- package/node_modules/@sting8k/pi-vcc/tests/format.test.ts +62 -0
- package/node_modules/@sting8k/pi-vcc/tests/lineage.test.ts +33 -0
- package/node_modules/@sting8k/pi-vcc/tests/load-messages.test.ts +51 -0
- package/node_modules/@sting8k/pi-vcc/tests/normalize.test.ts +97 -0
- package/node_modules/@sting8k/pi-vcc/tests/real-sessions.test.ts +38 -0
- package/node_modules/@sting8k/pi-vcc/tests/recall-expand.test.ts +15 -0
- package/node_modules/@sting8k/pi-vcc/tests/recall-scope.test.ts +32 -0
- package/node_modules/@sting8k/pi-vcc/tests/recall-tool-scope.test.ts +67 -0
- package/node_modules/@sting8k/pi-vcc/tests/render-entries.test.ts +62 -0
- package/node_modules/@sting8k/pi-vcc/tests/report.test.ts +44 -0
- package/node_modules/@sting8k/pi-vcc/tests/sanitize.test.ts +24 -0
- package/node_modules/@sting8k/pi-vcc/tests/search-entries.test.ts +144 -0
- package/node_modules/@sting8k/pi-vcc/tests/support/load-session.ts +23 -0
- package/node_modules/@sting8k/pi-vcc/tests/support/real-sessions.ts +51 -0
- package/package.json +15 -4
- package/scripts/__pycache__/merge_graphify_corpora.cpython-314.pyc +0 -0
- package/scripts/index_youtube_urls.py +376 -0
- package/scripts/merge_graphify_corpora.py +398 -0
- package/scripts/regen_graphify_html.py +46 -0
- package/.agents/skills/defuddle/SKILL.md +0 -90
- package/.agents/skills/wiki/SKILL.md +0 -215
- package/.agents/skills/wiki/references/css-snippets.md +0 -122
- package/.agents/skills/wiki/references/frontmatter.md +0 -107
- package/.agents/skills/wiki/references/git-setup.md +0 -58
- package/.agents/skills/wiki/references/mcp-setup.md +0 -149
- package/.agents/skills/wiki/references/modes.md +0 -259
- package/.agents/skills/wiki/references/plugins.md +0 -96
- package/.agents/skills/wiki/references/rest-api.md +0 -124
- package/.agents/skills/wiki-fold/SKILL.md +0 -204
- package/.agents/skills/wiki-fold/references/fold-template.md +0 -133
- package/.agents/skills/wiki-ingest/SKILL.md +0 -288
- package/.agents/skills/wiki-lint/SKILL.md +0 -183
- package/.agents/skills/wiki-query/SKILL.md +0 -176
- package/.pi/agents/rethink.md +0 -140
- package/.pi/agents/wiki-ingest.md +0 -67
- package/.pi/agents/wiki-lint.md +0 -75
- package/.pi/internal/cursor-sdk-transcript-parser.ts +0 -59
- package/.pi/prompts/save.md +0 -16
- package/.pi/prompts/wiki.md +0 -23
- package/.pi/providers/cursor-sdk-provider.test.mjs +0 -476
- package/.pi/providers/cursor-sdk-provider.ts +0 -1085
- package/vault/AGENTS.md +0 -37
- package/vault/wiki/_templates/comparison.md +0 -39
- package/vault/wiki/_templates/concept.md +0 -40
- package/vault/wiki/_templates/decision.md +0 -21
- package/vault/wiki/_templates/entity.md +0 -32
- package/vault/wiki/_templates/flow.md +0 -14
- package/vault/wiki/_templates/module.md +0 -18
- package/vault/wiki/_templates/question.md +0 -31
- package/vault/wiki/_templates/source.md +0 -39
- package/vault/wiki/concepts/AST-Aware Code Chunking.md +0 -44
- package/vault/wiki/concepts/Build-Time Prompt Compilation.md +0 -107
- package/vault/wiki/concepts/Context Engine (AI Coding).md +0 -47
- package/vault/wiki/concepts/Context-Aware System Reminders.md +0 -61
- package/vault/wiki/concepts/Contextualized Text Embedding.md +0 -42
- package/vault/wiki/concepts/Contractor vs Employee AI Model.md +0 -55
- package/vault/wiki/concepts/Dual-Model Agent Architecture.md +0 -65
- package/vault/wiki/concepts/Late Chunking vs Early Chunking.md +0 -43
- package/vault/wiki/concepts/Majority Vote Ensembling.md +0 -68
- package/vault/wiki/concepts/Meta-Harness.md +0 -16
- package/vault/wiki/concepts/Multi-Agent AI Coding Architecture.md +0 -75
- package/vault/wiki/concepts/Prompt Enhancement.md +0 -90
- package/vault/wiki/concepts/Prompt Renderer.md +0 -89
- package/vault/wiki/concepts/Semantic Codebase Indexing.md +0 -67
- package/vault/wiki/concepts/additive-config-hierarchy.md +0 -16
- package/vault/wiki/concepts/agent-artifacts-verifiable-deliverables.md +0 -71
- package/vault/wiki/concepts/agent-browser-browser-automation.md +0 -99
- package/vault/wiki/concepts/agent-codebase-interface.md +0 -43
- package/vault/wiki/concepts/agent-harness-architecture.md +0 -67
- package/vault/wiki/concepts/agent-loop-detection-patterns.md +0 -133
- package/vault/wiki/concepts/agent-search-enforcement.md +0 -126
- package/vault/wiki/concepts/agent-skills-ecosystem.md +0 -74
- package/vault/wiki/concepts/agent-skills-pattern.md +0 -68
- package/vault/wiki/concepts/agentic-harness-context-enforcement.md +0 -91
- package/vault/wiki/concepts/agentic-harness.md +0 -34
- package/vault/wiki/concepts/agentic-orchestration-pipeline.md +0 -56
- package/vault/wiki/concepts/agentic-search-no-embeddings.md +0 -18
- package/vault/wiki/concepts/anthropic-context-engineering.md +0 -13
- package/vault/wiki/concepts/antigravity-agent-first-architecture.md +0 -61
- package/vault/wiki/concepts/ast-compression.md +0 -19
- package/vault/wiki/concepts/ast-truncation.md +0 -66
- package/vault/wiki/concepts/barrel-files.md +0 -37
- package/vault/wiki/concepts/browser-harness-agent.md +0 -41
- package/vault/wiki/concepts/browser-subagent-visual-verification.md +0 -82
- package/vault/wiki/concepts/codebase-intelligence-ecosystem-comparison.md +0 -192
- package/vault/wiki/concepts/codebase-intelligence-harness-integration.md +0 -161
- package/vault/wiki/concepts/codebase-to-context-ingestion.md +0 -46
- package/vault/wiki/concepts/codex-harness-innovations.md +0 -147
- package/vault/wiki/concepts/consensus-debate-flow.md +0 -17
- package/vault/wiki/concepts/consensus-debate.md +0 -206
- package/vault/wiki/concepts/content-addressed-spec-identity.md +0 -166
- package/vault/wiki/concepts/context-anxiety.md +0 -57
- package/vault/wiki/concepts/context-compression-techniques.md +0 -19
- package/vault/wiki/concepts/context-continuity.md +0 -22
- package/vault/wiki/concepts/context-drift-in-agents.md +0 -106
- package/vault/wiki/concepts/context-engineering.md +0 -62
- package/vault/wiki/concepts/context-folding.md +0 -67
- package/vault/wiki/concepts/context-mode.md +0 -38
- package/vault/wiki/concepts/cursor-harness-innovations.md +0 -107
- package/vault/wiki/concepts/deterministic-session-compaction.md +0 -79
- package/vault/wiki/concepts/drift-detection-unified.md +0 -296
- package/vault/wiki/concepts/execution-feedback-loop.md +0 -46
- package/vault/wiki/concepts/feedforward-feedback-harness.md +0 -60
- package/vault/wiki/concepts/five-root-cause-metrics-sentrux.md +0 -40
- package/vault/wiki/concepts/fork-safe-spec-storage.md +0 -89
- package/vault/wiki/concepts/fts5-sandbox.md +0 -19
- package/vault/wiki/concepts/fuzzy-edit-matching.md +0 -71
- package/vault/wiki/concepts/gemini-cli-architecture.md +0 -104
- package/vault/wiki/concepts/generator-evaluator-architecture.md +0 -64
- package/vault/wiki/concepts/guardian-agent-pattern.md +0 -67
- package/vault/wiki/concepts/harness-configuration-layers.md +0 -89
- package/vault/wiki/concepts/harness-control-frameworks.md +0 -155
- package/vault/wiki/concepts/harness-engineering-first-principles.md +0 -90
- package/vault/wiki/concepts/harness-h-formalism.md +0 -53
- package/vault/wiki/concepts/hybrid-code-search.md +0 -61
- package/vault/wiki/concepts/inline-post-edit-validation.md +0 -112
- package/vault/wiki/concepts/legendary-engineering-patterns-harness.md +0 -110
- package/vault/wiki/concepts/lifecycle-hooks.md +0 -94
- package/vault/wiki/concepts/mcp-tool-routing.md +0 -102
- package/vault/wiki/concepts/memory-system-of-record-vs-ephemeral-cache.md +0 -47
- package/vault/wiki/concepts/meta-agent-context-pruning.md +0 -151
- package/vault/wiki/concepts/model-adaptive-harness.md +0 -122
- package/vault/wiki/concepts/model-routing-agents.md +0 -101
- package/vault/wiki/concepts/monorepo-architecture.md +0 -45
- package/vault/wiki/concepts/multi-agent-specialization.md +0 -61
- package/vault/wiki/concepts/permission-subsystem.md +0 -16
- package/vault/wiki/concepts/pi-messenger-analysis.md +0 -243
- package/vault/wiki/concepts/pi-vscode-extension-landscape.md +0 -37
- package/vault/wiki/concepts/policy-engine-pattern.md +0 -78
- package/vault/wiki/concepts/progressive-disclosure-agents.md +0 -53
- package/vault/wiki/concepts/progressive-skill-disclosure.md +0 -17
- package/vault/wiki/concepts/provider-native-prompting.md +0 -203
- package/vault/wiki/concepts/quality-signal-sentrux.md +0 -37
- package/vault/wiki/concepts/repo-map-ranking.md +0 -42
- package/vault/wiki/concepts/result-monad-error-handling.md +0 -47
- package/vault/wiki/concepts/safety-defense-in-depth.md +0 -83
- package/vault/wiki/concepts/sandbox-os-enforcement.md +0 -18
- package/vault/wiki/concepts/selective-debate-routing.md +0 -70
- package/vault/wiki/concepts/self-evolving-harness.md +0 -60
- package/vault/wiki/concepts/sentrux-mcp-integration.md +0 -36
- package/vault/wiki/concepts/sentrux-rules-engine.md +0 -49
- package/vault/wiki/concepts/shell-pattern-compression.md +0 -24
- package/vault/wiki/concepts/skill-first-architecture.md +0 -166
- package/vault/wiki/concepts/structured-compaction.md +0 -78
- package/vault/wiki/concepts/subagent-orchestration.md +0 -17
- package/vault/wiki/concepts/subagent-worktree-isolation.md +0 -68
- package/vault/wiki/concepts/superpowers-methodology.md +0 -78
- package/vault/wiki/concepts/think-in-code.md +0 -73
- package/vault/wiki/concepts/ts-execution-layer.md +0 -100
- package/vault/wiki/concepts/typescript-strict-mode.md +0 -37
- package/vault/wiki/concepts/vcc-conversation-compaction-for-pi.md +0 -53
- package/vault/wiki/concepts/verification-drift-detection.md +0 -19
- package/vault/wiki/consensus/consensus-records.md +0 -58
- package/vault/wiki/decisions/2026-04-30-pi-lean-ctx-native.md +0 -122
- package/vault/wiki/decisions/2026-05-07-replace-lean-ctx-with-context-mode.md +0 -59
- package/vault/wiki/decisions/adr-008.md +0 -40
- package/vault/wiki/decisions/adr-009.md +0 -46
- package/vault/wiki/decisions/adr-010.md +0 -55
- package/vault/wiki/decisions/adr-011.md +0 -165
- package/vault/wiki/decisions/adr-012.md +0 -102
- package/vault/wiki/decisions/adr-013.md +0 -59
- package/vault/wiki/decisions/adr-014.md +0 -73
- package/vault/wiki/decisions/adr-015.md +0 -81
- package/vault/wiki/decisions/adr-016.md +0 -91
- package/vault/wiki/decisions/adr-017.md +0 -79
- package/vault/wiki/decisions/adr-018.md +0 -100
- package/vault/wiki/decisions/adr-019.md +0 -75
- package/vault/wiki/decisions/adr-020.md +0 -106
- package/vault/wiki/decisions/adr-021.md +0 -86
- package/vault/wiki/decisions/adr-022.md +0 -113
- package/vault/wiki/decisions/adr-023.md +0 -113
- package/vault/wiki/decisions/adr-024.md +0 -73
- package/vault/wiki/decisions/adr-025.md +0 -130
- package/vault/wiki/decisions/adr-026.md +0 -56
- package/vault/wiki/decisions/adr-027.md +0 -94
- package/vault/wiki/decisions/colocate-wiki.md +0 -34
- package/vault/wiki/entities/Anders Hejlsberg.md +0 -29
- package/vault/wiki/entities/Anthropic.md +0 -17
- package/vault/wiki/entities/Augment Code.md +0 -49
- package/vault/wiki/entities/Bjarne Stroustrup.md +0 -26
- package/vault/wiki/entities/Bolt.new (StackBlitz).md +0 -39
- package/vault/wiki/entities/Boris Cherny.md +0 -11
- package/vault/wiki/entities/Claude Code.md +0 -19
- package/vault/wiki/entities/Dennis Ritchie.md +0 -26
- package/vault/wiki/entities/Emergent Labs.md +0 -32
- package/vault/wiki/entities/Google Cloud.md +0 -16
- package/vault/wiki/entities/Guido van Rossum.md +0 -28
- package/vault/wiki/entities/Ken Thompson.md +0 -28
- package/vault/wiki/entities/Lee et al.md +0 -16
- package/vault/wiki/entities/Linus Torvalds.md +0 -28
- package/vault/wiki/entities/Lovable (company).md +0 -40
- package/vault/wiki/entities/Martin Fowler.md +0 -16
- package/vault/wiki/entities/Meng et al.md +0 -16
- package/vault/wiki/entities/OpenAI.md +0 -16
- package/vault/wiki/entities/Rocket.new.md +0 -38
- package/vault/wiki/entities/VILA-Lab.md +0 -15
- package/vault/wiki/entities/autodev-codebase.md +0 -18
- package/vault/wiki/entities/ck-tool.md +0 -59
- package/vault/wiki/entities/codesearch.md +0 -18
- package/vault/wiki/entities/disler-indydevdan.md +0 -33
- package/vault/wiki/entities/gsd-get-shit-done.md +0 -56
- package/vault/wiki/entities/javascript-runtimes.md +0 -48
- package/vault/wiki/entities/jesse-vincent.md +0 -38
- package/vault/wiki/entities/lean-ctx.md +0 -32
- package/vault/wiki/entities/opendev.md +0 -41
- package/vault/wiki/entities/ops-codegraph-tool.md +0 -18
- package/vault/wiki/entities/pi-coding-agent.md +0 -53
- package/vault/wiki/entities/sentrux.md +0 -54
- package/vault/wiki/entities/vgrep-tool.md +0 -57
- package/vault/wiki/entities/vitest.md +0 -41
- package/vault/wiki/flows/harness-wiki-pipeline.md +0 -204
- package/vault/wiki/hot.md +0 -932
- package/vault/wiki/index.md +0 -437
- package/vault/wiki/log.md +0 -422
- package/vault/wiki/meta/dashboard.md +0 -30
- package/vault/wiki/meta/lint-report-2026-04-30.md +0 -86
- package/vault/wiki/meta/lint-report-2026-05-02.md +0 -251
- package/vault/wiki/meta/overview.canvas +0 -43
- package/vault/wiki/modules/adversarial-verification.md +0 -57
- package/vault/wiki/modules/automated-observability.md +0 -54
- package/vault/wiki/modules/bench.md +0 -20
- package/vault/wiki/modules/extensions.md +0 -23
- package/vault/wiki/modules/grounding-checkpoints.md +0 -62
- package/vault/wiki/modules/harness-implementation-plan.md +0 -345
- package/vault/wiki/modules/harness-wiki-skill-mapping.md +0 -135
- package/vault/wiki/modules/harness.md +0 -86
- package/vault/wiki/modules/persistent-memory.md +0 -85
- package/vault/wiki/modules/schema-orchestration.md +0 -68
- package/vault/wiki/modules/skills.md +0 -27
- package/vault/wiki/modules/spec-hardening.md +0 -58
- package/vault/wiki/modules/structured-planning.md +0 -53
- package/vault/wiki/modules/think-in-code-enforcement.md +0 -153
- package/vault/wiki/modules/wiki-query-interface.md +0 -64
- package/vault/wiki/overview.md +0 -51
- package/vault/wiki/questions/Research-pi-vs-claude-code-agentic-orchestration-pipeline.md +0 -87
- package/vault/wiki/questions/Research-sentrux-dev.md +0 -123
- package/vault/wiki/questions/Research-superpowers-skill-for-agentic-coding-agents.md +0 -164
- package/vault/wiki/questions/Research: Augment Code Context Engine.md +0 -244
- package/vault/wiki/questions/Research: Automating Software Engineering - Lovable, Bolt, Emergent, Rocket.md +0 -112
- package/vault/wiki/questions/Research: Claude Code State-of-the-Art Harness Improvements.md +0 -209
- package/vault/wiki/questions/Research: Codex State-of-the-Art Harness Improvements.md +0 -99
- package/vault/wiki/questions/Research: Engineering Workflows of Legendary Programmers and AI Harness Mapping.md +0 -107
- package/vault/wiki/questions/Research: Fallow Codebase Intelligence Harness Integration.md +0 -72
- package/vault/wiki/questions/Research: Gemini CLI SOTA Harness Integration.md +0 -166
- package/vault/wiki/questions/Research: GitHub Issues as Harness Spec Storage.md +0 -188
- package/vault/wiki/questions/Research: Google Antigravity Harness Integration.md +0 -120
- package/vault/wiki/questions/Research: Meta-Agent Context Drift Detection.md +0 -236
- package/vault/wiki/questions/Research: Model-Adaptive Agent Harness Design.md +0 -95
- package/vault/wiki/questions/Research: Model-Specific Prompting Guides.md +0 -165
- package/vault/wiki/questions/Research: Prompt Renderer for Multi-Model Agent Harness.md +0 -216
- package/vault/wiki/questions/Research: Skill-First Harness Architecture.md +0 -91
- package/vault/wiki/questions/Research: TypeScript Best Practices and Codebase Structure.md +0 -88
- package/vault/wiki/questions/Research: TypeScript Execution Layer for Agent Tool Calling.md +0 -81
- package/vault/wiki/questions/Research: claude-mem over Obsidian for Harness Layer.md +0 -71
- 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
- package/vault/wiki/questions/Research: context-mode vs lean-ctx.md +0 -72
- package/vault/wiki/questions/Research: cursor.sh Harness Innovations.md +0 -92
- package/vault/wiki/questions/Research: executor.sh Harness Integration.md +0 -170
- package/vault/wiki/questions/Research: how GSD fits into our coding harness setup.md +0 -97
- 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
- package/vault/wiki/questions/Research: pi-vcc.md +0 -113
- package/vault/wiki/questions/Research: semantic code search tools.md +0 -69
- package/vault/wiki/questions/Research: vcc extension for pi coding agent.md +0 -73
- package/vault/wiki/questions/how-to-enable-semantic-code-search-now.md +0 -111
- package/vault/wiki/questions/mvp-implementation-blueprint.md +0 -552
- package/vault/wiki/questions/research-agent-first-codebase-exploration.md +0 -199
- package/vault/wiki/questions/research-agentic-coding-harness-latest-papers.md +0 -142
- package/vault/wiki/questions/research-gitingest-gitreverse-integration.md +0 -100
- package/vault/wiki/questions/research-wozcode-token-reduction.md +0 -67
- package/vault/wiki/questions/resolved-context-pruning-inplace-vs-restart.md +0 -95
- package/vault/wiki/questions/resolved-context-window-economics.md +0 -167
- package/vault/wiki/questions/resolved-imad-debate-gating-transfer.md +0 -126
- package/vault/wiki/questions/resolved-mcp-tool-preference.md +0 -112
- package/vault/wiki/questions/resolved-small-model-meta-agents.md +0 -107
- package/vault/wiki/questions/resolved-treesitter-dynamic-languages.md +0 -95
- package/vault/wiki/sources/Auggie Context MCP Server.md +0 -63
- package/vault/wiki/sources/Augment Code Codacy AI Giants.md +0 -61
- package/vault/wiki/sources/Augment Code MCP SiliconAngle.md +0 -49
- package/vault/wiki/sources/Augment Code WorkOS ERC 2025.md +0 -55
- package/vault/wiki/sources/Augment Context Engine Official.md +0 -71
- package/vault/wiki/sources/Augment SWE-bench Agent GitHub.md +0 -74
- package/vault/wiki/sources/Augment SWE-bench Pro Blog.md +0 -58
- package/vault/wiki/sources/Source: AgentBus Jinja2 Prompt Pipelines.md +0 -75
- package/vault/wiki/sources/Source: Arxiv /342/200/224 Don't Break the Cache.md" +0 -85
- package/vault/wiki/sources/Source: Augment - Harness Engineering for AI Coding Agents.md +0 -58
- package/vault/wiki/sources/Source: Blake Crosley Agent Architecture Guide.md +0 -100
- package/vault/wiki/sources/Source: Bolt.new Architecture & Case Study.md +0 -75
- package/vault/wiki/sources/Source: Build-Time Prompt Compilation Architecture.md +0 -107
- package/vault/wiki/sources/Source: Claude API Agent Skills Overview.md +0 -70
- package/vault/wiki/sources/Source: Gemini CLI Changelogs.md +0 -88
- package/vault/wiki/sources/Source: Google Blog - Gemini CLI Announcement.md +0 -57
- package/vault/wiki/sources/Source: Google Gemini CLI Architecture Docs.md +0 -53
- package/vault/wiki/sources/Source: LangChain - Anatomy of Agent Harness.md +0 -65
- package/vault/wiki/sources/Source: Lovable Architecture & Clone Analysis.md +0 -83
- package/vault/wiki/sources/Source: Martin Fowler - Harness Engineering.md +0 -70
- package/vault/wiki/sources/Source: OpenAI Harness Engineering Five Principles.md +0 -58
- package/vault/wiki/sources/Source: OpenAI Harness Engineering /342/200/224 0 Lines of Human Code.md" +0 -101
- package/vault/wiki/sources/Source: OpenDev /342/200/224 Building AI Coding Agents for the Terminal.md" +0 -100
- package/vault/wiki/sources/Source: Render AI Coding Agents Benchmark 2025.md +0 -53
- package/vault/wiki/sources/Source: Rocket.new /342/200/224 Vibe Solutioning Platform.md" +0 -70
- package/vault/wiki/sources/Source: SwirlAI Agent Skills Progressive Disclosure.md +0 -71
- package/vault/wiki/sources/Source: TianPan Prompt Caching Architecture.md +0 -89
- package/vault/wiki/sources/Source: Vercel Labs agent-browser.md +0 -155
- package/vault/wiki/sources/Source: browser-harness CDP Harness.md +0 -126
- package/vault/wiki/sources/agent-drift-academic-paper.md +0 -79
- package/vault/wiki/sources/aider-repomap-tree-sitter.md +0 -42
- package/vault/wiki/sources/anthropic-compaction-api.md +0 -58
- package/vault/wiki/sources/anthropic-effective-harnesses.md +0 -42
- package/vault/wiki/sources/anthropic-prompt-best-practices.md +0 -100
- package/vault/wiki/sources/anthropic2026-harness-design.md +0 -63
- package/vault/wiki/sources/barrel-files-tkdodo.md +0 -38
- package/vault/wiki/sources/birth-of-unix-kernighan-interview.md +0 -57
- package/vault/wiki/sources/bockeler2026-harness-engineering.md +0 -69
- package/vault/wiki/sources/cast-code-chunking-paper.md +0 -50
- package/vault/wiki/sources/ck-semantic-search.md +0 -78
- package/vault/wiki/sources/claude-code-architecture-karaxai-2026.md +0 -71
- package/vault/wiki/sources/claude-code-architecture-qubytes-2026.md +0 -50
- package/vault/wiki/sources/claude-code-architecture-vila-lab-2026.md +0 -64
- package/vault/wiki/sources/claude-code-security-architecture-penligent-2026.md +0 -70
- package/vault/wiki/sources/claude-context-editing-docs.md +0 -13
- package/vault/wiki/sources/cloudflare-codemode.md +0 -63
- package/vault/wiki/sources/code-chunk-library-supermemory.md +0 -63
- package/vault/wiki/sources/codeact-apple-2024.md +0 -62
- package/vault/wiki/sources/codex-dsc-rfc-8573.md +0 -41
- package/vault/wiki/sources/codex-open-source-agent-2026.md +0 -110
- package/vault/wiki/sources/coir-code-retrieval-benchmark.md +0 -51
- package/vault/wiki/sources/colinmcnamara-context-optimization-codemode.md +0 -48
- package/vault/wiki/sources/context-folding-paper.md +0 -61
- package/vault/wiki/sources/context-mode-website.md +0 -63
- package/vault/wiki/sources/cursor-agent-best-practices-2026.md +0 -62
- package/vault/wiki/sources/cursor-fork-29b-2025.md +0 -50
- package/vault/wiki/sources/cursor-harness-april-2026.md +0 -76
- package/vault/wiki/sources/cursor-instant-apply-2024.md +0 -45
- package/vault/wiki/sources/cursor-shadow-workspace-2024.md +0 -52
- package/vault/wiki/sources/cursor-shipped-coding-agent-2026.md +0 -53
- package/vault/wiki/sources/cursor-vs-antigravity-2026.md +0 -51
- package/vault/wiki/sources/disler-pi-vs-claude-code.md +0 -69
- package/vault/wiki/sources/distill-deterministic-context-compression.md +0 -53
- package/vault/wiki/sources/embedding-models-benchmark-supermemory-2025.md +0 -48
- package/vault/wiki/sources/executor-rhyssullivan.md +0 -122
- package/vault/wiki/sources/fallow-rs-codebase-intelligence.md +0 -125
- package/vault/wiki/sources/fan2025-imad.md +0 -60
- package/vault/wiki/sources/forgecode-gpt5-agent-improvements.md +0 -63
- package/vault/wiki/sources/gemini-3-prompting-guide.md +0 -78
- package/vault/wiki/sources/gh-cli-sub-issue-rfc.md +0 -50
- package/vault/wiki/sources/gh-sub-issue-extension.md +0 -72
- package/vault/wiki/sources/github-fork-issues-discussion.md +0 -44
- package/vault/wiki/sources/github-issue-dependencies-docs.md +0 -49
- package/vault/wiki/sources/github-sub-issues-docs.md +0 -51
- package/vault/wiki/sources/gitingest.md +0 -91
- package/vault/wiki/sources/gitreverse.md +0 -63
- package/vault/wiki/sources/google-antigravity-official-blog.md +0 -47
- package/vault/wiki/sources/google-antigravity-wikipedia.md +0 -53
- package/vault/wiki/sources/gsd-codecentric-deep-dive.md +0 -57
- package/vault/wiki/sources/gsd-github-repo.md +0 -51
- package/vault/wiki/sources/gsd-hn-discussion.md +0 -59
- package/vault/wiki/sources/guido-python-design-philosophy.md +0 -56
- package/vault/wiki/sources/hejlsberg-7-learnings.md +0 -48
- package/vault/wiki/sources/ironclaw-drift-monitor.md +0 -80
- package/vault/wiki/sources/langsight-loop-detection.md +0 -80
- package/vault/wiki/sources/leanctx-website.md +0 -69
- package/vault/wiki/sources/lee2026-meta-harness.md +0 -59
- package/vault/wiki/sources/linux-kernel-coding-workflow.md +0 -50
- package/vault/wiki/sources/lou2026-autoharness.md +0 -53
- package/vault/wiki/sources/martin-fowler-harness-engineering.md +0 -73
- package/vault/wiki/sources/mcp-architecture-docs.md +0 -13
- package/vault/wiki/sources/meng2026-agent-harness-survey.md +0 -79
- package/vault/wiki/sources/mindstudio-four-agent-types.md +0 -68
- package/vault/wiki/sources/ms-chat-history-management.md +0 -13
- package/vault/wiki/sources/openai-prompt-guidance.md +0 -104
- package/vault/wiki/sources/openclaw-session-pruning.md +0 -13
- package/vault/wiki/sources/opencode-dcp.md +0 -13
- package/vault/wiki/sources/opendev-arxiv-2603.05344v1.md +0 -79
- package/vault/wiki/sources/openhands-platform.md +0 -39
- package/vault/wiki/sources/oss-guide-codebase-exploration.md +0 -53
- package/vault/wiki/sources/pi-compaction-extensions-ecosystem.md +0 -102
- package/vault/wiki/sources/pi-context-prune-github-repo.md +0 -38
- package/vault/wiki/sources/pi-mono-compaction-docs.md +0 -38
- package/vault/wiki/sources/pi-omni-compact-github-repo.md +0 -50
- package/vault/wiki/sources/pi-rtk-optimizer-github-repo.md +0 -45
- package/vault/wiki/sources/pi-vcc-github-repo.md +0 -69
- package/vault/wiki/sources/pi-vscode-marketplace.md +0 -41
- package/vault/wiki/sources/pi-vscode-model-provider-marketplace.md +0 -39
- package/vault/wiki/sources/py-tree-sitter.md +0 -13
- package/vault/wiki/sources/sentrux-dev-landing.md +0 -40
- package/vault/wiki/sources/sentrux-docs-pro-architecture.md +0 -75
- package/vault/wiki/sources/sentrux-docs-quality-signal.md +0 -46
- package/vault/wiki/sources/sentrux-docs-root-cause-metrics.md +0 -57
- package/vault/wiki/sources/sentrux-docs-rules-engine.md +0 -58
- package/vault/wiki/sources/sentrux-github-repo.md +0 -56
- package/vault/wiki/sources/superpowers-github-repo.md +0 -56
- package/vault/wiki/sources/superpowers-release-blog.md +0 -54
- package/vault/wiki/sources/superpowers-termdock-analysis.md +0 -45
- package/vault/wiki/sources/swe-agent-aci.md +0 -42
- package/vault/wiki/sources/swe-bench.md +0 -45
- package/vault/wiki/sources/swe-pruner-context-pruning.md +0 -13
- package/vault/wiki/sources/think-in-code-blog.md +0 -48
- package/vault/wiki/sources/tree-sitter-docs.md +0 -13
- package/vault/wiki/sources/ts-best-practices-2025-devto.md +0 -42
- package/vault/wiki/sources/ts-folder-structure-mingyang.md +0 -58
- package/vault/wiki/sources/ts-monorepo-koerselman.md +0 -44
- package/vault/wiki/sources/ts-result-error-handling-kkalamarski.md +0 -52
- package/vault/wiki/sources/ts-runtimes-comparison-betterstack.md +0 -42
- package/vault/wiki/sources/ts-strict-mode-rishikc.md +0 -43
- package/vault/wiki/sources/unix-philosophy.md +0 -48
- package/vault/wiki/sources/vectara-chunking-vs-embedding-naacl2025.md +0 -39
- package/vault/wiki/sources/vectara-guardian-agents.md +0 -79
- package/vault/wiki/sources/vgrep-semantic-search.md +0 -76
- package/vault/wiki/sources/vitest-official.md +0 -41
- package/vault/wiki/sources/vscode-pi-community-extension.md +0 -40
- package/vault/wiki/sources/wozcode.md +0 -79
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import type { Message } from "@mariozechner/pi-ai";
|
|
2
|
+
import { buildSections } from "./build-sections";
|
|
3
|
+
import { clip } from "./content";
|
|
4
|
+
import { normalize } from "./normalize";
|
|
5
|
+
import { renderMessage } from "./render-entries";
|
|
6
|
+
import { searchEntries } from "./search-entries";
|
|
7
|
+
import { type CompileInput, compile } from "./summarize";
|
|
8
|
+
|
|
9
|
+
const SECTION_HEADERS = ["Session Goal", "Files And Changes", "Commits", "Outstanding Context"];
|
|
10
|
+
|
|
11
|
+
interface RoleCounts {
|
|
12
|
+
user: number;
|
|
13
|
+
assistant: number;
|
|
14
|
+
toolResult: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interface BlockCounts {
|
|
18
|
+
user: number;
|
|
19
|
+
assistant: number;
|
|
20
|
+
toolCalls: number;
|
|
21
|
+
toolResults: number;
|
|
22
|
+
thinking: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface RecallProbe {
|
|
26
|
+
label: string;
|
|
27
|
+
sourceText: string;
|
|
28
|
+
query: string;
|
|
29
|
+
summaryMentioned: boolean;
|
|
30
|
+
recallHits: number;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface CompactReport {
|
|
34
|
+
summary: string;
|
|
35
|
+
before: {
|
|
36
|
+
messageCount: number;
|
|
37
|
+
roleCounts: RoleCounts;
|
|
38
|
+
blockCounts: BlockCounts;
|
|
39
|
+
inputChars: number;
|
|
40
|
+
estimatedTokens: number;
|
|
41
|
+
topFiles: string[];
|
|
42
|
+
preview: string;
|
|
43
|
+
};
|
|
44
|
+
after: {
|
|
45
|
+
summaryLength: number;
|
|
46
|
+
estimatedTokens: number;
|
|
47
|
+
sectionCount: number;
|
|
48
|
+
summaryPreview: string;
|
|
49
|
+
goalsCount: number;
|
|
50
|
+
blockersCount: number;
|
|
51
|
+
briefTranscriptLines: number;
|
|
52
|
+
};
|
|
53
|
+
compression: {
|
|
54
|
+
charsBefore: number;
|
|
55
|
+
charsAfter: number;
|
|
56
|
+
ratio: number;
|
|
57
|
+
messagesBefore: number;
|
|
58
|
+
};
|
|
59
|
+
recall: {
|
|
60
|
+
probes: RecallProbe[];
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const estimateTokensFromChars = (chars: number): number =>
|
|
65
|
+
Math.ceil(chars / 4);
|
|
66
|
+
|
|
67
|
+
const countRoles = (messages: Message[]): RoleCounts => {
|
|
68
|
+
const counts: RoleCounts = { user: 0, assistant: 0, toolResult: 0 };
|
|
69
|
+
for (const msg of messages) {
|
|
70
|
+
if (msg.role === "user") counts.user += 1;
|
|
71
|
+
else if (msg.role === "assistant") counts.assistant += 1;
|
|
72
|
+
else if (msg.role === "toolResult") counts.toolResult += 1;
|
|
73
|
+
}
|
|
74
|
+
return counts;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const countBlocks = (messages: Message[]): BlockCounts => {
|
|
78
|
+
const counts: BlockCounts = {
|
|
79
|
+
user: 0,
|
|
80
|
+
assistant: 0,
|
|
81
|
+
toolCalls: 0,
|
|
82
|
+
toolResults: 0,
|
|
83
|
+
thinking: 0,
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
for (const block of normalize(messages)) {
|
|
87
|
+
if (block.kind === "user") counts.user += 1;
|
|
88
|
+
else if (block.kind === "assistant") counts.assistant += 1;
|
|
89
|
+
else if (block.kind === "tool_call") counts.toolCalls += 1;
|
|
90
|
+
else if (block.kind === "tool_result") counts.toolResults += 1;
|
|
91
|
+
else if (block.kind === "thinking") counts.thinking += 1;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return counts;
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const inputCharsOf = (messages: Message[]): number =>
|
|
98
|
+
messages
|
|
99
|
+
.map((msg, index) => renderMessage(msg, index, true).summary.length)
|
|
100
|
+
.reduce((sum, len) => sum + len, 0);
|
|
101
|
+
|
|
102
|
+
const topFilesOf = (messages: Message[]): string[] => {
|
|
103
|
+
const files = new Set<string>();
|
|
104
|
+
for (const block of normalize(messages)) {
|
|
105
|
+
if (block.kind === "tool_call") {
|
|
106
|
+
for (const key of ["path", "file_path", "filePath", "file"]) {
|
|
107
|
+
const val = block.args[key];
|
|
108
|
+
if (typeof val === "string") { files.add(val); break; }
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return [...files].slice(0, 10);
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
const previewOf = (messages: Message[], edgeCount = 3): string => {
|
|
116
|
+
const rendered = messages.map((msg, index) => renderMessage(msg, index));
|
|
117
|
+
if (rendered.length === 0) return "(empty)";
|
|
118
|
+
if (rendered.length <= edgeCount * 2) {
|
|
119
|
+
return rendered
|
|
120
|
+
.map((entry) => `#${entry.index} [${entry.role}] ${clip(entry.summary, 220)}`)
|
|
121
|
+
.join("\n");
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const first = rendered.slice(0, edgeCount);
|
|
125
|
+
const last = rendered.slice(-edgeCount);
|
|
126
|
+
return [
|
|
127
|
+
...first.map((entry) => `#${entry.index} [${entry.role}] ${clip(entry.summary, 220)}`),
|
|
128
|
+
"...",
|
|
129
|
+
...last.map((entry) => `#${entry.index} [${entry.role}] ${clip(entry.summary, 220)}`),
|
|
130
|
+
].join("\n");
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
const sectionCountOf = (summary: string): number =>
|
|
134
|
+
SECTION_HEADERS.filter((header) => summary.includes(`[${header}]`)).length;
|
|
135
|
+
|
|
136
|
+
const briefLineCountOf = (summary: string): number => {
|
|
137
|
+
const sep = "\n\n---\n\n";
|
|
138
|
+
const idx = summary.indexOf(sep);
|
|
139
|
+
if (idx < 0) return 0;
|
|
140
|
+
return summary.slice(idx + sep.length).split("\n").length;
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
const queryTermsOf = (text: string): string[] =>
|
|
144
|
+
(text.match(/[\p{L}\p{N}_./-]{3,}/gu) ?? [])
|
|
145
|
+
.map((part) => part.trim())
|
|
146
|
+
.filter(Boolean);
|
|
147
|
+
|
|
148
|
+
const queryOf = (text: string): string => {
|
|
149
|
+
const terms = queryTermsOf(text);
|
|
150
|
+
return terms.slice(0, 6).join(" ");
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const matchesQuery = (text: string, query: string): boolean => {
|
|
154
|
+
const hay = text.toLowerCase();
|
|
155
|
+
return query
|
|
156
|
+
.toLowerCase()
|
|
157
|
+
.split(/\s+/)
|
|
158
|
+
.filter(Boolean)
|
|
159
|
+
.every((term) => hay.includes(term));
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
const probesOf = (messages: Message[], summary: string): RecallProbe[] => {
|
|
163
|
+
const blocks = normalize(messages);
|
|
164
|
+
const data = buildSections({ blocks });
|
|
165
|
+
|
|
166
|
+
// Find first file from tool calls
|
|
167
|
+
let firstFile = "";
|
|
168
|
+
for (const b of blocks) {
|
|
169
|
+
if (b.kind === "tool_call") {
|
|
170
|
+
for (const key of ["path", "file_path", "filePath", "file"]) {
|
|
171
|
+
if (typeof b.args[key] === "string") { firstFile = b.args[key] as string; break; }
|
|
172
|
+
}
|
|
173
|
+
if (firstFile) break;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const rawProbes = [
|
|
178
|
+
{ label: "goal", text: data.sessionGoal[0] ?? "" },
|
|
179
|
+
{ label: "file", text: firstFile },
|
|
180
|
+
{ label: "problem", text: data.outstandingContext[0] ?? "" },
|
|
181
|
+
];
|
|
182
|
+
|
|
183
|
+
const rendered = messages.map((msg, index) => renderMessage(msg, index));
|
|
184
|
+
|
|
185
|
+
return rawProbes
|
|
186
|
+
.map(({ label, text }) => {
|
|
187
|
+
const sourceText = text.trim();
|
|
188
|
+
const query = queryOf(sourceText);
|
|
189
|
+
if (!query) return null;
|
|
190
|
+
return {
|
|
191
|
+
label,
|
|
192
|
+
sourceText,
|
|
193
|
+
query,
|
|
194
|
+
summaryMentioned: matchesQuery(summary, query),
|
|
195
|
+
recallHits: searchEntries(rendered, query).length,
|
|
196
|
+
};
|
|
197
|
+
})
|
|
198
|
+
.filter((probe): probe is RecallProbe => probe !== null);
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
export const buildCompactReport = (input: CompileInput): CompactReport => {
|
|
202
|
+
const summary = compile(input);
|
|
203
|
+
const data = buildSections({ blocks: normalize(input.messages) });
|
|
204
|
+
const inputChars = inputCharsOf(input.messages);
|
|
205
|
+
const topFiles = topFilesOf(input.messages);
|
|
206
|
+
|
|
207
|
+
return {
|
|
208
|
+
summary,
|
|
209
|
+
before: {
|
|
210
|
+
messageCount: input.messages.length,
|
|
211
|
+
roleCounts: countRoles(input.messages),
|
|
212
|
+
blockCounts: countBlocks(input.messages),
|
|
213
|
+
inputChars,
|
|
214
|
+
estimatedTokens: estimateTokensFromChars(inputChars),
|
|
215
|
+
topFiles,
|
|
216
|
+
preview: previewOf(input.messages),
|
|
217
|
+
},
|
|
218
|
+
after: {
|
|
219
|
+
summaryLength: summary.length,
|
|
220
|
+
estimatedTokens: estimateTokensFromChars(summary.length),
|
|
221
|
+
sectionCount: sectionCountOf(summary),
|
|
222
|
+
summaryPreview: summary,
|
|
223
|
+
goalsCount: data.sessionGoal.length,
|
|
224
|
+
blockersCount: data.outstandingContext.length,
|
|
225
|
+
briefTranscriptLines: briefLineCountOf(summary),
|
|
226
|
+
},
|
|
227
|
+
compression: {
|
|
228
|
+
charsBefore: inputChars,
|
|
229
|
+
charsAfter: summary.length,
|
|
230
|
+
ratio: summary.length === 0 ? 0 : Number((inputChars / summary.length).toFixed(2)),
|
|
231
|
+
messagesBefore: input.messages.length,
|
|
232
|
+
},
|
|
233
|
+
recall: {
|
|
234
|
+
probes: probesOf(input.messages, summary),
|
|
235
|
+
},
|
|
236
|
+
};
|
|
237
|
+
};
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import type { Message } from "@mariozechner/pi-ai";
|
|
2
|
+
import type { RenderedEntry } from "./render-entries";
|
|
3
|
+
import { textOf } from "./content";
|
|
4
|
+
|
|
5
|
+
export interface SearchHit extends RenderedEntry {
|
|
6
|
+
/** Context snippet around the first matched term (only when query provided) */
|
|
7
|
+
snippet?: string;
|
|
8
|
+
/** Number of query terms matched (for ranking) */
|
|
9
|
+
matchCount?: number;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const escapeRegex = (s: string): string =>
|
|
13
|
+
s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
14
|
+
|
|
15
|
+
/** Try to compile as regex; fall back to escaped literal. */
|
|
16
|
+
const safeRegex = (pattern: string): RegExp => {
|
|
17
|
+
try {
|
|
18
|
+
return new RegExp(pattern, "i");
|
|
19
|
+
} catch {
|
|
20
|
+
return new RegExp(escapeRegex(pattern), "i");
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/** Detect if the query looks like a single regex pattern (contains regex metacharacters). */
|
|
25
|
+
const looksLikeRegex = (query: string): boolean =>
|
|
26
|
+
/[|*+?{}()[\]\\^$.]/.test(query);
|
|
27
|
+
|
|
28
|
+
/** Build a regex for snippet highlighting — matches first available term. */
|
|
29
|
+
const snippetRegex = (terms: string[]): RegExp => {
|
|
30
|
+
const alts = terms.map((t) => {
|
|
31
|
+
try {
|
|
32
|
+
// Validate that it's a valid regex
|
|
33
|
+
new RegExp(t, "i");
|
|
34
|
+
return t;
|
|
35
|
+
} catch {
|
|
36
|
+
return escapeRegex(t);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
return new RegExp(alts.join("|"), "i");
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
// ── Stopwords for natural language queries ──
|
|
43
|
+
const STOPWORDS = new Set([
|
|
44
|
+
// English
|
|
45
|
+
"the", "a", "an", "is", "are", "was", "were", "be", "been", "being",
|
|
46
|
+
"have", "has", "had", "do", "does", "did", "will", "would", "could",
|
|
47
|
+
"should", "may", "might", "can", "shall", "of", "in", "to", "for",
|
|
48
|
+
"with", "on", "at", "from", "by", "as", "into", "through", "during",
|
|
49
|
+
"before", "after", "above", "below", "between", "out", "off", "over",
|
|
50
|
+
"under", "again", "further", "then", "once", "here", "there", "when",
|
|
51
|
+
"where", "why", "how", "all", "both", "each", "few", "more", "most",
|
|
52
|
+
"other", "some", "such", "no", "nor", "not", "only", "own", "same",
|
|
53
|
+
"so", "than", "too", "very", "just", "about", "it", "its", "that",
|
|
54
|
+
"this", "what", "which", "who", "whom", "these", "those",
|
|
55
|
+
]);
|
|
56
|
+
|
|
57
|
+
/** Remove stopwords, keep meaningful terms. */
|
|
58
|
+
const filterStopwords = (terms: string[]): string[] => {
|
|
59
|
+
const meaningful = terms.filter((t) => !STOPWORDS.has(t.toLowerCase()) && t.length > 1);
|
|
60
|
+
// If all terms were stopwords, return original (don't lose everything)
|
|
61
|
+
return meaningful.length > 0 ? meaningful : terms;
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/** Count how many distinct terms match the haystack. */
|
|
65
|
+
const countMatches = (hay: string, terms: string[]): number => {
|
|
66
|
+
let count = 0;
|
|
67
|
+
for (const t of terms) {
|
|
68
|
+
if (safeRegex(t).test(hay)) count++;
|
|
69
|
+
}
|
|
70
|
+
return count;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
// ── BM25-lite scoring ──
|
|
74
|
+
const BM25_K = 1.2;
|
|
75
|
+
const BM25_B = 0.75;
|
|
76
|
+
|
|
77
|
+
/** Count occurrences of a regex pattern in text. */
|
|
78
|
+
const termFreq = (text: string, pattern: RegExp): number => {
|
|
79
|
+
const matches = text.match(new RegExp(pattern.source, "gi"));
|
|
80
|
+
return matches ? matches.length : 0;
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
interface BM25Context {
|
|
84
|
+
n: number; // total docs
|
|
85
|
+
avgDl: number; // average doc length (words)
|
|
86
|
+
df: Map<string, number>; // term -> number of docs containing it
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** Precompute IDF and avgDl across all docs. */
|
|
90
|
+
const buildBM25Context = (docs: string[], terms: string[]): BM25Context => {
|
|
91
|
+
const n = docs.length;
|
|
92
|
+
const df = new Map<string, number>();
|
|
93
|
+
let totalLen = 0;
|
|
94
|
+
|
|
95
|
+
for (const doc of docs) {
|
|
96
|
+
totalLen += doc.split(/\s+/).length;
|
|
97
|
+
for (const t of terms) {
|
|
98
|
+
if (safeRegex(t).test(doc)) {
|
|
99
|
+
df.set(t, (df.get(t) ?? 0) + 1);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return { n, avgDl: totalLen / Math.max(n, 1), df };
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
/** BM25 score for a single doc against query terms. */
|
|
108
|
+
const bm25Score = (doc: string, terms: string[], ctx: BM25Context): number => {
|
|
109
|
+
const dl = doc.split(/\s+/).length;
|
|
110
|
+
let score = 0;
|
|
111
|
+
|
|
112
|
+
for (const t of terms) {
|
|
113
|
+
const tf = termFreq(doc, safeRegex(t));
|
|
114
|
+
if (tf === 0) continue;
|
|
115
|
+
|
|
116
|
+
const docFreq = ctx.df.get(t) ?? 0;
|
|
117
|
+
// IDF: log((N - df + 0.5) / (df + 0.5) + 1)
|
|
118
|
+
const idf = Math.log((ctx.n - docFreq + 0.5) / (docFreq + 0.5) + 1);
|
|
119
|
+
// TF saturation with length normalization
|
|
120
|
+
const tfNorm = (tf * (BM25_K + 1)) / (tf + BM25_K * (1 - BM25_B + BM25_B * dl / ctx.avgDl));
|
|
121
|
+
score += idf * tfNorm;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return score;
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
/** Line-based snippet: ±contextLines around first regex match. */
|
|
128
|
+
const lineSnippet = (text: string, regex: RegExp, contextLines = 2): string | undefined => {
|
|
129
|
+
const lines = text.split("\n");
|
|
130
|
+
let matchIdx = -1;
|
|
131
|
+
for (let i = 0; i < lines.length; i++) {
|
|
132
|
+
if (regex.test(lines[i])) {
|
|
133
|
+
matchIdx = i;
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
if (matchIdx === -1) return undefined;
|
|
138
|
+
|
|
139
|
+
const start = Math.max(0, matchIdx - contextLines);
|
|
140
|
+
const end = Math.min(lines.length, matchIdx + contextLines + 1);
|
|
141
|
+
const slice = lines.slice(start, end);
|
|
142
|
+
|
|
143
|
+
const parts: string[] = [];
|
|
144
|
+
if (start > 0) parts.push(`...(${start} lines above)`);
|
|
145
|
+
parts.push(...slice);
|
|
146
|
+
if (end < lines.length) parts.push(`...(${lines.length - end} lines below)`);
|
|
147
|
+
return parts.join("\n");
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
/** Build full searchable text for a message. */
|
|
151
|
+
const fullText = (msg: Message): string => {
|
|
152
|
+
if ((msg as any).role === "bashExecution") {
|
|
153
|
+
return `${(msg as any).command ?? ""} ${(msg as any).output ?? ""}`;
|
|
154
|
+
}
|
|
155
|
+
return textOf(msg.content);
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
export const searchEntries = (
|
|
159
|
+
entries: RenderedEntry[],
|
|
160
|
+
messages: Message[],
|
|
161
|
+
query?: string,
|
|
162
|
+
): SearchHit[] => {
|
|
163
|
+
if (!query?.trim()) return entries;
|
|
164
|
+
|
|
165
|
+
const rawQuery = query.trim();
|
|
166
|
+
|
|
167
|
+
// If query looks like a single regex pattern (contains metacharacters),
|
|
168
|
+
// treat the whole thing as one pattern — don't split into terms
|
|
169
|
+
if (looksLikeRegex(rawQuery)) {
|
|
170
|
+
const regex = safeRegex(rawQuery);
|
|
171
|
+
const hits: SearchHit[] = [];
|
|
172
|
+
for (let i = 0; i < entries.length; i++) {
|
|
173
|
+
const e = entries[i];
|
|
174
|
+
const msg = messages[i];
|
|
175
|
+
const text = msg ? fullText(msg) : e.summary;
|
|
176
|
+
const filePart = e.files?.join(" ") ?? "";
|
|
177
|
+
const hay = `${e.role} ${text} ${filePart}`;
|
|
178
|
+
if (regex.test(hay)) {
|
|
179
|
+
const snip = lineSnippet(text, regex);
|
|
180
|
+
hits.push({ ...e, snippet: snip, matchCount: 1 });
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return hits;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Natural language / multi-word query: BM25 scoring
|
|
187
|
+
const rawTerms = rawQuery.split(/\s+/);
|
|
188
|
+
const terms = filterStopwords(rawTerms);
|
|
189
|
+
const snipRe = snippetRegex(terms);
|
|
190
|
+
|
|
191
|
+
// Build all docs for BM25 context
|
|
192
|
+
const docs: string[] = [];
|
|
193
|
+
for (let i = 0; i < entries.length; i++) {
|
|
194
|
+
const e = entries[i];
|
|
195
|
+
const msg = messages[i];
|
|
196
|
+
const text = msg ? fullText(msg) : e.summary;
|
|
197
|
+
const filePart = e.files?.join(" ") ?? "";
|
|
198
|
+
docs.push(`${e.role} ${text} ${filePart}`);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
const ctx = buildBM25Context(docs, terms);
|
|
202
|
+
|
|
203
|
+
const scored: Array<{ hit: SearchHit; score: number }> = [];
|
|
204
|
+
for (let i = 0; i < entries.length; i++) {
|
|
205
|
+
const e = entries[i];
|
|
206
|
+
const hay = docs[i];
|
|
207
|
+
const mc = countMatches(hay, terms);
|
|
208
|
+
if (mc === 0) continue;
|
|
209
|
+
const score = bm25Score(hay, terms, ctx);
|
|
210
|
+
const text = messages[i] ? fullText(messages[i]) : e.summary;
|
|
211
|
+
const snip = lineSnippet(text, snipRe);
|
|
212
|
+
scored.push({
|
|
213
|
+
hit: { ...e, snippet: snip, matchCount: mc },
|
|
214
|
+
score,
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Sort by BM25 score desc
|
|
219
|
+
scored.sort((a, b) => b.score - a.score);
|
|
220
|
+
return scored.map((s) => s.hit);
|
|
221
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
2
|
+
import { homedir } from "os";
|
|
3
|
+
import { dirname, join } from "path";
|
|
4
|
+
|
|
5
|
+
export const SETTINGS_PATH_DEFAULT = join(homedir(), ".pi", "agent", "pi-vcc-config.json");
|
|
6
|
+
const settingsPath = (): string => process.env.PI_VCC_CONFIG_PATH ?? SETTINGS_PATH_DEFAULT;
|
|
7
|
+
/** Backwards-compat export. Resolves at access time, not import time. */
|
|
8
|
+
export const SETTINGS_PATH = settingsPath();
|
|
9
|
+
|
|
10
|
+
export interface PiVccSettings {
|
|
11
|
+
/**
|
|
12
|
+
* When true, pi-vcc handles ALL compactions:
|
|
13
|
+
* - /compact (no args)
|
|
14
|
+
* - /compact <text>
|
|
15
|
+
* - auto threshold / overflow
|
|
16
|
+
* - /pi-vcc (always handled regardless)
|
|
17
|
+
*
|
|
18
|
+
* When false (default), pi-vcc only handles /pi-vcc; everything else
|
|
19
|
+
* falls back to pi core's default LLM-based compaction.
|
|
20
|
+
*/
|
|
21
|
+
overrideDefaultCompaction: boolean;
|
|
22
|
+
/** Write debug snapshot to /tmp/pi-vcc-debug.json on each compaction. */
|
|
23
|
+
debug: boolean;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const DEFAULT_SETTINGS: PiVccSettings = {
|
|
27
|
+
overrideDefaultCompaction: false,
|
|
28
|
+
debug: false,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const readJson = (path: string): Record<string, unknown> | null => {
|
|
32
|
+
try {
|
|
33
|
+
return JSON.parse(readFileSync(path, "utf-8"));
|
|
34
|
+
} catch {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export function loadSettings(): PiVccSettings {
|
|
40
|
+
const parsed = readJson(settingsPath());
|
|
41
|
+
if (!parsed || typeof parsed !== "object") return { ...DEFAULT_SETTINGS };
|
|
42
|
+
return { ...DEFAULT_SETTINGS, ...(parsed as Partial<PiVccSettings>) };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Ensure ~/.pi/agent/pi-vcc-config.json exists with default keys.
|
|
47
|
+
* - File missing → create with full default block.
|
|
48
|
+
* - File exists but invalid JSON → no-op (don't clobber user file).
|
|
49
|
+
* - File exists and valid → fill in missing default keys, preserve existing values.
|
|
50
|
+
*/
|
|
51
|
+
export function scaffoldSettings(): void {
|
|
52
|
+
try {
|
|
53
|
+
const path = settingsPath();
|
|
54
|
+
const dir = dirname(path);
|
|
55
|
+
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
56
|
+
|
|
57
|
+
if (!existsSync(path)) {
|
|
58
|
+
writeFileSync(path, `${JSON.stringify(DEFAULT_SETTINGS, null, 2)}\n`);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const parsed = readJson(path);
|
|
63
|
+
if (!parsed || typeof parsed !== "object") return; // don't clobber
|
|
64
|
+
|
|
65
|
+
let changed = false;
|
|
66
|
+
const next: Record<string, unknown> = { ...parsed };
|
|
67
|
+
for (const [key, value] of Object.entries(DEFAULT_SETTINGS)) {
|
|
68
|
+
if (!(key in next)) {
|
|
69
|
+
next[key] = value;
|
|
70
|
+
changed = true;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (changed) writeFileSync(path, `${JSON.stringify(next, null, 2)}\n`);
|
|
74
|
+
} catch {
|
|
75
|
+
// best-effort; never crash extension load
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/** Shared skill-tag collapse utilities */
|
|
2
|
+
|
|
3
|
+
const SKILL_TAG_RE = /^-?\s*<skill\s+name="([^"]+)"/;
|
|
4
|
+
const SKILL_CLOSE_RE = /^-?\s*<\/skill>/;
|
|
5
|
+
|
|
6
|
+
/** Collapse skill tags in an array of lines — dedup by name, drop all content inside block */
|
|
7
|
+
export const collapseSkillLines = (lines: string[]): string[] => {
|
|
8
|
+
const result: string[] = [];
|
|
9
|
+
const seenSkills = new Set<string>();
|
|
10
|
+
let insideSkill = false;
|
|
11
|
+
|
|
12
|
+
for (const line of lines) {
|
|
13
|
+
const skillMatch = line.match(SKILL_TAG_RE);
|
|
14
|
+
if (skillMatch) {
|
|
15
|
+
insideSkill = true;
|
|
16
|
+
const name = skillMatch[1];
|
|
17
|
+
if (!seenSkills.has(name)) {
|
|
18
|
+
seenSkills.add(name);
|
|
19
|
+
result.push(`[skill: ${name}]`);
|
|
20
|
+
}
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
23
|
+
if (insideSkill) {
|
|
24
|
+
if (SKILL_CLOSE_RE.test(line)) insideSkill = false;
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
result.push(line);
|
|
28
|
+
}
|
|
29
|
+
return result;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/** Collapse <skill name="X" ...>...</skill> blocks in raw text */
|
|
33
|
+
const SKILL_BLOCK_RE = /<skill\s+name="([^"]+)"[^>]*>[\s\S]*?(?:<\/skill>|$)/g;
|
|
34
|
+
export const collapseSkillText = (text: string): string =>
|
|
35
|
+
text.replace(SKILL_BLOCK_RE, (_, name) => `[skill: ${name}]`);
|