pi-mega-compact 0.7.9 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/dist/extensions/dashboard-server/html.js +333 -66
  2. package/dist/extensions/dashboard-server/html.test.js +41 -0
  3. package/dist/extensions/dashboard-server/server.js +161 -1
  4. package/dist/extensions/dashboard-server/server.test.js +120 -0
  5. package/dist/extensions/dashboard-server-s32.test.js +181 -0
  6. package/dist/extensions/mega-compact.js +3 -0
  7. package/dist/extensions/mega-events/agent-handlers.js +49 -0
  8. package/dist/extensions/mega-events/compact-handlers.js +29 -0
  9. package/dist/extensions/mega-game-cmds.js +106 -0
  10. package/dist/extensions/mega-game-cmds.test.js +113 -0
  11. package/dist/extensions/mega-runtime/state.js +167 -1
  12. package/dist/extensions/mega-runtime/state.test.js +171 -0
  13. package/dist/extensions/mega-runtime/widget.js +93 -20
  14. package/dist/extensions/mega-runtime/widget.test.js +160 -0
  15. package/dist/src/config/themes.js +84 -0
  16. package/dist/src/config/themes.test.js +94 -0
  17. package/dist/src/game/scoring.js +105 -0
  18. package/dist/src/game/scoring.test.js +98 -0
  19. package/dist/src/store/sqlite/game-achievements.js +111 -0
  20. package/dist/src/store/sqlite/game-achievements.test.js +67 -0
  21. package/dist/src/store/sqlite/game-scores.js +105 -0
  22. package/dist/src/store/sqlite/game-scores.test.js +106 -0
  23. package/dist/src/store/sqlite/game-state.js +54 -0
  24. package/dist/src/store/sqlite/game-state.test.js +76 -0
  25. package/dist/src/store/sqlite/schema.js +44 -0
  26. package/dist/src/store/sqlite.js +3 -0
  27. package/extensions/dashboard-server/html.test.ts +50 -0
  28. package/extensions/dashboard-server/html.ts +334 -66
  29. package/extensions/dashboard-server/server.test.ts +131 -0
  30. package/extensions/dashboard-server/server.ts +148 -1
  31. package/extensions/dashboard-server-s32.test.ts +195 -0
  32. package/extensions/mega-compact.ts +3 -0
  33. package/extensions/mega-events/agent-handlers.ts +48 -0
  34. package/extensions/mega-events/compact-handlers.ts +28 -0
  35. package/extensions/mega-game-cmds.test.ts +137 -0
  36. package/extensions/mega-game-cmds.ts +122 -0
  37. package/extensions/mega-runtime/state.test.ts +171 -0
  38. package/extensions/mega-runtime/state.ts +170 -0
  39. package/extensions/mega-runtime/widget.test.ts +185 -0
  40. package/extensions/mega-runtime/widget.ts +119 -18
  41. package/package.json +1 -1
  42. package/src/config/themes.test.ts +116 -0
  43. package/src/config/themes.ts +124 -0
  44. package/src/game/scoring.test.ts +103 -0
  45. package/src/game/scoring.ts +158 -0
  46. package/src/store/sqlite/game-achievements.test.ts +80 -0
  47. package/src/store/sqlite/game-achievements.ts +147 -0
  48. package/src/store/sqlite/game-scores.test.ts +132 -0
  49. package/src/store/sqlite/game-scores.ts +168 -0
  50. package/src/store/sqlite/game-state.test.ts +89 -0
  51. package/src/store/sqlite/game-state.ts +87 -0
  52. package/src/store/sqlite/schema.ts +47 -0
  53. package/src/store/sqlite.ts +3 -0
  54. package/dist/extensions/dashboard-server/helpers.js +0 -37
  55. package/dist/extensions/dashboard-server/html/all-repos-tab.js +0 -26
  56. package/dist/extensions/dashboard-server/html/body-open.js +0 -23
  57. package/dist/extensions/dashboard-server/html/current-repo-tab.js +0 -130
  58. package/dist/extensions/dashboard-server/html/head-open.js +0 -16
  59. package/dist/extensions/dashboard-server/html/high-score-tab.js +0 -25
  60. package/dist/extensions/dashboard-server/html/repo-detail-modal.js +0 -26
  61. package/dist/extensions/dashboard-server/html/script.js +0 -259
  62. package/dist/extensions/dashboard-server/html/styles.js +0 -103
  63. package/dist/extensions/dashboard-server/html/summary-tab.js +0 -19
  64. package/dist/extensions/dashboard-server/html-template.js +0 -41
  65. package/dist/src/store/sqlite/connection.js +0 -35
  66. package/dist/src/store/sqlite/index-store.js +0 -167
  67. package/dist/src/store/sqlite/memory.js +0 -54
  68. package/dist/src/store/sqlite/minhash-lsh.js +0 -47
  69. package/dist/src/store/sqlite/sessions.js +0 -39
  70. package/dist/src/store/sqlite/transaction.js +0 -19
  71. package/dist/src/vectorStore/add.js +0 -260
  72. package/dist/src/vectorStore/dedup.js +0 -52
  73. package/dist/src/vectorStore/index.js +0 -10
  74. package/dist/src/vectorStore/queries.js +0 -83
  75. package/dist/src/vectorStore/search.js +0 -95
  76. package/dist/src/vectorStore/session.js +0 -19
  77. package/dist/src/vectorStore/store.js +0 -105
  78. package/dist/src/vectorStore/types.js +0 -6
  79. package/dist/src/vectorStore/utils.js +0 -23
