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,61 @@
|
|
|
1
|
+
import { describe, it, expect } from "bun:test";
|
|
2
|
+
import { filterNoise } from "../src/core/filter-noise";
|
|
3
|
+
import type { NormalizedBlock } from "../src/types";
|
|
4
|
+
|
|
5
|
+
describe("filterNoise", () => {
|
|
6
|
+
it("removes thinking blocks", () => {
|
|
7
|
+
const blocks: NormalizedBlock[] = [
|
|
8
|
+
{ kind: "thinking", text: "hmm", redacted: false },
|
|
9
|
+
{ kind: "assistant", text: "hello" },
|
|
10
|
+
];
|
|
11
|
+
expect(filterNoise(blocks)).toEqual([{ kind: "assistant", text: "hello" }]);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it("removes noise tool calls and results", () => {
|
|
15
|
+
const blocks: NormalizedBlock[] = [
|
|
16
|
+
{ kind: "tool_call", name: "TodoWrite", args: {} },
|
|
17
|
+
{ kind: "tool_result", name: "TodoWrite", text: "ok", isError: false },
|
|
18
|
+
{ kind: "tool_call", name: "Read", args: { path: "x.ts" } },
|
|
19
|
+
];
|
|
20
|
+
const result = filterNoise(blocks);
|
|
21
|
+
expect(result).toHaveLength(1);
|
|
22
|
+
expect(result[0]).toEqual({ kind: "tool_call", name: "Read", args: { path: "x.ts" } });
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
it("removes user blocks that are pure XML wrappers", () => {
|
|
26
|
+
const blocks: NormalizedBlock[] = [
|
|
27
|
+
{ kind: "user", text: "<system-reminder>some noise</system-reminder>" },
|
|
28
|
+
{ kind: "user", text: "Fix the bug" },
|
|
29
|
+
];
|
|
30
|
+
const result = filterNoise(blocks);
|
|
31
|
+
expect(result).toHaveLength(1);
|
|
32
|
+
expect(result[0]).toEqual({ kind: "user", text: "Fix the bug" });
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it("cleans XML wrappers from user text but keeps real content", () => {
|
|
36
|
+
const blocks: NormalizedBlock[] = [
|
|
37
|
+
{ kind: "user", text: "<system-reminder>noise</system-reminder>\nFix the login" },
|
|
38
|
+
];
|
|
39
|
+
const result = filterNoise(blocks);
|
|
40
|
+
expect(result).toHaveLength(1);
|
|
41
|
+
expect((result[0] as any).text).toBe("Fix the login");
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it("removes known noise strings", () => {
|
|
45
|
+
const blocks: NormalizedBlock[] = [
|
|
46
|
+
{ kind: "user", text: "Continue from where you left off." },
|
|
47
|
+
{ kind: "user", text: "real task" },
|
|
48
|
+
];
|
|
49
|
+
const result = filterNoise(blocks);
|
|
50
|
+
expect(result).toHaveLength(1);
|
|
51
|
+
expect((result[0] as any).text).toBe("real task");
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it("preserves non-noise tool calls", () => {
|
|
55
|
+
const blocks: NormalizedBlock[] = [
|
|
56
|
+
{ kind: "tool_call", name: "Edit", args: { path: "a.ts" } },
|
|
57
|
+
{ kind: "tool_result", name: "Edit", text: "ok", isError: false },
|
|
58
|
+
];
|
|
59
|
+
expect(filterNoise(blocks)).toHaveLength(2);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { Message } from "@mariozechner/pi-ai";
|
|
2
|
+
|
|
3
|
+
const ts = Date.now();
|
|
4
|
+
const assistBase = {
|
|
5
|
+
api: "messages" as any,
|
|
6
|
+
provider: "anthropic" as any,
|
|
7
|
+
model: "test",
|
|
8
|
+
usage: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
|
|
9
|
+
timestamp: ts,
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const userMsg = (text: string): Message => ({
|
|
13
|
+
role: "user",
|
|
14
|
+
content: text,
|
|
15
|
+
timestamp: ts,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
export const assistantText = (text: string): Message => ({
|
|
19
|
+
role: "assistant",
|
|
20
|
+
content: [{ type: "text", text }],
|
|
21
|
+
...assistBase,
|
|
22
|
+
stopReason: "stop",
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
export const assistantWithThinking = (
|
|
26
|
+
text: string,
|
|
27
|
+
thinking: string,
|
|
28
|
+
): Message => ({
|
|
29
|
+
role: "assistant",
|
|
30
|
+
content: [
|
|
31
|
+
{ type: "thinking", thinking },
|
|
32
|
+
{ type: "text", text },
|
|
33
|
+
],
|
|
34
|
+
...assistBase,
|
|
35
|
+
stopReason: "stop",
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
export const assistantWithToolCall = (
|
|
39
|
+
name: string,
|
|
40
|
+
args: Record<string, unknown>,
|
|
41
|
+
): Message => ({
|
|
42
|
+
role: "assistant",
|
|
43
|
+
content: [{ type: "toolCall", id: "tc_1", name, arguments: args }],
|
|
44
|
+
...assistBase,
|
|
45
|
+
stopReason: "toolUse",
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
export const toolResult = (
|
|
49
|
+
name: string,
|
|
50
|
+
text: string,
|
|
51
|
+
isError = false,
|
|
52
|
+
): Message => ({
|
|
53
|
+
role: "toolResult",
|
|
54
|
+
toolCallId: "tc_1",
|
|
55
|
+
toolName: name,
|
|
56
|
+
content: [{ type: "text", text }],
|
|
57
|
+
isError,
|
|
58
|
+
timestamp: ts,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { describe, it, expect } from "bun:test";
|
|
2
|
+
import { formatRecallOutput } from "../src/core/format-recall";
|
|
3
|
+
import type { RenderedEntry } from "../src/core/render-entries";
|
|
4
|
+
|
|
5
|
+
describe("formatRecallOutput", () => {
|
|
6
|
+
it("shows no-match message with query", () => {
|
|
7
|
+
const r = formatRecallOutput([], "xyz");
|
|
8
|
+
expect(r).toContain('No matches for "xyz"');
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it("shows no-entries message without query", () => {
|
|
12
|
+
expect(formatRecallOutput([])).toContain("No entries");
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it("formats entries with index and role", () => {
|
|
16
|
+
const entries: RenderedEntry[] = [
|
|
17
|
+
{ index: 0, role: "user", summary: "hello" },
|
|
18
|
+
];
|
|
19
|
+
const r = formatRecallOutput(entries);
|
|
20
|
+
expect(r).toContain("#0 [user] hello");
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("shows match count with query", () => {
|
|
24
|
+
const entries: RenderedEntry[] = [
|
|
25
|
+
{ index: 2, role: "assistant", summary: "done" },
|
|
26
|
+
];
|
|
27
|
+
const r = formatRecallOutput(entries, "done");
|
|
28
|
+
expect(r).toContain('Found 1 matches for "done"');
|
|
29
|
+
});
|
|
30
|
+
});
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { describe, it, expect } from "bun:test";
|
|
2
|
+
import { formatSummary } from "../src/core/format";
|
|
3
|
+
import type { SectionData } from "../src/sections";
|
|
4
|
+
|
|
5
|
+
const empty: SectionData = {
|
|
6
|
+
sessionGoal: [],
|
|
7
|
+
outstandingContext: [],
|
|
8
|
+
filesAndChanges: [],
|
|
9
|
+
commits: [],
|
|
10
|
+
userPreferences: [],
|
|
11
|
+
briefTranscript: "",
|
|
12
|
+
transcriptEntries: [],
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
describe("formatSummary", () => {
|
|
16
|
+
it("returns empty string for all-empty sections", () => {
|
|
17
|
+
expect(formatSummary(empty)).toBe("");
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it("formats a single header section", () => {
|
|
21
|
+
const data = {
|
|
22
|
+
...empty,
|
|
23
|
+
sessionGoal: ["fix auth bug"],
|
|
24
|
+
};
|
|
25
|
+
const r = formatSummary(data);
|
|
26
|
+
expect(r).toContain("[Session Goal]");
|
|
27
|
+
expect(r).toContain("- fix auth bug");
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it("separates header and brief transcript with ---", () => {
|
|
31
|
+
const data = {
|
|
32
|
+
...empty,
|
|
33
|
+
sessionGoal: ["goal"],
|
|
34
|
+
briefTranscript: "[user]\ndo something",
|
|
35
|
+
};
|
|
36
|
+
const r = formatSummary(data);
|
|
37
|
+
expect(r).toContain("[Session Goal]");
|
|
38
|
+
expect(r).toContain("---");
|
|
39
|
+
expect(r).toContain("[user]\ndo something");
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it("renders brief transcript alone when no header sections", () => {
|
|
43
|
+
const data = {
|
|
44
|
+
...empty,
|
|
45
|
+
briefTranscript: "[user]\nhi\n\n[assistant]\nhello",
|
|
46
|
+
};
|
|
47
|
+
const r = formatSummary(data);
|
|
48
|
+
expect(r).toContain("[user]\nhi\n\n[assistant]\nhello");
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it("joins multiple header sections with blank line", () => {
|
|
52
|
+
const data = {
|
|
53
|
+
...empty,
|
|
54
|
+
sessionGoal: ["goal"],
|
|
55
|
+
outstandingContext: ["blocker"],
|
|
56
|
+
};
|
|
57
|
+
const r = formatSummary(data);
|
|
58
|
+
expect(r).toContain("[Session Goal]");
|
|
59
|
+
expect(r).toContain("[Outstanding Context]");
|
|
60
|
+
expect(r).toContain("\n\n");
|
|
61
|
+
});
|
|
62
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { describe, it, expect } from "bun:test";
|
|
2
|
+
import { getActiveLineageEntryIds } from "../src/core/lineage";
|
|
3
|
+
|
|
4
|
+
describe("getActiveLineageEntryIds", () => {
|
|
5
|
+
it("returns IDs from active branch", () => {
|
|
6
|
+
const ids = getActiveLineageEntryIds({
|
|
7
|
+
getBranch: () => [{ id: "a" }, { id: "b" }, { id: "c" }],
|
|
8
|
+
});
|
|
9
|
+
expect([...ids]).toEqual(["a", "b", "c"]);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it("falls back to getEntries when getBranch throws", () => {
|
|
13
|
+
const ids = getActiveLineageEntryIds({
|
|
14
|
+
getBranch: () => {
|
|
15
|
+
throw new Error("boom");
|
|
16
|
+
},
|
|
17
|
+
getEntries: () => [{ id: "x" }, { id: "y" }],
|
|
18
|
+
});
|
|
19
|
+
expect([...ids]).toEqual(["x", "y"]);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("returns empty set when both branch and entries are unavailable", () => {
|
|
23
|
+
const ids = getActiveLineageEntryIds({
|
|
24
|
+
getBranch: () => {
|
|
25
|
+
throw new Error("boom");
|
|
26
|
+
},
|
|
27
|
+
getEntries: () => {
|
|
28
|
+
throw new Error("boom2");
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
expect(ids.size).toBe(0);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { describe, it, expect } from "bun:test";
|
|
2
|
+
import { mkdtempSync, writeFileSync, rmSync } from "fs";
|
|
3
|
+
import { tmpdir } from "os";
|
|
4
|
+
import { join } from "path";
|
|
5
|
+
import { loadAllMessages } from "../src/core/load-messages";
|
|
6
|
+
|
|
7
|
+
describe("loadAllMessages", () => {
|
|
8
|
+
it("loads all message entries when no lineage filter is provided", () => {
|
|
9
|
+
const dir = mkdtempSync(join(tmpdir(), "pi-vcc-load-all-"));
|
|
10
|
+
const file = join(dir, "session.jsonl");
|
|
11
|
+
try {
|
|
12
|
+
const lines = [
|
|
13
|
+
JSON.stringify({ type: "session", id: "s1" }),
|
|
14
|
+
JSON.stringify({ type: "message", id: "m1", message: { role: "user", content: "u1" } }),
|
|
15
|
+
JSON.stringify({ type: "custom", id: "c1", customType: "x", data: {} }),
|
|
16
|
+
JSON.stringify({ type: "message", id: "m2", message: { role: "assistant", content: [{ type: "text", text: "a1" }] } }),
|
|
17
|
+
JSON.stringify({ type: "message", id: "m3", message: { role: "toolResult", toolName: "read", content: [{ type: "text", text: "ok" }] } }),
|
|
18
|
+
];
|
|
19
|
+
writeFileSync(file, lines.join("\n") + "\n", "utf8");
|
|
20
|
+
|
|
21
|
+
const loaded = loadAllMessages(file, false);
|
|
22
|
+
expect(loaded.rendered).toHaveLength(3);
|
|
23
|
+
expect(loaded.rawMessages).toHaveLength(3);
|
|
24
|
+
expect(loaded.entryIds).toEqual(["m1", "m2", "m3"]);
|
|
25
|
+
expect(loaded.rendered.map((e) => e.index)).toEqual([0, 1, 2]);
|
|
26
|
+
} finally {
|
|
27
|
+
rmSync(dir, { recursive: true, force: true });
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("filters messages by allowed lineage entry IDs and preserves original message index", () => {
|
|
32
|
+
const dir = mkdtempSync(join(tmpdir(), "pi-vcc-load-filter-"));
|
|
33
|
+
const file = join(dir, "session.jsonl");
|
|
34
|
+
try {
|
|
35
|
+
const lines = [
|
|
36
|
+
JSON.stringify({ type: "message", id: "m1", message: { role: "user", content: "u1" } }),
|
|
37
|
+
JSON.stringify({ type: "message", id: "m2", message: { role: "assistant", content: [{ type: "text", text: "a1" }] } }),
|
|
38
|
+
JSON.stringify({ type: "message", id: "m3", message: { role: "user", content: "u2" } }),
|
|
39
|
+
];
|
|
40
|
+
writeFileSync(file, lines.join("\n") + "\n", "utf8");
|
|
41
|
+
|
|
42
|
+
const loaded = loadAllMessages(file, false, new Set(["m2"]));
|
|
43
|
+
expect(loaded.rendered).toHaveLength(1);
|
|
44
|
+
expect(loaded.rawMessages).toHaveLength(1);
|
|
45
|
+
expect(loaded.entryIds).toEqual(["m2"]);
|
|
46
|
+
expect(loaded.rendered[0].index).toBe(1);
|
|
47
|
+
} finally {
|
|
48
|
+
rmSync(dir, { recursive: true, force: true });
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
});
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { describe, it, expect } from "bun:test";
|
|
2
|
+
import { normalize } from "../src/core/normalize";
|
|
3
|
+
import {
|
|
4
|
+
userMsg,
|
|
5
|
+
assistantText,
|
|
6
|
+
assistantWithThinking,
|
|
7
|
+
assistantWithToolCall,
|
|
8
|
+
toolResult,
|
|
9
|
+
} from "./fixtures";
|
|
10
|
+
|
|
11
|
+
describe("normalize", () => {
|
|
12
|
+
it("returns empty for empty input", () => {
|
|
13
|
+
expect(normalize([])).toEqual([]);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it("normalizes user message (string content)", () => {
|
|
17
|
+
const blocks = normalize([userMsg("fix the bug")]);
|
|
18
|
+
expect(blocks).toEqual([{ kind: "user", text: "fix the bug", sourceIndex: 0 }]);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it("normalizes assistant text message", () => {
|
|
22
|
+
const blocks = normalize([assistantText("done")]);
|
|
23
|
+
expect(blocks).toEqual([{ kind: "assistant", text: "done", sourceIndex: 0 }]);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("normalizes assistant string content", () => {
|
|
27
|
+
const msg = { ...assistantText("done"), content: "plain text" } as any;
|
|
28
|
+
expect(normalize([msg])).toEqual([{ kind: "assistant", text: "plain text", sourceIndex: 0 }]);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("splits assistant thinking + text", () => {
|
|
32
|
+
const blocks = normalize([assistantWithThinking("result", "hmm")]);
|
|
33
|
+
expect(blocks).toHaveLength(2);
|
|
34
|
+
expect(blocks[0]).toEqual({
|
|
35
|
+
kind: "thinking", text: "hmm", redacted: false, sourceIndex: 0,
|
|
36
|
+
});
|
|
37
|
+
expect(blocks[1]).toEqual({ kind: "assistant", text: "result", sourceIndex: 0 });
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("normalizes tool call", () => {
|
|
41
|
+
const blocks = normalize([assistantWithToolCall("Read", { path: "a.ts" })]);
|
|
42
|
+
expect(blocks).toEqual([{
|
|
43
|
+
kind: "tool_call", name: "Read", args: { path: "a.ts" }, sourceIndex: 0,
|
|
44
|
+
}]);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("normalizes tool result", () => {
|
|
48
|
+
const blocks = normalize([toolResult("Read", "file contents")]);
|
|
49
|
+
expect(blocks).toEqual([{
|
|
50
|
+
kind: "tool_result", name: "Read",
|
|
51
|
+
text: "file contents", isError: false, sourceIndex: 0,
|
|
52
|
+
}]);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("normalizes error tool result", () => {
|
|
56
|
+
const blocks = normalize([toolResult("Edit", "not found", true)]);
|
|
57
|
+
expect(blocks[0]).toMatchObject({
|
|
58
|
+
kind: "tool_result", isError: true,
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it("handles mixed message sequence", () => {
|
|
63
|
+
const blocks = normalize([
|
|
64
|
+
userMsg("fix it"),
|
|
65
|
+
assistantWithToolCall("Read", { path: "x.ts" }),
|
|
66
|
+
toolResult("Read", "code"),
|
|
67
|
+
assistantText("done"),
|
|
68
|
+
]);
|
|
69
|
+
expect(blocks).toHaveLength(4);
|
|
70
|
+
expect(blocks.map((b) => b.kind)).toEqual([
|
|
71
|
+
"user", "tool_call", "tool_result", "assistant",
|
|
72
|
+
]);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it("produces image placeholder for user image content", () => {
|
|
76
|
+
const msg = {
|
|
77
|
+
role: "user" as const,
|
|
78
|
+
content: [
|
|
79
|
+
{ type: "text" as const, text: "look at this" },
|
|
80
|
+
{ type: "image" as const, data: "abc", mimeType: "image/png" },
|
|
81
|
+
],
|
|
82
|
+
timestamp: Date.now(),
|
|
83
|
+
};
|
|
84
|
+
const blocks = normalize([msg]);
|
|
85
|
+
expect(blocks).toHaveLength(2);
|
|
86
|
+
expect(blocks[0]).toEqual({ kind: "user", text: "look at this", sourceIndex: 0 });
|
|
87
|
+
expect(blocks[1]).toEqual({ kind: "user", text: "[image: image/png]", sourceIndex: 0 });
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it("skips unknown message roles gracefully", () => {
|
|
91
|
+
const weird = { role: "bashExecution", command: "ls", output: "files", exitCode: 0 } as any;
|
|
92
|
+
const blocks = normalize([weird]);
|
|
93
|
+
expect(blocks).toEqual([]);
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { beforeAll, describe, expect, it } from "bun:test";
|
|
2
|
+
import { buildCompactReport } from "../src/core/report";
|
|
3
|
+
import { prepareSessionSamples, readSourceStat, type SessionSample } from "./support/real-sessions";
|
|
4
|
+
import { loadSessionMessages } from "./support/load-session";
|
|
5
|
+
|
|
6
|
+
let samples: SessionSample[] = [];
|
|
7
|
+
|
|
8
|
+
beforeAll(async () => {
|
|
9
|
+
samples = await prepareSessionSamples(2);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
describe("real session integration", () => {
|
|
13
|
+
it("compiles copied large sessions without mutating originals", async () => {
|
|
14
|
+
for (const sample of samples) {
|
|
15
|
+
const before = await readSourceStat(sample);
|
|
16
|
+
const loaded = loadSessionMessages(sample.copy);
|
|
17
|
+
const report = buildCompactReport({ messages: loaded.messages });
|
|
18
|
+
const after = await readSourceStat(sample);
|
|
19
|
+
|
|
20
|
+
expect(loaded.messageCount).toBeGreaterThan(0);
|
|
21
|
+
expect(loaded.skippedCount).toBeGreaterThanOrEqual(0);
|
|
22
|
+
expect(report.summary.length).toBeGreaterThan(0);
|
|
23
|
+
expect(report.summary).toContain("[");
|
|
24
|
+
expect(report.before.preview.length).toBeGreaterThan(0);
|
|
25
|
+
expect(report.after.summaryPreview.length).toBeGreaterThan(0);
|
|
26
|
+
expect(report.compression.charsBefore).toBeGreaterThan(0);
|
|
27
|
+
expect(report.recall.probes.length).toBeGreaterThan(0);
|
|
28
|
+
expect(after).toEqual(before);
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it("uses read-only copied fixtures", () => {
|
|
33
|
+
for (const sample of samples) {
|
|
34
|
+
expect(sample.copy).not.toBe(sample.source);
|
|
35
|
+
expect(sample.copy.includes("pi-vcc-sessions-")).toBe(true);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { describe, it, expect } from "bun:test";
|
|
2
|
+
import { invalidExpandIndices } from "../src/tools/recall";
|
|
3
|
+
|
|
4
|
+
describe("invalidExpandIndices", () => {
|
|
5
|
+
it("returns indices that are not in available lineage index set", () => {
|
|
6
|
+
const available = new Set([0, 2, 5]);
|
|
7
|
+
expect(invalidExpandIndices([0, 2], available)).toEqual([]);
|
|
8
|
+
expect(invalidExpandIndices([1, 2, 7], available)).toEqual([1, 7]);
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it("rejects non-integer indices", () => {
|
|
12
|
+
const available = new Set([0, 1, 2]);
|
|
13
|
+
expect(invalidExpandIndices([1.5, 2], available)).toEqual([1.5]);
|
|
14
|
+
});
|
|
15
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { describe, it, expect } from "bun:test";
|
|
2
|
+
import { normalizeRecallScope, parseRecallScope } from "../src/core/recall-scope";
|
|
3
|
+
|
|
4
|
+
describe("normalizeRecallScope", () => {
|
|
5
|
+
it("defaults to active lineage", () => {
|
|
6
|
+
expect(normalizeRecallScope()).toBe("lineage");
|
|
7
|
+
expect(normalizeRecallScope("lineage")).toBe("lineage");
|
|
8
|
+
expect(normalizeRecallScope("unknown")).toBe("lineage");
|
|
9
|
+
expect(normalizeRecallScope(123)).toBe("lineage");
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it("accepts all scope", () => {
|
|
13
|
+
expect(normalizeRecallScope("all")).toBe("all");
|
|
14
|
+
expect(normalizeRecallScope("ALL")).toBe("all");
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
describe("parseRecallScope", () => {
|
|
19
|
+
it("removes scope token from command text", () => {
|
|
20
|
+
expect(parseRecallScope("license scope:all page:2")).toEqual({
|
|
21
|
+
scope: "all",
|
|
22
|
+
text: "license page:2",
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("defaults to lineage when no scope token is present", () => {
|
|
27
|
+
expect(parseRecallScope("license page:2")).toEqual({
|
|
28
|
+
scope: "lineage",
|
|
29
|
+
text: "license page:2",
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
});
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { describe, it, expect } from "bun:test";
|
|
2
|
+
import { mkdtempSync, writeFileSync, rmSync } from "fs";
|
|
3
|
+
import { tmpdir } from "os";
|
|
4
|
+
import { join } from "path";
|
|
5
|
+
import { registerRecallTool } from "../src/tools/recall";
|
|
6
|
+
|
|
7
|
+
const makeSession = () => {
|
|
8
|
+
const dir = mkdtempSync(join(tmpdir(), "pi-vcc-recall-scope-"));
|
|
9
|
+
const file = join(dir, "session.jsonl");
|
|
10
|
+
const lines = [
|
|
11
|
+
JSON.stringify({ type: "message", id: "m1", message: { role: "user", content: "active lineage token" } }),
|
|
12
|
+
JSON.stringify({ type: "message", id: "m2", message: { role: "user", content: "off lineage secret" } }),
|
|
13
|
+
];
|
|
14
|
+
writeFileSync(file, lines.join("\n") + "\n", "utf8");
|
|
15
|
+
return { dir, file };
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const register = () => {
|
|
19
|
+
let tool: any;
|
|
20
|
+
registerRecallTool({ registerTool: (t: any) => { tool = t; } } as any);
|
|
21
|
+
return tool;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const invoke = async (tool: any, file: string, params: Record<string, unknown>) => {
|
|
25
|
+
const result = await tool.execute("tool-call", params, undefined, undefined, {
|
|
26
|
+
sessionManager: {
|
|
27
|
+
getSessionFile: () => file,
|
|
28
|
+
getBranch: () => [{ id: "m1" }],
|
|
29
|
+
getEntries: () => [{ id: "m1" }, { id: "m2" }],
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
return result.content[0].text as string;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
describe("vcc_recall scope", () => {
|
|
36
|
+
it("defaults to active lineage and opts into all-session search explicitly", async () => {
|
|
37
|
+
const { dir, file } = makeSession();
|
|
38
|
+
try {
|
|
39
|
+
const tool = register();
|
|
40
|
+
|
|
41
|
+
const lineage = await invoke(tool, file, { query: "secret" });
|
|
42
|
+
expect(lineage).toContain("No matches");
|
|
43
|
+
|
|
44
|
+
const all = await invoke(tool, file, { query: "secret", scope: "all" });
|
|
45
|
+
expect(all).toContain("scope: all");
|
|
46
|
+
expect(all).toContain("off lineage secret");
|
|
47
|
+
} finally {
|
|
48
|
+
rmSync(dir, { recursive: true, force: true });
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
it("keeps expand strict by default but allows off-lineage expand with scope all", async () => {
|
|
53
|
+
const { dir, file } = makeSession();
|
|
54
|
+
try {
|
|
55
|
+
const tool = register();
|
|
56
|
+
|
|
57
|
+
const lineage = await invoke(tool, file, { expand: [1] });
|
|
58
|
+
expect(lineage).toContain("Cannot expand indices outside active lineage: 1");
|
|
59
|
+
|
|
60
|
+
const all = await invoke(tool, file, { expand: [1], scope: "all" });
|
|
61
|
+
expect(all).toContain("Scope: all");
|
|
62
|
+
expect(all).toContain("#1 [user] off lineage secret");
|
|
63
|
+
} finally {
|
|
64
|
+
rmSync(dir, { recursive: true, force: true });
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
});
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { describe, it, expect } from "bun:test";
|
|
2
|
+
import { renderMessage } from "../src/core/render-entries";
|
|
3
|
+
import type { Message } from "@mariozechner/pi-ai";
|
|
4
|
+
import { userMsg, assistantText, assistantWithToolCall, toolResult } from "./fixtures";
|
|
5
|
+
|
|
6
|
+
describe("renderMessage", () => {
|
|
7
|
+
it("renders user message", () => {
|
|
8
|
+
const r = renderMessage(userMsg("hello"), 0);
|
|
9
|
+
expect(r).toEqual({ index: 0, role: "user", summary: "hello" });
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it("renders assistant text", () => {
|
|
13
|
+
const r = renderMessage(assistantText("done"), 1);
|
|
14
|
+
expect(r.role).toBe("assistant");
|
|
15
|
+
expect(r.summary).toBe("done");
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it("renders tool result", () => {
|
|
19
|
+
const r = renderMessage(toolResult("Read", "file contents"), 2);
|
|
20
|
+
expect(r.role).toBe("tool_result");
|
|
21
|
+
expect(r.summary).toContain("[Read]");
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it("renders tool call arguments with values", () => {
|
|
25
|
+
const r = renderMessage(assistantWithToolCall("Read", { path: "a.ts" }), 2);
|
|
26
|
+
expect(r.summary).toContain("Read(path=a.ts)");
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
it("renders error tool result with prefix", () => {
|
|
30
|
+
const r = renderMessage(toolResult("bash", "not found", true), 3);
|
|
31
|
+
expect(r.summary).toStartWith("ERROR");
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it("truncates long user text", () => {
|
|
35
|
+
const long = "x".repeat(500);
|
|
36
|
+
const r = renderMessage(userMsg(long), 0);
|
|
37
|
+
expect(r.summary.length).toBeLessThanOrEqual(300);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it("renders bashExecution message", () => {
|
|
41
|
+
const msg = { role: "bashExecution", command: "ls -la", output: "total 0\n" } as any;
|
|
42
|
+
const r = renderMessage(msg, 5);
|
|
43
|
+
expect(r.role).toBe("bash");
|
|
44
|
+
expect(r.summary).toContain("$ ls -la");
|
|
45
|
+
expect(r.summary).toContain("total 0");
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it("renders bashExecution with missing output", () => {
|
|
49
|
+
const msg = { role: "bashExecution", command: "exit 1" } as any;
|
|
50
|
+
const r = renderMessage(msg, 6);
|
|
51
|
+
expect(r.role).toBe("bash");
|
|
52
|
+
expect(r.summary).toContain("$ exit 1");
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it("handles message with undefined content", () => {
|
|
56
|
+
const msg = { role: "assistant", content: undefined } as any;
|
|
57
|
+
const r = renderMessage(msg, 3);
|
|
58
|
+
expect(r.role).toBe("assistant");
|
|
59
|
+
expect(r.summary).toBe("");
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { describe, it, expect } from "bun:test";
|
|
2
|
+
import { buildCompactReport } from "../src/core/report";
|
|
3
|
+
import {
|
|
4
|
+
userMsg,
|
|
5
|
+
assistantText,
|
|
6
|
+
assistantWithToolCall,
|
|
7
|
+
toolResult,
|
|
8
|
+
} from "./fixtures";
|
|
9
|
+
|
|
10
|
+
describe("buildCompactReport", () => {
|
|
11
|
+
it("includes before and after compact metrics", () => {
|
|
12
|
+
const report = buildCompactReport({
|
|
13
|
+
messages: [
|
|
14
|
+
userMsg("Fix login bug in auth.ts"),
|
|
15
|
+
assistantWithToolCall("Read", { path: "auth.ts" }),
|
|
16
|
+
toolResult("Read", "const x = 1;"),
|
|
17
|
+
assistantText("Found the root cause in auth.ts.\n1. Fix validation\n2. Run tests"),
|
|
18
|
+
],
|
|
19
|
+
});
|
|
20
|
+
expect(report.before.messageCount).toBe(4);
|
|
21
|
+
expect(report.before.roleCounts.user).toBe(1);
|
|
22
|
+
expect(report.before.topFiles).toContain("auth.ts");
|
|
23
|
+
expect(report.before.preview).toContain("Fix login bug in auth.ts");
|
|
24
|
+
expect(report.after.sectionCount).toBeGreaterThan(0);
|
|
25
|
+
expect(report.after.summaryPreview).toContain("[Session Goal]");
|
|
26
|
+
expect(report.after.summaryPreview).toContain('* Read "auth.ts"');
|
|
27
|
+
expect(report.after.briefTranscriptLines).toBeGreaterThan(0);
|
|
28
|
+
expect(report.compression.ratio).toBeGreaterThan(0);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("marks recall probe coverage for goal and file queries", () => {
|
|
32
|
+
const report = buildCompactReport({
|
|
33
|
+
messages: [
|
|
34
|
+
userMsg("Fix login bug in auth.ts"),
|
|
35
|
+
assistantWithToolCall("Read", { path: "auth.ts" }),
|
|
36
|
+
toolResult("Read", "code content"),
|
|
37
|
+
assistantText("Found the root cause"),
|
|
38
|
+
],
|
|
39
|
+
});
|
|
40
|
+
expect(report.recall.probes.length).toBeGreaterThanOrEqual(1);
|
|
41
|
+
const goalProbe = report.recall.probes.find((p) => p.label === "goal");
|
|
42
|
+
expect(goalProbe?.summaryMentioned).toBe(true);
|
|
43
|
+
});
|
|
44
|
+
});
|