supipowers 1.5.3 → 2.0.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.
- package/README.md +14 -8
- package/bin/install.mjs +20 -5
- package/bin/install.ts +95 -0
- package/package.json +8 -4
- package/skills/context-mode/SKILL.md +17 -10
- package/skills/harness/SKILL.md +94 -0
- package/skills/ui-design/SKILL.md +63 -0
- package/skills/ui-design/sub-agent-templates/component-builder.md +29 -0
- package/skills/ui-design/sub-agent-templates/design-critic.md +46 -0
- package/skills/ui-design/sub-agent-templates/pencil/component-builder.md +29 -0
- package/skills/ui-design/sub-agent-templates/pencil/design-critic.md +42 -0
- package/skills/ui-design/sub-agent-templates/pencil/section-assembler.md +27 -0
- package/skills/ui-design/sub-agent-templates/section-assembler.md +27 -0
- package/skills/ultraplan-discover/SKILL.md +96 -0
- package/skills/ultraplan-intake/SKILL.md +89 -0
- package/skills/ultraplan-research/SKILL.md +129 -0
- package/skills/ultraplan-review/SKILL.md +86 -0
- package/skills/ultraplan-review-scope/SKILL.md +111 -0
- package/skills/ultraplan-review-structure/SKILL.md +120 -0
- package/skills/ultraplan-review-tdd/SKILL.md +142 -0
- package/skills/ultraplan-scout/SKILL.md +110 -0
- package/skills/ultraplan-synthesize/SKILL.md +124 -0
- package/src/{quality/ai-session.ts → ai/final-message.ts} +27 -0
- package/src/ai/schema-text.ts +129 -0
- package/src/ai/structured-output.ts +274 -0
- package/src/ai/template.ts +27 -0
- package/src/bootstrap.ts +63 -28
- package/src/commands/agents.ts +131 -42
- package/src/commands/ai-review.ts +251 -30
- package/src/commands/clear.ts +434 -0
- package/src/commands/commit.ts +1 -0
- package/src/commands/config.ts +242 -44
- package/src/commands/context.ts +55 -28
- package/src/commands/doctor.ts +234 -6
- package/src/commands/fix-pr.ts +306 -131
- package/src/commands/generate.ts +111 -21
- package/src/commands/memory.ts +192 -0
- package/src/commands/model-picker.ts +28 -21
- package/src/commands/model.ts +18 -8
- package/src/commands/optimize-context.ts +408 -29
- package/src/commands/plan.ts +2 -0
- package/src/commands/qa.ts +312 -137
- package/src/commands/release.ts +259 -76
- package/src/commands/review.ts +293 -59
- package/src/commands/status.ts +200 -13
- package/src/commands/supi.ts +3 -35
- package/src/commands/ui-design.ts +394 -0
- package/src/commands/ultraplan.ts +1518 -0
- package/src/commands/update.ts +86 -0
- package/src/config/defaults.ts +62 -0
- package/src/config/loader.ts +448 -60
- package/src/config/schema.ts +108 -2
- package/src/context/optimizer.ts +25 -33
- package/src/context/rule-renderer.ts +223 -0
- package/src/context/savings.ts +258 -0
- package/src/context/startup-check.ts +380 -0
- package/src/context/startup-optimizer.ts +355 -0
- package/src/context/tokenignore.ts +146 -0
- package/src/context-mode/cache-handle.ts +49 -0
- package/src/context-mode/cache-preview.ts +71 -0
- package/src/context-mode/cache-store.ts +738 -0
- package/src/context-mode/compressor.ts +131 -26
- package/src/context-mode/dedup.ts +108 -0
- package/src/context-mode/detector.ts +35 -4
- package/src/context-mode/event-extractor.ts +14 -12
- package/src/context-mode/event-store.ts +91 -36
- package/src/context-mode/hooks.ts +798 -56
- package/src/context-mode/knowledge/store.ts +255 -11
- package/src/context-mode/memory-store.ts +325 -0
- package/src/context-mode/metrics-recorder.ts +158 -0
- package/src/context-mode/metrics-store.ts +765 -0
- package/src/context-mode/model.ts +24 -0
- package/src/context-mode/processor-keys.ts +29 -0
- package/src/context-mode/processors/build.ts +66 -0
- package/src/context-mode/processors/docker.ts +57 -0
- package/src/context-mode/processors/git.ts +111 -0
- package/src/context-mode/processors/json.ts +112 -0
- package/src/context-mode/processors/k8s.ts +67 -0
- package/src/context-mode/processors/lint.ts +67 -0
- package/src/context-mode/processors/log.ts +86 -0
- package/src/context-mode/processors/registry.ts +116 -0
- package/src/context-mode/processors/test-runner.ts +102 -0
- package/src/context-mode/processors/types.ts +20 -0
- package/src/context-mode/repomap.ts +400 -0
- package/src/context-mode/routing.ts +97 -24
- package/src/context-mode/sandbox/runners.ts +5 -1
- package/src/context-mode/snapshot-builder.ts +106 -11
- package/src/context-mode/source-hash.ts +173 -0
- package/src/context-mode/tool-name.ts +11 -0
- package/src/context-mode/tools.ts +654 -22
- package/src/context-mode/web/fetcher.ts +31 -12
- package/src/debug/logger.ts +2 -1
- package/src/deps/registry.ts +1 -1
- package/src/discipline/failure-summarizer.ts +170 -0
- package/src/discipline/failure-taxonomy.ts +131 -0
- package/src/discipline/workflow-invariants.ts +125 -0
- package/src/discovery/index.ts +31 -0
- package/src/discovery/lsp.ts +87 -0
- package/src/discovery/rank.ts +144 -0
- package/src/discovery/sources.ts +89 -0
- package/src/discovery/workflow.ts +87 -0
- package/src/docs/contracts.ts +39 -0
- package/src/docs/drift.ts +117 -87
- package/src/fix-pr/assessment.ts +200 -0
- package/src/fix-pr/contracts.ts +47 -0
- package/src/fix-pr/fetch-comments.ts +80 -0
- package/src/fix-pr/prompt-builder.ts +58 -40
- package/src/fix-pr/scripts/exec.ts +34 -0
- package/src/fix-pr/scripts/trigger-review.ts +106 -0
- package/src/fix-pr/scripts/wait-and-check.ts +108 -0
- package/src/fix-pr/types.ts +4 -0
- package/src/git/branch-finish.ts +5 -0
- package/src/git/commit-contract.ts +83 -0
- package/src/git/commit.ts +121 -184
- package/src/git/status.ts +62 -8
- package/src/harness/anti_slop/architecture-parser.ts +210 -0
- package/src/harness/anti_slop/backend-factory.ts +30 -0
- package/src/harness/anti_slop/backend.ts +140 -0
- package/src/harness/anti_slop/desloppify-adapter.ts +319 -0
- package/src/harness/anti_slop/fallow-adapter.ts +305 -0
- package/src/harness/anti_slop/installer.ts +227 -0
- package/src/harness/anti_slop/queue.ts +216 -0
- package/src/harness/anti_slop/recommend.ts +84 -0
- package/src/harness/anti_slop/score.ts +180 -0
- package/src/harness/anti_slop/synthetic-edit-test.ts +128 -0
- package/src/harness/artifacts/agents-md.ts +88 -0
- package/src/harness/artifacts/checks-wiring.ts +57 -0
- package/src/harness/artifacts/docs-tree.ts +79 -0
- package/src/harness/artifacts/lint-configs.ts +136 -0
- package/src/harness/artifacts/review-agents.ts +67 -0
- package/src/harness/bare-entry.ts +108 -0
- package/src/harness/command.ts +1010 -0
- package/src/harness/default-agents/design.md +23 -0
- package/src/harness/default-agents/discover.md +18 -0
- package/src/harness/default-agents/implement.md +24 -0
- package/src/harness/default-agents/plan.md +19 -0
- package/src/harness/default-agents/research.md +21 -0
- package/src/harness/default-agents/validate.md +22 -0
- package/src/harness/gc/reporter.ts +28 -0
- package/src/harness/gc/runner.ts +136 -0
- package/src/harness/hooks/layer-context-inject.ts +155 -0
- package/src/harness/hooks/post-session-sweep.ts +130 -0
- package/src/harness/hooks/pre-edit-dupe-probe.ts +224 -0
- package/src/harness/hooks/register.ts +118 -0
- package/src/harness/model.ts +117 -0
- package/src/harness/pipeline.ts +348 -0
- package/src/harness/project-paths.ts +235 -0
- package/src/harness/stage-runner.ts +107 -0
- package/src/harness/stages/design.ts +386 -0
- package/src/harness/stages/discover.ts +454 -0
- package/src/harness/stages/implement.ts +162 -0
- package/src/harness/stages/plan.ts +335 -0
- package/src/harness/stages/research.ts +263 -0
- package/src/harness/stages/validate.ts +684 -0
- package/src/harness/storage.ts +467 -0
- package/src/harness/tools.ts +426 -0
- package/src/lsp/bridge.ts +56 -95
- package/src/lsp/capabilities.ts +108 -0
- package/src/lsp/contracts.ts +35 -0
- package/src/lsp/detector.ts +8 -12
- package/src/markdown-frontmatter.ts +68 -0
- package/src/mempalace/bridge.ts +129 -0
- package/src/mempalace/config.ts +75 -0
- package/src/mempalace/format.ts +163 -0
- package/src/mempalace/hooks.ts +370 -0
- package/src/mempalace/installer-helper.ts +194 -0
- package/src/mempalace/python/mempalace_bridge.py +440 -0
- package/src/mempalace/runtime.ts +565 -0
- package/src/mempalace/schema.ts +264 -0
- package/src/mempalace/session-summary.ts +198 -0
- package/src/mempalace/tool.ts +186 -0
- package/src/mempalace/uv.ts +256 -0
- package/src/migrate/runner.ts +354 -0
- package/src/planning/approval-flow.ts +206 -9
- package/src/planning/plan-writer-prompt.ts +4 -3
- package/src/planning/planning-ask-tool.ts +39 -0
- package/src/planning/render-markdown.ts +74 -0
- package/src/planning/spec.ts +42 -0
- package/src/planning/system-prompt.ts +11 -8
- package/src/planning/validate.ts +84 -0
- package/src/platform/omp.ts +15 -2
- package/src/platform/system-prompt.ts +37 -0
- package/src/platform/test-utils.ts +3 -0
- package/src/platform/types.ts +6 -1
- package/src/qa/config.ts +12 -6
- package/src/qa/detect-app-type.ts +13 -6
- package/src/qa/matrix.ts +12 -6
- package/src/qa/prompt-builder.ts +28 -30
- package/src/qa/scripts/dev-server-utils.ts +72 -0
- package/src/qa/scripts/run-e2e-tests.ts +226 -0
- package/src/qa/scripts/start-dev-server.ts +138 -0
- package/src/qa/scripts/stop-dev-server.ts +77 -0
- package/src/qa/session.ts +13 -7
- package/src/quality/ai-setup.ts +27 -25
- package/src/quality/contracts.ts +34 -0
- package/src/quality/gates/ai-review.ts +20 -58
- package/src/quality/gates/command.ts +249 -46
- package/src/quality/review-gates.ts +18 -2
- package/src/quality/runner.ts +63 -22
- package/src/quality/schemas.ts +37 -2
- package/src/quality/setup.ts +96 -16
- package/src/release/changelog.ts +1 -1
- package/src/release/channels/custom.ts +13 -3
- package/src/release/channels/types.ts +5 -0
- package/src/release/contracts.ts +90 -0
- package/src/release/executor.ts +122 -45
- package/src/release/prompt.ts +18 -2
- package/src/release/targets.ts +86 -0
- package/src/release/version.ts +96 -71
- package/src/review/agent-loader.ts +221 -109
- package/src/review/fixer.ts +10 -6
- package/src/review/multi-agent-runner.ts +114 -13
- package/src/review/output.ts +12 -139
- package/src/review/runner.ts +12 -6
- package/src/review/scope.ts +144 -24
- package/src/review/types.ts +1 -20
- package/src/review/validator.ts +12 -6
- package/src/storage/fix-pr-sessions.ts +21 -14
- package/src/storage/plans.ts +14 -5
- package/src/storage/qa-sessions.ts +25 -19
- package/src/storage/reliability-metrics.ts +180 -0
- package/src/storage/reports.ts +8 -7
- package/src/storage/review-sessions.ts +55 -20
- package/src/tool-catalog/active-tool-controller.ts +164 -0
- package/src/tool-catalog/active-tool-planner.ts +212 -0
- package/src/tool-catalog/tool-groups.ts +102 -0
- package/src/types.ts +1399 -5
- package/src/ui-design/backend-adapter.ts +78 -0
- package/src/ui-design/backends/local-html.ts +82 -0
- package/src/ui-design/backends/pencil-mcp.ts +111 -0
- package/src/ui-design/components-scanner.ts +124 -0
- package/src/ui-design/config.ts +55 -0
- package/src/ui-design/pen-scanner.ts +95 -0
- package/src/ui-design/pen-selector.ts +72 -0
- package/src/ui-design/prompt-builder.ts +73 -0
- package/src/ui-design/scanner.ts +136 -0
- package/src/ui-design/session.ts +974 -0
- package/src/ui-design/system-prompt.ts +312 -0
- package/src/ui-design/tokens-scanner.ts +181 -0
- package/src/ui-design/types.ts +96 -0
- package/src/ultraplan/agent-catalog.ts +522 -0
- package/src/ultraplan/authoring/agent-catalog.ts +310 -0
- package/src/ultraplan/authoring/authoring-tools.ts +552 -0
- package/src/ultraplan/authoring/command-handlers.ts +339 -0
- package/src/ultraplan/authoring/markdown.ts +510 -0
- package/src/ultraplan/authoring/model.ts +162 -0
- package/src/ultraplan/authoring/pipeline.ts +319 -0
- package/src/ultraplan/authoring/stage-runner.ts +141 -0
- package/src/ultraplan/authoring/stages/approve.ts +249 -0
- package/src/ultraplan/authoring/stages/discover.ts +289 -0
- package/src/ultraplan/authoring/stages/intake.ts +203 -0
- package/src/ultraplan/authoring/stages/research.ts +399 -0
- package/src/ultraplan/authoring/stages/review.ts +333 -0
- package/src/ultraplan/authoring/stages/scout.ts +188 -0
- package/src/ultraplan/authoring/stages/synthesize.ts +348 -0
- package/src/ultraplan/authoring/storage.ts +594 -0
- package/src/ultraplan/authoring/synth-gate.ts +165 -0
- package/src/ultraplan/authoring-draft.ts +653 -0
- package/src/ultraplan/authoring-persist.ts +180 -0
- package/src/ultraplan/authoring-tool.ts +608 -0
- package/src/ultraplan/authoring-wizard.ts +587 -0
- package/src/ultraplan/batch/merge.ts +98 -0
- package/src/ultraplan/batch/planner.ts +150 -0
- package/src/ultraplan/batch/presenter.ts +97 -0
- package/src/ultraplan/batch/storage.ts +420 -0
- package/src/ultraplan/batch/supervisor.ts +317 -0
- package/src/ultraplan/batch/worker.ts +26 -0
- package/src/ultraplan/batch/worktree.ts +110 -0
- package/src/ultraplan/contracts.ts +1593 -0
- package/src/ultraplan/default-agents/authoring/discoverer.md +12 -0
- package/src/ultraplan/default-agents/authoring/intake.md +12 -0
- package/src/ultraplan/default-agents/authoring/planner.md +12 -0
- package/src/ultraplan/default-agents/authoring/researcher.md +12 -0
- package/src/ultraplan/default-agents/authoring/scope-checker.md +12 -0
- package/src/ultraplan/default-agents/authoring/scout.md +12 -0
- package/src/ultraplan/default-agents/authoring/structure-checker.md +12 -0
- package/src/ultraplan/default-agents/authoring/tdd-checker.md +12 -0
- package/src/ultraplan/default-agents/backend-domain-reviewer.md +10 -0
- package/src/ultraplan/default-agents/backend-executor.md +10 -0
- package/src/ultraplan/default-agents/backend-stack-reviewer.md +10 -0
- package/src/ultraplan/default-agents/backend-tester.md +10 -0
- package/src/ultraplan/default-agents/frontend-domain-reviewer.md +10 -0
- package/src/ultraplan/default-agents/frontend-executor.md +10 -0
- package/src/ultraplan/default-agents/frontend-stack-reviewer.md +10 -0
- package/src/ultraplan/default-agents/frontend-tester.md +10 -0
- package/src/ultraplan/default-agents/infrastructure-domain-reviewer.md +10 -0
- package/src/ultraplan/default-agents/infrastructure-executor.md +10 -0
- package/src/ultraplan/default-agents/infrastructure-stack-reviewer.md +10 -0
- package/src/ultraplan/default-agents/infrastructure-tester.md +10 -0
- package/src/ultraplan/execution/contract.ts +71 -0
- package/src/ultraplan/execution/policy.ts +217 -0
- package/src/ultraplan/execution/runtime-tools.ts +107 -0
- package/src/ultraplan/execution/session-runner.ts +281 -0
- package/src/ultraplan/next-router.ts +85 -0
- package/src/ultraplan/presenter.ts +359 -0
- package/src/ultraplan/project-paths.ts +342 -0
- package/src/ultraplan/runtime/active-execution.ts +72 -0
- package/src/ultraplan/runtime/apply-mutation.ts +416 -0
- package/src/ultraplan/runtime/blockers.ts +243 -0
- package/src/ultraplan/runtime/hook-bridge.ts +486 -0
- package/src/ultraplan/runtime/launch-context.ts +207 -0
- package/src/ultraplan/runtime/migration.ts +524 -0
- package/src/ultraplan/runtime/normalize.ts +281 -0
- package/src/ultraplan/runtime/proof.ts +260 -0
- package/src/ultraplan/runtime/reducer.ts +416 -0
- package/src/ultraplan/runtime/repair.ts +251 -0
- package/src/ultraplan/runtime/tracker-storage.ts +368 -0
- package/src/ultraplan/session-selection.ts +291 -0
- package/src/ultraplan/storage.ts +374 -0
- package/src/utils/editor.ts +38 -0
- package/src/utils/executable.ts +80 -0
- package/src/utils/paths.ts +1 -20
- package/src/utils/shell.ts +31 -0
- package/src/visual/companion.ts +2 -1
- package/src/visual/scripts/frame-template.html +60 -0
- package/src/visual/scripts/index.js +59 -13
- package/src/visual/scripts/package.json +3 -0
- package/src/visual/start-server.ts +2 -1
- package/src/workspace/git-scope.ts +64 -0
- package/src/workspace/locks.ts +23 -0
- package/src/workspace/package-manager.ts +117 -0
- package/src/workspace/path-mapping.ts +75 -0
- package/src/workspace/project-slug.ts +92 -0
- package/src/workspace/repo-root.ts +137 -0
- package/src/workspace/selector.ts +115 -0
- package/src/workspace/state-paths.ts +118 -0
- package/src/workspace/targets.ts +313 -0
- package/src/fix-pr/scripts/diff-comments.sh +0 -33
- package/src/fix-pr/scripts/fetch-pr-comments.sh +0 -25
- package/src/fix-pr/scripts/trigger-review.sh +0 -36
- package/src/fix-pr/scripts/wait-and-check.sh +0 -37
- package/src/qa/scripts/detect-app-type.sh +0 -68
- package/src/qa/scripts/discover-routes.sh +0 -143
- package/src/qa/scripts/run-e2e-tests.sh +0 -131
- package/src/qa/scripts/start-dev-server.sh +0 -46
- package/src/qa/scripts/stop-dev-server.sh +0 -36
- package/src/review/prompts/fix-output-schema.md +0 -18
- package/src/review/prompts/review-output-schema.md +0 -38
- package/src/review/template.ts +0 -15
- /package/src/{review → ai}/prompts/invalid-output-retry.md +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/context-mode/event-store.ts
|
|
2
|
-
import { Database } from "bun:sqlite";
|
|
2
|
+
import { constants, Database } from "bun:sqlite";
|
|
3
3
|
import { createHash } from "node:crypto";
|
|
4
4
|
|
|
5
5
|
/** Event categories extracted from tool results */
|
|
@@ -129,75 +129,117 @@ function computeDataHash(data: string): string {
|
|
|
129
129
|
return createHash("sha256").update(data).digest("hex").slice(0, 16);
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
+
|
|
133
|
+
|
|
132
134
|
export class EventStore {
|
|
133
|
-
|
|
135
|
+
#db: Database;
|
|
136
|
+
readonly #dbPath: string;
|
|
137
|
+
#closed = false;
|
|
134
138
|
|
|
135
139
|
constructor(dbPath: string) {
|
|
136
|
-
this
|
|
140
|
+
this.#dbPath = dbPath;
|
|
141
|
+
this.#db = new Database(dbPath);
|
|
137
142
|
}
|
|
138
143
|
|
|
139
144
|
init(): void {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
145
|
+
try {
|
|
146
|
+
this.#ensureDeleteJournalMode();
|
|
147
|
+
this.#migrate();
|
|
148
|
+
this.#db.exec(SCHEMA);
|
|
149
|
+
} catch (error) {
|
|
150
|
+
this.close();
|
|
151
|
+
throw error;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
#ensureDeleteJournalMode(): void {
|
|
156
|
+
const journalMode = this.#getJournalMode();
|
|
157
|
+
if (journalMode === "delete") return;
|
|
158
|
+
|
|
159
|
+
if (journalMode === "wal") {
|
|
160
|
+
this.#cleanupWalSidecars();
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
try {
|
|
164
|
+
this.#db.exec("PRAGMA journal_mode = DELETE;");
|
|
165
|
+
} catch {
|
|
166
|
+
// Older WAL-backed databases can stay on WAL for this process.
|
|
167
|
+
// close() still checkpoints them so teardown and the next reopen succeed.
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
#getJournalMode(): string {
|
|
172
|
+
const { journal_mode } = this.#db.prepare("PRAGMA journal_mode").get() as {
|
|
173
|
+
journal_mode: string;
|
|
174
|
+
};
|
|
175
|
+
return journal_mode.toLowerCase();
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
#cleanupWalSidecars(): void {
|
|
179
|
+
try {
|
|
180
|
+
this.#db.fileControl(constants.SQLITE_FCNTL_PERSIST_WAL, 0);
|
|
181
|
+
this.#db.exec("PRAGMA wal_checkpoint(TRUNCATE);");
|
|
182
|
+
} catch {
|
|
183
|
+
// Best effort only: close() still releases the handle in finally.
|
|
184
|
+
}
|
|
143
185
|
}
|
|
144
186
|
|
|
145
187
|
// ── Schema migration ────────────────────────────────────────
|
|
146
188
|
|
|
147
|
-
|
|
148
|
-
const { user_version } = this
|
|
189
|
+
#migrate(): void {
|
|
190
|
+
const { user_version } = this.#db.prepare("PRAGMA user_version").get() as { user_version: number };
|
|
149
191
|
if (user_version >= SCHEMA_VERSION) return;
|
|
150
192
|
|
|
151
193
|
// Upgrade from v0: session_events exists but lacks data_hash column
|
|
152
|
-
const tableExists = this
|
|
194
|
+
const tableExists = this.#db.prepare(
|
|
153
195
|
"SELECT name FROM sqlite_master WHERE type='table' AND name='session_events'",
|
|
154
196
|
).get();
|
|
155
197
|
|
|
156
198
|
if (tableExists) {
|
|
157
199
|
try {
|
|
158
|
-
this
|
|
200
|
+
this.#db.exec("ALTER TABLE session_events ADD COLUMN data_hash TEXT NOT NULL DEFAULT ''");
|
|
159
201
|
} catch {
|
|
160
202
|
// Column already exists (fresh install ran SCHEMA first somehow)
|
|
161
203
|
}
|
|
162
204
|
}
|
|
163
205
|
|
|
164
|
-
this
|
|
206
|
+
this.#db.exec(`PRAGMA user_version = ${SCHEMA_VERSION};`);
|
|
165
207
|
}
|
|
166
208
|
|
|
167
209
|
// ── Write with dedup + eviction ─────────────────────────────
|
|
168
210
|
|
|
169
211
|
writeEvent(event: Omit<TrackedEvent, "id" | "dataHash">): void {
|
|
170
212
|
const dataHash = computeDataHash(event.data);
|
|
171
|
-
if (this
|
|
213
|
+
if (this.#isDuplicate(event.sessionId, event.category, dataHash)) return;
|
|
172
214
|
|
|
173
|
-
this
|
|
215
|
+
this.#db.prepare(
|
|
174
216
|
"INSERT INTO session_events (session_id, category, data, priority, source, timestamp, data_hash) VALUES (?, ?, ?, ?, ?, ?, ?)",
|
|
175
217
|
).run(event.sessionId, event.category, event.data, event.priority, event.source, event.timestamp, dataHash);
|
|
176
218
|
|
|
177
|
-
this
|
|
219
|
+
this.#enforceEventCap(event.sessionId);
|
|
178
220
|
}
|
|
179
221
|
|
|
180
222
|
writeEvents(events: Omit<TrackedEvent, "id" | "dataHash">[]): void {
|
|
181
223
|
if (events.length === 0) return;
|
|
182
224
|
|
|
183
|
-
const insert = this
|
|
225
|
+
const insert = this.#db.prepare(
|
|
184
226
|
"INSERT INTO session_events (session_id, category, data, priority, source, timestamp, data_hash) VALUES (?, ?, ?, ?, ?, ?, ?)",
|
|
185
227
|
);
|
|
186
|
-
const tx = this
|
|
228
|
+
const tx = this.#db.transaction(() => {
|
|
187
229
|
for (const event of events) {
|
|
188
230
|
const dataHash = computeDataHash(event.data);
|
|
189
|
-
if (this
|
|
231
|
+
if (this.#isDuplicate(event.sessionId, event.category, dataHash)) continue;
|
|
190
232
|
insert.run(event.sessionId, event.category, event.data, event.priority, event.source, event.timestamp, dataHash);
|
|
191
233
|
}
|
|
192
234
|
});
|
|
193
235
|
tx();
|
|
194
236
|
|
|
195
|
-
this
|
|
237
|
+
this.#enforceEventCap(events[0].sessionId);
|
|
196
238
|
}
|
|
197
239
|
|
|
198
240
|
/** Check last DEDUP_WINDOW events for same category + content hash */
|
|
199
|
-
|
|
200
|
-
const row = this
|
|
241
|
+
#isDuplicate(sessionId: string, category: string, dataHash: string): boolean {
|
|
242
|
+
const row = this.#db.prepare(
|
|
201
243
|
`SELECT 1 FROM (
|
|
202
244
|
SELECT category, data_hash FROM session_events
|
|
203
245
|
WHERE session_id = ? ORDER BY id DESC LIMIT ?
|
|
@@ -207,15 +249,15 @@ export class EventStore {
|
|
|
207
249
|
}
|
|
208
250
|
|
|
209
251
|
/** Delete lowest-priority (highest number), then oldest events to stay at cap */
|
|
210
|
-
|
|
211
|
-
const { count } = this
|
|
252
|
+
#enforceEventCap(sessionId: string): void {
|
|
253
|
+
const { count } = this.#db.prepare(
|
|
212
254
|
"SELECT COUNT(*) AS count FROM session_events WHERE session_id = ?",
|
|
213
255
|
).get(sessionId) as { count: number };
|
|
214
256
|
|
|
215
257
|
if (count <= MAX_EVENTS_PER_SESSION) return;
|
|
216
258
|
|
|
217
259
|
const excess = count - MAX_EVENTS_PER_SESSION;
|
|
218
|
-
this
|
|
260
|
+
this.#db.prepare(
|
|
219
261
|
`DELETE FROM session_events WHERE id IN (
|
|
220
262
|
SELECT id FROM session_events WHERE session_id = ?
|
|
221
263
|
ORDER BY CAST(priority AS INTEGER) DESC, timestamp ASC
|
|
@@ -258,7 +300,7 @@ export class EventStore {
|
|
|
258
300
|
params.push(filters.limit);
|
|
259
301
|
}
|
|
260
302
|
|
|
261
|
-
return this
|
|
303
|
+
return this.#db.prepare(sql).all(...params) as TrackedEvent[];
|
|
262
304
|
}
|
|
263
305
|
|
|
264
306
|
searchEvents(sessionId: string, query: string, limit = 20): TrackedEvent[] {
|
|
@@ -271,11 +313,11 @@ export class EventStore {
|
|
|
271
313
|
ORDER BY rank
|
|
272
314
|
LIMIT ?
|
|
273
315
|
`;
|
|
274
|
-
return this
|
|
316
|
+
return this.#db.prepare(sql).all(query, sessionId, limit) as TrackedEvent[];
|
|
275
317
|
}
|
|
276
318
|
|
|
277
319
|
getEventCounts(sessionId: string): Record<EventCategory, number> {
|
|
278
|
-
const rows = this
|
|
320
|
+
const rows = this.#db.prepare(
|
|
279
321
|
"SELECT category, COUNT(*) AS count FROM session_events WHERE session_id = ? GROUP BY category",
|
|
280
322
|
).all(sessionId) as Array<{ category: EventCategory; count: number }>;
|
|
281
323
|
|
|
@@ -288,7 +330,7 @@ export class EventStore {
|
|
|
288
330
|
// ── Session metadata ────────────────────────────────────────
|
|
289
331
|
|
|
290
332
|
upsertMeta(sessionId: string, projectDir: string): void {
|
|
291
|
-
this
|
|
333
|
+
this.#db.prepare(
|
|
292
334
|
`INSERT INTO session_meta (session_id, project_dir, event_count)
|
|
293
335
|
VALUES (?, ?, 0)
|
|
294
336
|
ON CONFLICT(session_id) DO UPDATE SET
|
|
@@ -298,7 +340,7 @@ export class EventStore {
|
|
|
298
340
|
}
|
|
299
341
|
|
|
300
342
|
getMeta(sessionId: string): SessionMeta | null {
|
|
301
|
-
const row = this
|
|
343
|
+
const row = this.#db.prepare(
|
|
302
344
|
`SELECT session_id AS sessionId, project_dir AS projectDir,
|
|
303
345
|
started_at AS startedAt, last_event_at AS lastEventAt,
|
|
304
346
|
event_count AS eventCount, compact_count AS compactCount
|
|
@@ -308,7 +350,7 @@ export class EventStore {
|
|
|
308
350
|
}
|
|
309
351
|
|
|
310
352
|
incrementCompactCount(sessionId: string): void {
|
|
311
|
-
this
|
|
353
|
+
this.#db.prepare(
|
|
312
354
|
"UPDATE session_meta SET compact_count = compact_count + 1 WHERE session_id = ?",
|
|
313
355
|
).run(sessionId);
|
|
314
356
|
}
|
|
@@ -316,7 +358,7 @@ export class EventStore {
|
|
|
316
358
|
// ── Resume snapshots ────────────────────────────────────────
|
|
317
359
|
|
|
318
360
|
upsertResume(sessionId: string, snapshot: string, eventCount: number): void {
|
|
319
|
-
this
|
|
361
|
+
this.#db.prepare(
|
|
320
362
|
`INSERT INTO session_resume (session_id, snapshot, event_count, consumed)
|
|
321
363
|
VALUES (?, ?, ?, 0)
|
|
322
364
|
ON CONFLICT(session_id) DO UPDATE SET
|
|
@@ -328,7 +370,7 @@ export class EventStore {
|
|
|
328
370
|
}
|
|
329
371
|
|
|
330
372
|
getResume(sessionId: string): SessionResume | null {
|
|
331
|
-
const row = this
|
|
373
|
+
const row = this.#db.prepare(
|
|
332
374
|
`SELECT session_id AS sessionId, snapshot, event_count AS eventCount,
|
|
333
375
|
created_at AS createdAt, consumed
|
|
334
376
|
FROM session_resume WHERE session_id = ? AND consumed = 0`,
|
|
@@ -338,7 +380,7 @@ export class EventStore {
|
|
|
338
380
|
}
|
|
339
381
|
|
|
340
382
|
consumeResume(sessionId: string): void {
|
|
341
|
-
this
|
|
383
|
+
this.#db.prepare(
|
|
342
384
|
"UPDATE session_resume SET consumed = 1 WHERE session_id = ?",
|
|
343
385
|
).run(sessionId);
|
|
344
386
|
}
|
|
@@ -346,11 +388,11 @@ export class EventStore {
|
|
|
346
388
|
// ── Maintenance ─────────────────────────────────────────────
|
|
347
389
|
|
|
348
390
|
pruneEvents(olderThan: number): number {
|
|
349
|
-
const countRow = this
|
|
391
|
+
const countRow = this.#db.prepare(
|
|
350
392
|
"SELECT COUNT(*) AS count FROM session_events WHERE timestamp < ?",
|
|
351
393
|
).get(olderThan) as { count: number };
|
|
352
394
|
if (countRow.count > 0) {
|
|
353
|
-
this
|
|
395
|
+
this.#db.prepare("DELETE FROM session_events WHERE timestamp < ?").run(olderThan);
|
|
354
396
|
}
|
|
355
397
|
return countRow.count;
|
|
356
398
|
}
|
|
@@ -359,7 +401,7 @@ export class EventStore {
|
|
|
359
401
|
const cutoff = Date.now() - retentionDays * 24 * 60 * 60 * 1000;
|
|
360
402
|
const pruned = this.pruneEvents(cutoff);
|
|
361
403
|
// Remove orphaned metadata for sessions with no remaining events
|
|
362
|
-
this
|
|
404
|
+
this.#db.exec(`
|
|
363
405
|
DELETE FROM session_meta WHERE session_id NOT IN (
|
|
364
406
|
SELECT DISTINCT session_id FROM session_events
|
|
365
407
|
);
|
|
@@ -371,6 +413,19 @@ export class EventStore {
|
|
|
371
413
|
}
|
|
372
414
|
|
|
373
415
|
close(): void {
|
|
374
|
-
this
|
|
416
|
+
if (this.#closed) return;
|
|
417
|
+
|
|
418
|
+
try {
|
|
419
|
+
try {
|
|
420
|
+
if (this.#getJournalMode() === "wal") {
|
|
421
|
+
this.#cleanupWalSidecars();
|
|
422
|
+
}
|
|
423
|
+
} catch {
|
|
424
|
+
// The DB path may already be gone during teardown; still close the handle.
|
|
425
|
+
}
|
|
426
|
+
} finally {
|
|
427
|
+
this.#db.close();
|
|
428
|
+
this.#closed = true;
|
|
429
|
+
}
|
|
375
430
|
}
|
|
376
431
|
}
|