@@ -1,83 +0,0 @@
1
- /**
2
- * vectorStore/queries.ts — Read-only queries: list, topSimilar, stats, repoStats,
3
- * dataInvariant, similarity.
4
- */
5
- import { cosineSimilarity } from "../embedder.js";
6
- import { normalizeSessionId } from "../store.js";
7
- import { listCheckpoints, loadSessionState, getDedupStats, repoStats as repoStatsFromStore, dataInvariantStats, } from "../store/sqlite.js";
8
- /** All checkpoints for a session (sorted by checkpointId). */
9
- export function listSession(ctx, sessionId) {
10
- return listCheckpoints(normalizeSessionId(sessionId), ctx.stateDir);
11
- }
12
- /** Convenience for a raw vector cosine (exposed for tests). */
13
- export function similarityScore(a, b) {
14
- return cosineSimilarity(a, b);
15
- }
16
- /**
17
- * Return the n most similar checkpoints to the current (most recent) checkpoint
18
- * by cosine similarity. Returns fewer than n if the session has fewer checkpoints.
19
- * The current checkpoint itself is excluded from results.
20
- */
21
- export function topSimilarSession(ctx, sessionId, n) {
22
- const sid = normalizeSessionId(sessionId);
23
- const checkpoints = listCheckpoints(sid, ctx.stateDir);
24
- if (checkpoints.length <= 1)
25
- return [];
26
- // Find the most recent checkpoint (by checkpointId, which is sequential)
27
- const ordered = [...checkpoints].sort((a, b) => a.checkpointId.localeCompare(b.checkpointId));
28
- const current = ordered[ordered.length - 1];
29
- // Score all other checkpoints by similarity to current
30
- const scored = ordered
31
- .filter((cp) => cp.checkpointId !== current.checkpointId)
32
- .map((cp) => ({
33
- checkpoint: cp,
34
- score: cosineSimilarity(current.embedding, cp.embedding),
35
- }))
36
- .sort((a, b) => b.score - a.score);
37
- return scored.slice(0, n);
38
- }
39
- /**
40
- * Store statistics for status reporting / logging. Returns counts + the last
41
- * (highest-numbered) checkpoint, or nulls when the session is empty.
42
- */
43
- export function statsSession(ctx, sessionId) {
44
- const sid = normalizeSessionId(sessionId);
45
- const cps = listCheckpoints(sid, ctx.stateDir);
46
- const state = loadSessionState(sid, ctx.stateDir);
47
- const ordered = [...cps].sort((a, b) => a.checkpointId.localeCompare(b.checkpointId));
48
- const last = ordered[ordered.length - 1];
49
- const injected = state.injectedCheckpointIds.length;
50
- const ds = getDedupStats(ctx.stateDir);
51
- const sessionTok = cps.reduce((s, c) => s + (c.tokenEstimate ?? 0), 0);
52
- const sessionOrig = cps.reduce((s, c) => s + (c.originalTokenEstimate ?? 0), 0);
53
- // Per-session "tokens saved" = Σ(original − stored) over this session's
54
- // stored checkpoints. Deduped adds (whole region discarded, nothing stored)
55
- // are counted in the repo-wide meta counter via repoStats(); the per-session
56
- // DB sum here covers the rows that exist.
57
- const sessionSaved = cps.reduce((s, c) => s + Math.max(0, (c.originalTokenEstimate ?? 0) - (c.tokenEstimate ?? 0)), 0);
58
- return {
59
- checkpointCount: cps.length,
60
- totalTokenEstimate: sessionTok,
61
- lastCheckpointId: last?.checkpointId,
62
- lastSummary: last?.summary,
63
- injectedCount: injected,
64
- dedupHitRate: cps.length === 0 ? 0 : injected / cps.length,
65
- storageDedupRate: ds.attempts === 0 ? 0 : ds.deduped / ds.attempts,
66
- tokensSaved: sessionSaved,
67
- originalTokens: sessionOrig,
68
- dedupAttempts: ds.attempts,
69
- dedupCollapsed: ds.deduped,
70
- };
71
- }
72
- /**
73
- * Repo-wide stats — aggregates every session in this store (one per repo).
74
- * Cumulative, resumable, cross-device. Surfaces the dashboard's "Repo …"
75
- * figures; distinct from {@link statsSession} (per-session).
76
- */
77
- export function repoStatsStore(ctx) {
78
- return repoStatsFromStore(ctx.stateDir);
79
- }
80
- /** Data-safety invariant (Phase 0): regions retained vs bytes permanently deleted. */
81
- export function dataInvariantStore(ctx) {
82
- return dataInvariantStats(ctx.stateDir);
83
- }
@@ -1,95 +0,0 @@
1
- /**
2
- * vectorStore/search.ts — Semantic search and RAPTOR integration.
3
- */
4
- import { cosineSimilarity } from "../embedder.js";
5
- import { normalizeSessionId } from "../store.js";
6
- import { mmrRerank } from "../dedup/mmr.js";
7
- import { topK } from "../dedup/topk.js";
8
- import { listCheckpoints } from "../store/sqlite.js";
9
- import { rehydrateRaptorTree } from "../dedup/raptor/index.js";
10
- import { stagedExpansion } from "../dedup/raptor/retrieval.js";
11
- /**
12
- * Serve the RAPTOR tree for a query (Fix D): rehydrate the persisted tree and
13
- * return its staged-expansion leaf hits as SearchHits. Returns [] when no tree
14
- * exists (small sessions — flat search remains the path). Best-effort/non-fatal.
15
- */
16
- export function raptorSearchHits(ctx, sid, query, k) {
17
- try {
18
- const tree = rehydrateRaptorTree(sid, ctx.stateDir);
19
- if (!tree || !tree.rootId)
20
- return [];
21
- const leafIds = stagedExpansion(query, tree, {
22
- embedder: ctx.embedder,
23
- k,
24
- topM: ctx.cfg.RAPTOR_CLUSTERS_PER_LEVEL,
25
- mmrLambda: ctx.cfg.MMR_LAMBDA,
26
- });
27
- if (leafIds.length === 0)
28
- return [];
29
- const all = listCheckpoints(sid, ctx.stateDir).filter((cp) => cp.dedupStatus !== "removed");
30
- const qv = ctx.embedder.embed(query);
31
- const hits = [];
32
- for (const id of leafIds) {
33
- const cp = all.find((c) => c.checkpointId === id);
34
- if (cp)
35
- hits.push({ checkpoint: cp, score: cosineSimilarity(qv, cp.embedding) });
36
- }
37
- return hits;
38
- }
39
- catch {
40
- return [];
41
- }
42
- }
43
- /**
44
- * Semantic search within a session's checkpoints. Returns top-K by cosine
45
- * similarity, diversified via MMR (QA #10) so a cluster of near-identical
46
- * hits yields at most a few distinct-relevance results.
47
- *
48
- * Heap-based top-K (QA #4, O(N log k)) replaces the old full sort; MMR then
49
- * reranks the candidate window for diversity.
50
- */
51
- export function searchStore(ctx, sessionId, query, k = 3) {
52
- const sid = normalizeSessionId(sessionId);
53
- const checkpoints = listCheckpoints(sid, ctx.stateDir).filter((cp) => cp.dedupStatus !== "removed");
54
- if (checkpoints.length === 0)
55
- return [];
56
- const qv = ctx.embedder.embed(query);
57
- const scored = checkpoints.map((cp) => ({
58
- checkpoint: cp,
59
- score: cosineSimilarity(qv, cp.embedding),
60
- }));
61
- // Heap top-K over a widened window (2k) so MMR has diverse candidates.
62
- const window = topK(scored.map((h) => ({ item: h, score: h.score })), Math.max(k * 2, k)).map((s) => s.item);
63
- // MMR (QA #10) is part of the L2 semantic tier: skip it when L2 is disabled
64
- // (Sprint 14 flag), returning the plain relevance-ranked window instead.
65
- if (!ctx.cfg.L2_ENABLED)
66
- return window.slice(0, k);
67
- // Fix D: when RAPTOR is promoted, ALSO recall high-level tree summaries and
68
- // merge them with the flat hits via MMR so RAPTOR + flat don't double-cover.
69
- // RAPTOR returns fewer, broader hits (O(log n) high-level nodes) than the
70
- // O(n) flat leaves, tightening the block at read time.
71
- if (ctx.cfg.RAPTOR_ENABLED) {
72
- const raptorHits = raptorSearchHits(ctx, sid, query, k);
73
- if (raptorHits.length > 0) {
74
- const merged = [...window];
75
- for (const rh of raptorHits) {
76
- if (!merged.some((m) => m.checkpoint.checkpointId === rh.checkpoint.checkpointId)) {
77
- merged.push(rh);
78
- }
79
- }
80
- const mmrItems = merged.map((h) => ({
81
- item: h,
82
- vector: h.checkpoint.embedding,
83
- relevance: h.score,
84
- }));
85
- return mmrRerank(mmrItems, k, ctx.cfg.MMR_LAMBDA);
86
- }
87
- }
88
- const mmrItems = window.map((h) => ({
89
- item: h,
90
- vector: h.checkpoint.embedding,
91
- relevance: h.score,
92
- }));
93
- const ranked = mmrRerank(mmrItems, k, ctx.cfg.MMR_LAMBDA);
94
- return ranked;
95
- }
@@ -1,19 +0,0 @@
1
- /**
2
- * vectorStore/session.ts — Session-state mutations (injection tracking).
3
- */
4
- import { normalizeSessionId } from "../store.js";
5
- import { loadSessionState, saveSessionState } from "../store/sqlite.js";
6
- /** Mark a checkpoint as injected into the window (recall dedup). */
7
- export function markInjectedStore(ctx, sessionId, checkpointId) {
8
- const sid = normalizeSessionId(sessionId);
9
- const state = loadSessionState(sid, ctx.stateDir);
10
- if (!state.injectedCheckpointIds.includes(checkpointId)) {
11
- state.injectedCheckpointIds.push(checkpointId);
12
- saveSessionState(sid, state, ctx.stateDir);
13
- }
14
- }
15
- /** True if this checkpoint was already injected this session. */
16
- export function wasInjectedStore(ctx, sessionId, checkpointId) {
17
- const state = loadSessionState(normalizeSessionId(sessionId), ctx.stateDir);
18
- return state.injectedCheckpointIds.includes(checkpointId);
19
- }
@@ -1,105 +0,0 @@
1
- /**
2
- * vectorStore/store.ts — VectorStore class (thin wrapper delegating to
3
- * sub-modules). Public API is identical to the pre-split monolith.
4
- */
5
- import { defaultEmbedder } from "../embedder.js";
6
- import { loadDedupConfig } from "../config/dedup.js";
7
- import { getStateDir } from "../store.js";
8
- import { openBloom } from "../store/bloom.js";
9
- import { migrateJsonToSqlite } from "../store/migrate.js";
10
- import { addToStore } from "./add.js";
11
- import { searchStore } from "./search.js";
12
- import { semDedupStore, dedupeCheck } from "./dedup.js";
13
- import { markInjectedStore, wasInjectedStore } from "./session.js";
14
- import { listSession, topSimilarSession, statsSession, repoStatsStore, dataInvariantStore, similarityScore, } from "./queries.js";
15
- export class VectorStore {
16
- ctx;
17
- constructor(opts = {}) {
18
- const embedder = opts.embedder ?? defaultEmbedder();
19
- const stateDir = opts.stateDir ?? getStateDir();
20
- // Sprint 14: all tier flags/thresholds flow from the single config source
21
- // (DedupConfig). The legacy opts.dedupSim / opts.l2Enabled remain accepted
22
- // for backward-compat callers but flags are authoritative via `cfg`.
23
- void opts.dedupSim;
24
- void opts.l2Enabled;
25
- // Sprint 12 L2 semantic tier. Threshold 0.85 is the default trigram
26
- // embedder's honest firing point; a direct override is allowed for tests.
27
- const cfg = opts.config ?? loadDedupConfig();
28
- const l2Threshold = opts.l2Threshold ?? cfg.L2_COSINE;
29
- this.ctx = {
30
- embedder,
31
- stateDir,
32
- l2Threshold,
33
- cfg,
34
- eventsPath: opts.eventsPath,
35
- };
36
- // Sprint 8: bring any v0.1.0 JSON checkpoint files into SQLite (idempotent).
37
- migrateJsonToSqlite(stateDir);
38
- // Sprint 10: warm the bloom accelerator (accelerator only — SQLite stays
39
- // source of truth; a bloom hit is always confirmed by a query below).
40
- openBloom(stateDir);
41
- }
42
- /** @internal Shared context for sub-module operations. */
43
- get context() {
44
- return this.ctx;
45
- }
46
- /** @internal Kept for test compatibility — delegates to ctx.stateDir. */
47
- get stateDir() {
48
- return this.ctx.stateDir;
49
- }
50
- add(input) {
51
- return addToStore(this.ctx, input);
52
- }
53
- search(sessionId, query, k = 3) {
54
- return searchStore(this.ctx, sessionId, query, k);
55
- }
56
- semDedup(sessionId, threshold = this.ctx.cfg.SEMDEDUP_COSINE) {
57
- return semDedupStore(this.ctx, sessionId, threshold);
58
- }
59
- dedupe(sessionId, regionHashOrText, isText = false) {
60
- return dedupeCheck(this.ctx, sessionId, regionHashOrText, isText);
61
- }
62
- /** Mark a checkpoint as injected into the window (recall dedup). */
63
- markInjected(sessionId, checkpointId) {
64
- markInjectedStore(this.ctx, sessionId, checkpointId);
65
- }
66
- /** True if this checkpoint was already injected this session. */
67
- wasInjected(sessionId, checkpointId) {
68
- return wasInjectedStore(this.ctx, sessionId, checkpointId);
69
- }
70
- /** Convenience for a raw vector cosine (exposed for tests). */
71
- similarity(a, b) {
72
- return similarityScore(a, b);
73
- }
74
- /** All checkpoints for a session (sorted by checkpointId). */
75
- list(sessionId) {
76
- return listSession(this.ctx, sessionId);
77
- }
78
- /**
79
- * Return the n most similar checkpoints to the current (most recent) checkpoint
80
- * by cosine similarity. Returns fewer than n if the session has fewer checkpoints.
81
- * The current checkpoint itself is excluded from results.
82
- */
83
- topSimilar(sessionId, n) {
84
- return topSimilarSession(this.ctx, sessionId, n);
85
- }
86
- /**
87
- * Store statistics for status reporting / logging. Returns counts + the last
88
- * (highest-numbered) checkpoint, or nulls when the session is empty.
89
- */
90
- stats(sessionId) {
91
- return statsSession(this.ctx, sessionId);
92
- }
93
- /**
94
- * Repo-wide stats — aggregates every session in this store (one per repo).
95
- * Cumulative, resumable, cross-device. Surfaces the dashboard's "Repo …"
96
- * figures; distinct from {@link stats} (per-session).
97
- */
98
- repoStats() {
99
- return repoStatsStore(this.ctx);
100
- }
101
- /** Data-safety invariant (Phase 0): regions retained vs bytes permanently deleted. */
102
- dataInvariant() {
103
- return dataInvariantStore(this.ctx);
104
- }
105
- }
@@ -1,6 +0,0 @@
1
- /**
2
- * vectorStore/types.ts — Shared types, constants, and context interface for the
3
- * vector store sub-modules.
4
- */
5
- /** Default L2 semantic-dedup enable flag (trigram embedder is local, zero-network). */
6
- export const L2_ENABLED = true;
@@ -1,23 +0,0 @@
1
- /**
2
- * vectorStore/utils.ts — Hashing and monitoring utilities.
3
- */
4
- import { createHash } from "node:crypto";
5
- import { logDecision } from "../monitoring.js";
6
- /** Stable hash of a compacted region, the dedup sentinel key. */
7
- export function computeRegionHash(regionText) {
8
- // Normalize whitespace before hashing so "foo bar" and "foo bar" dedup.
9
- const normalized = regionText.replace(/\s+/g, " ").trim();
10
- return createHash("sha256").update(normalized).digest("hex").slice(0, 16);
11
- }
12
- /** Emit a structured dedup-decision event (best-effort, never throws). */
13
- export function recordDecision(ctx, tier, result, reason, latencyMs) {
14
- if (!ctx.eventsPath)
15
- return;
16
- logDecision(ctx.eventsPath, {
17
- ts: Date.now(),
18
- tier,
19
- result,
20
- reason,
21
- latencyMs: Math.round(latencyMs * 100) / 100,
22
- });
23
- }