squish-memory 1.0.0 → 1.0.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/.env.mcp.example +18 -11
- package/README.md +59 -24
- package/bin/squish-add.mjs +32 -0
- package/bin/squish-rm.mjs +21 -0
- package/config/plugin-manifest.json +1 -1
- package/config/settings.json +51 -0
- package/dist/api/web/web.js +479 -452
- package/dist/commands/mcp-server.js +7 -3
- package/dist/config.d.ts +10 -10
- package/dist/config.js +78 -23
- package/dist/core/embeddings.d.ts +1 -1
- package/dist/core/embeddings.js +10 -67
- package/dist/core/local-embeddings.d.ts +3 -11
- package/dist/core/local-embeddings.js +2 -76
- package/dist/core/mcp/server.js +27 -1
- package/dist/core/mcp/types.d.ts +4 -4
- package/dist/core/memory/context-collector.js +3 -2
- package/dist/core/memory/feedback-tracker.js +10 -6
- package/dist/core/memory/hybrid-search.js +32 -32
- package/dist/core/memory/memories.js +55 -52
- package/dist/core/memory/query-rewriter.js +9 -9
- package/dist/core/memory/stats.js +5 -5
- package/dist/core/namespaces/index.js +20 -11
- package/dist/core/scheduler/cron-scheduler.js +78 -20
- package/dist/core/scheduler/job-runner.js +8 -5
- package/dist/core/search/conversations.js +33 -33
- package/dist/core/session-hooks/self-iteration-job.js +43 -39
- package/dist/core/session-hooks/session-hooks.js +6 -3
- package/dist/core/tracing/collector.js +25 -13
- package/dist/db/adapter.d.ts +6 -1
- package/dist/db/adapter.js +122 -126
- package/dist/db/bootstrap.js +622 -548
- package/dist/db/index.d.ts +5 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +195 -49
- package/generated/mcp/manifest.json +23 -23
- package/package.json +72 -59
- package/scripts/install-interactive.mjs +7 -4
- package/skills/memory-guide/SKILL.md +94 -18
- package/skills/squish-cli/SKILL.md +61 -21
- package/skills/squish-mcp/SKILL.md +46 -2
- package/skills/squish-memory/SKILL.md +30 -16
- package/dist/algorithms/analytics/token-estimator.d.ts.map +0 -1
- package/dist/algorithms/analytics/token-estimator.js.map +0 -1
- package/dist/algorithms/detection/hash-filters.d.ts.map +0 -1
- package/dist/algorithms/detection/hash-filters.js.map +0 -1
- package/dist/algorithms/detection/semantic-ranker.d.ts.map +0 -1
- package/dist/algorithms/detection/semantic-ranker.js.map +0 -1
- package/dist/algorithms/detection/two-stage-detector.d.ts.map +0 -1
- package/dist/algorithms/detection/two-stage-detector.js.map +0 -1
- package/dist/algorithms/handlers/approve-merge.d.ts.map +0 -1
- package/dist/algorithms/handlers/approve-merge.js.map +0 -1
- package/dist/algorithms/handlers/detect-duplicates.d.ts.map +0 -1
- package/dist/algorithms/handlers/detect-duplicates.js.map +0 -1
- package/dist/algorithms/handlers/get-stats.d.ts.map +0 -1
- package/dist/algorithms/handlers/get-stats.js.map +0 -1
- package/dist/algorithms/handlers/list-proposals.d.ts.map +0 -1
- package/dist/algorithms/handlers/list-proposals.js.map +0 -1
- package/dist/algorithms/handlers/preview-merge.d.ts.map +0 -1
- package/dist/algorithms/handlers/preview-merge.js.map +0 -1
- package/dist/algorithms/handlers/reject-merge.d.ts.map +0 -1
- package/dist/algorithms/handlers/reject-merge.js.map +0 -1
- package/dist/algorithms/handlers/reverse-merge.d.ts.map +0 -1
- package/dist/algorithms/handlers/reverse-merge.js.map +0 -1
- package/dist/algorithms/safety/safety-checks.d.ts.map +0 -1
- package/dist/algorithms/safety/safety-checks.js.map +0 -1
- package/dist/algorithms/strategies/merge-strategies.d.ts.map +0 -1
- package/dist/algorithms/strategies/merge-strategies.js.map +0 -1
- package/dist/algorithms/utils/response-builder.d.ts.map +0 -1
- package/dist/algorithms/utils/response-builder.js.map +0 -1
- package/dist/api/web/index.d.ts.map +0 -1
- package/dist/api/web/index.js.map +0 -1
- package/dist/api/web/web-server.d.ts.map +0 -1
- package/dist/api/web/web-server.js.map +0 -1
- package/dist/api/web/web.d.ts.map +0 -1
- package/dist/api/web/web.js.map +0 -1
- package/dist/commands/managed-sync.d.ts.map +0 -1
- package/dist/commands/managed-sync.js.map +0 -1
- package/dist/commands/mcp-server.d.ts.map +0 -1
- package/dist/commands/mcp-server.js.map +0 -1
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js.map +0 -1
- package/dist/core/agent-memory.d.ts.map +0 -1
- package/dist/core/agent-memory.js.map +0 -1
- package/dist/core/associations.d.ts.map +0 -1
- package/dist/core/associations.js.map +0 -1
- package/dist/core/cache.d.ts.map +0 -1
- package/dist/core/cache.js.map +0 -1
- package/dist/core/consolidation.d.ts.map +0 -1
- package/dist/core/consolidation.js.map +0 -1
- package/dist/core/context-paging.d.ts.map +0 -1
- package/dist/core/context-paging.js.map +0 -1
- package/dist/core/context.d.ts.map +0 -1
- package/dist/core/context.js.map +0 -1
- package/dist/core/core-memory.d.ts.map +0 -1
- package/dist/core/core-memory.js.map +0 -1
- package/dist/core/database.d.ts.map +0 -1
- package/dist/core/database.js.map +0 -1
- package/dist/core/embeddings/google-multimodal.d.ts.map +0 -1
- package/dist/core/embeddings/google-multimodal.js.map +0 -1
- package/dist/core/embeddings/qmd-client.d.ts.map +0 -1
- package/dist/core/embeddings/qmd-client.js.map +0 -1
- package/dist/core/embeddings.d.ts.map +0 -1
- package/dist/core/embeddings.js.map +0 -1
- package/dist/core/governance.d.ts.map +0 -1
- package/dist/core/governance.js.map +0 -1
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/index.js.map +0 -1
- package/dist/core/layers/generator.d.ts.map +0 -1
- package/dist/core/layers/generator.js.map +0 -1
- package/dist/core/lifecycle.d.ts.map +0 -1
- package/dist/core/lifecycle.js.map +0 -1
- package/dist/core/local-embeddings.d.ts.map +0 -1
- package/dist/core/local-embeddings.js.map +0 -1
- package/dist/core/logger.d.ts.map +0 -1
- package/dist/core/logger.js.map +0 -1
- package/dist/core/mcp/client.d.ts.map +0 -1
- package/dist/core/mcp/client.js.map +0 -1
- package/dist/core/mcp/index.d.ts.map +0 -1
- package/dist/core/mcp/index.js.map +0 -1
- package/dist/core/mcp/server.d.ts.map +0 -1
- package/dist/core/mcp/server.js.map +0 -1
- package/dist/core/mcp/standalone-server.d.ts.map +0 -1
- package/dist/core/mcp/standalone-server.js.map +0 -1
- package/dist/core/mcp/tools.d.ts.map +0 -1
- package/dist/core/mcp/tools.js.map +0 -1
- package/dist/core/mcp/types.d.ts.map +0 -1
- package/dist/core/mcp/types.js.map +0 -1
- package/dist/core/memory/bridge-discovery.d.ts.map +0 -1
- package/dist/core/memory/bridge-discovery.js.map +0 -1
- package/dist/core/memory/categorizer.d.ts.map +0 -1
- package/dist/core/memory/categorizer.js.map +0 -1
- package/dist/core/memory/conflict-detector.d.ts.map +0 -1
- package/dist/core/memory/conflict-detector.js.map +0 -1
- package/dist/core/memory/consolidation.d.ts.map +0 -1
- package/dist/core/memory/consolidation.js.map +0 -1
- package/dist/core/memory/context-collector.d.ts.map +0 -1
- package/dist/core/memory/context-collector.js.map +0 -1
- package/dist/core/memory/contradiction-resolver.d.ts.map +0 -1
- package/dist/core/memory/contradiction-resolver.js.map +0 -1
- package/dist/core/memory/edit-workflow.d.ts.map +0 -1
- package/dist/core/memory/edit-workflow.js.map +0 -1
- package/dist/core/memory/entity-extractor.d.ts.map +0 -1
- package/dist/core/memory/entity-extractor.js.map +0 -1
- package/dist/core/memory/entity-resolver.d.ts.map +0 -1
- package/dist/core/memory/entity-resolver.js.map +0 -1
- package/dist/core/memory/fact-extractor.d.ts.map +0 -1
- package/dist/core/memory/fact-extractor.js.map +0 -1
- package/dist/core/memory/feedback-tracker.d.ts.map +0 -1
- package/dist/core/memory/feedback-tracker.js.map +0 -1
- package/dist/core/memory/hybrid-retrieval.d.ts.map +0 -1
- package/dist/core/memory/hybrid-retrieval.js.map +0 -1
- package/dist/core/memory/hybrid-scorer.d.ts.map +0 -1
- package/dist/core/memory/hybrid-scorer.js.map +0 -1
- package/dist/core/memory/hybrid-search.d.ts.map +0 -1
- package/dist/core/memory/hybrid-search.js.map +0 -1
- package/dist/core/memory/importance.d.ts.map +0 -1
- package/dist/core/memory/importance.js.map +0 -1
- package/dist/core/memory/index.d.ts.map +0 -1
- package/dist/core/memory/index.js.map +0 -1
- package/dist/core/memory/memories.d.ts.map +0 -1
- package/dist/core/memory/memories.js.map +0 -1
- package/dist/core/memory/memory-manager.d.ts.map +0 -1
- package/dist/core/memory/memory-manager.js.map +0 -1
- package/dist/core/memory/progressive-disclosure.d.ts.map +0 -1
- package/dist/core/memory/progressive-disclosure.js.map +0 -1
- package/dist/core/memory/query-processor.d.ts.map +0 -1
- package/dist/core/memory/query-processor.js.map +0 -1
- package/dist/core/memory/query-rewriter.d.ts.map +0 -1
- package/dist/core/memory/query-rewriter.js.map +0 -1
- package/dist/core/memory/response-analyzer.d.ts.map +0 -1
- package/dist/core/memory/response-analyzer.js.map +0 -1
- package/dist/core/memory/serialization.d.ts.map +0 -1
- package/dist/core/memory/serialization.js.map +0 -1
- package/dist/core/memory/stats.d.ts.map +0 -1
- package/dist/core/memory/stats.js.map +0 -1
- package/dist/core/memory/telemetry.d.ts.map +0 -1
- package/dist/core/memory/telemetry.js.map +0 -1
- package/dist/core/memory/temporal-facts.d.ts.map +0 -1
- package/dist/core/memory/temporal-facts.js.map +0 -1
- package/dist/core/memory/temporal-parser.d.ts.map +0 -1
- package/dist/core/memory/temporal-parser.js.map +0 -1
- package/dist/core/memory/trigger-detector.d.ts.map +0 -1
- package/dist/core/memory/trigger-detector.js.map +0 -1
- package/dist/core/memory/write-gate.d.ts.map +0 -1
- package/dist/core/memory/write-gate.js.map +0 -1
- package/dist/core/namespaces/index.d.ts.map +0 -1
- package/dist/core/namespaces/index.js.map +0 -1
- package/dist/core/namespaces/uri-parser.d.ts.map +0 -1
- package/dist/core/namespaces/uri-parser.js.map +0 -1
- package/dist/core/observations.d.ts.map +0 -1
- package/dist/core/observations.js.map +0 -1
- package/dist/core/privacy.d.ts.map +0 -1
- package/dist/core/privacy.js.map +0 -1
- package/dist/core/projects.d.ts.map +0 -1
- package/dist/core/projects.js.map +0 -1
- package/dist/core/redis.d.ts.map +0 -1
- package/dist/core/redis.js.map +0 -1
- package/dist/core/requirements.d.ts.map +0 -1
- package/dist/core/requirements.js.map +0 -1
- package/dist/core/scheduler/cron-scheduler.d.ts.map +0 -1
- package/dist/core/scheduler/cron-scheduler.js.map +0 -1
- package/dist/core/scheduler/heartbeat.d.ts.map +0 -1
- package/dist/core/scheduler/heartbeat.js.map +0 -1
- package/dist/core/scheduler/index.d.ts.map +0 -1
- package/dist/core/scheduler/index.js.map +0 -1
- package/dist/core/scheduler/job-runner.d.ts.map +0 -1
- package/dist/core/scheduler/job-runner.js.map +0 -1
- package/dist/core/search/conversations.d.ts.map +0 -1
- package/dist/core/search/conversations.js.map +0 -1
- package/dist/core/search/entities.d.ts.map +0 -1
- package/dist/core/search/entities.js.map +0 -1
- package/dist/core/search/folder-context.d.ts.map +0 -1
- package/dist/core/search/folder-context.js.map +0 -1
- package/dist/core/search/index.d.ts.map +0 -1
- package/dist/core/search/index.js.map +0 -1
- package/dist/core/search/qmd-search.d.ts.map +0 -1
- package/dist/core/search/qmd-search.js.map +0 -1
- package/dist/core/secret-detector.d.ts.map +0 -1
- package/dist/core/secret-detector.js.map +0 -1
- package/dist/core/session/auto-load.d.ts.map +0 -1
- package/dist/core/session/auto-load.js.map +0 -1
- package/dist/core/session/index.d.ts.map +0 -1
- package/dist/core/session/index.js.map +0 -1
- package/dist/core/session/types.d.ts.map +0 -1
- package/dist/core/session/types.js.map +0 -1
- package/dist/core/session-hooks/self-iteration-job.d.ts.map +0 -1
- package/dist/core/session-hooks/self-iteration-job.js.map +0 -1
- package/dist/core/session-hooks/session-hooks.d.ts.map +0 -1
- package/dist/core/session-hooks/session-hooks.js.map +0 -1
- package/dist/core/snapshots/cleanup.d.ts.map +0 -1
- package/dist/core/snapshots/cleanup.js.map +0 -1
- package/dist/core/snapshots/comparison.d.ts.map +0 -1
- package/dist/core/snapshots/comparison.js.map +0 -1
- package/dist/core/snapshots/creation.d.ts.map +0 -1
- package/dist/core/snapshots/creation.js.map +0 -1
- package/dist/core/snapshots/retrieval.d.ts.map +0 -1
- package/dist/core/snapshots/retrieval.js.map +0 -1
- package/dist/core/snapshots/stats.d.ts.map +0 -1
- package/dist/core/snapshots/stats.js.map +0 -1
- package/dist/core/snapshots.d.ts.map +0 -1
- package/dist/core/snapshots.js.map +0 -1
- package/dist/core/summarization/cleanup.d.ts.map +0 -1
- package/dist/core/summarization/cleanup.js.map +0 -1
- package/dist/core/summarization/queries.d.ts.map +0 -1
- package/dist/core/summarization/queries.js.map +0 -1
- package/dist/core/summarization/stats.d.ts.map +0 -1
- package/dist/core/summarization/stats.js.map +0 -1
- package/dist/core/summarization/strategies.d.ts.map +0 -1
- package/dist/core/summarization/strategies.js.map +0 -1
- package/dist/core/summarization.d.ts.map +0 -1
- package/dist/core/summarization.js.map +0 -1
- package/dist/core/sync/qmd-sync.d.ts.map +0 -1
- package/dist/core/sync/qmd-sync.js.map +0 -1
- package/dist/core/temporal-facts.d.ts.map +0 -1
- package/dist/core/temporal-facts.js.map +0 -1
- package/dist/core/tracing/collector.d.ts.map +0 -1
- package/dist/core/tracing/collector.js.map +0 -1
- package/dist/core/tracing/visualizer.d.ts.map +0 -1
- package/dist/core/tracing/visualizer.js.map +0 -1
- package/dist/core/utils/cleanup-operations.d.ts.map +0 -1
- package/dist/core/utils/cleanup-operations.js.map +0 -1
- package/dist/core/utils/content-extraction.d.ts.map +0 -1
- package/dist/core/utils/content-extraction.js.map +0 -1
- package/dist/core/utils/filter-builder.d.ts.map +0 -1
- package/dist/core/utils/filter-builder.js.map +0 -1
- package/dist/core/utils/history-traversal.d.ts.map +0 -1
- package/dist/core/utils/history-traversal.js.map +0 -1
- package/dist/core/utils/memory-operations.d.ts.map +0 -1
- package/dist/core/utils/memory-operations.js.map +0 -1
- package/dist/core/utils/query-operations.d.ts.map +0 -1
- package/dist/core/utils/query-operations.js.map +0 -1
- package/dist/core/utils/summarization-helpers.d.ts.map +0 -1
- package/dist/core/utils/summarization-helpers.js.map +0 -1
- package/dist/core/utils/temporal-queries.d.ts.map +0 -1
- package/dist/core/utils/temporal-queries.js.map +0 -1
- package/dist/core/utils/version-management.d.ts.map +0 -1
- package/dist/core/utils/version-management.js.map +0 -1
- package/dist/core/utils.d.ts.map +0 -1
- package/dist/core/utils.js.map +0 -1
- package/dist/core/worker.d.ts.map +0 -1
- package/dist/core/worker.js.map +0 -1
- package/dist/db/adapter.d.ts.map +0 -1
- package/dist/db/adapter.js.map +0 -1
- package/dist/db/bootstrap.d.ts.map +0 -1
- package/dist/db/bootstrap.js.map +0 -1
- package/dist/db/index.d.ts.map +0 -1
- package/dist/db/index.js.map +0 -1
- package/dist/db/schema.d.ts.map +0 -1
- package/dist/db/schema.js.map +0 -1
- package/dist/drizzle/schema-sqlite.d.ts.map +0 -1
- package/dist/drizzle/schema-sqlite.js.map +0 -1
- package/dist/drizzle/schema.d.ts.map +0 -1
- package/dist/drizzle/schema.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/packages/plugin-claude-code/dist/plugin-wrapper.d.ts.map +0 -1
- package/packages/plugin-claude-code/dist/plugin-wrapper.js.map +0 -1
- package/packages/plugin-openclaw/dist/index.d.ts.map +0 -1
- package/packages/plugin-openclaw/dist/index.js.map +0 -1
|
@@ -46,24 +46,24 @@ async function searchConversationsSqlite(input, limit) {
|
|
|
46
46
|
params.push(input.role);
|
|
47
47
|
}
|
|
48
48
|
params.push(limit);
|
|
49
|
-
const statement = sqlite.prepare(`
|
|
50
|
-
SELECT DISTINCT
|
|
51
|
-
c.id as id,
|
|
52
|
-
c.project_id as projectId,
|
|
53
|
-
c.session_id as sessionId,
|
|
54
|
-
c.title as title,
|
|
55
|
-
c.summary as summary,
|
|
56
|
-
c.message_count as messageCount,
|
|
57
|
-
c.token_count as tokenCount,
|
|
58
|
-
c.started_at as startedAt,
|
|
59
|
-
c.ended_at as endedAt,
|
|
60
|
-
c.metadata as metadata
|
|
61
|
-
FROM conversations c
|
|
62
|
-
JOIN messages m ON m.conversation_id = c.id
|
|
63
|
-
JOIN messages_fts ON messages_fts.rowid = m.rowid
|
|
64
|
-
WHERE ${where}
|
|
65
|
-
ORDER BY c.started_at DESC
|
|
66
|
-
LIMIT ?
|
|
49
|
+
const statement = sqlite.prepare(`
|
|
50
|
+
SELECT DISTINCT
|
|
51
|
+
c.id as id,
|
|
52
|
+
c.project_id as projectId,
|
|
53
|
+
c.session_id as sessionId,
|
|
54
|
+
c.title as title,
|
|
55
|
+
c.summary as summary,
|
|
56
|
+
c.message_count as messageCount,
|
|
57
|
+
c.token_count as tokenCount,
|
|
58
|
+
c.started_at as startedAt,
|
|
59
|
+
c.ended_at as endedAt,
|
|
60
|
+
c.metadata as metadata
|
|
61
|
+
FROM conversations c
|
|
62
|
+
JOIN messages m ON m.conversation_id = c.id
|
|
63
|
+
JOIN messages_fts ON messages_fts.rowid = m.rowid
|
|
64
|
+
WHERE ${where}
|
|
65
|
+
ORDER BY c.started_at DESC
|
|
66
|
+
LIMIT ?
|
|
67
67
|
`);
|
|
68
68
|
const rows = statement.all(...params);
|
|
69
69
|
return rows.map((row) => normalizeConversation(row));
|
|
@@ -77,21 +77,21 @@ async function searchConversationsPostgres(input, limit) {
|
|
|
77
77
|
whereParts.push(`m.role = $${values.length}`);
|
|
78
78
|
}
|
|
79
79
|
values.push(limit);
|
|
80
|
-
const rows = await db.$client.query(`SELECT DISTINCT ON (c.id)
|
|
81
|
-
c.id as "id",
|
|
82
|
-
c.project_id as "projectId",
|
|
83
|
-
c.session_id as "sessionId",
|
|
84
|
-
c.title as "title",
|
|
85
|
-
c.summary as "summary",
|
|
86
|
-
c.message_count as "messageCount",
|
|
87
|
-
c.token_count as "tokenCount",
|
|
88
|
-
c.started_at as "startedAt",
|
|
89
|
-
c.ended_at as "endedAt",
|
|
90
|
-
c.metadata as "metadata"
|
|
91
|
-
FROM conversations c
|
|
92
|
-
JOIN messages m ON m.conversation_id = c.id
|
|
93
|
-
WHERE ${whereParts.join(' AND ')}
|
|
94
|
-
ORDER BY c.id, c.started_at DESC
|
|
80
|
+
const rows = await db.$client.query(`SELECT DISTINCT ON (c.id)
|
|
81
|
+
c.id as "id",
|
|
82
|
+
c.project_id as "projectId",
|
|
83
|
+
c.session_id as "sessionId",
|
|
84
|
+
c.title as "title",
|
|
85
|
+
c.summary as "summary",
|
|
86
|
+
c.message_count as "messageCount",
|
|
87
|
+
c.token_count as "tokenCount",
|
|
88
|
+
c.started_at as "startedAt",
|
|
89
|
+
c.ended_at as "endedAt",
|
|
90
|
+
c.metadata as "metadata"
|
|
91
|
+
FROM conversations c
|
|
92
|
+
JOIN messages m ON m.conversation_id = c.id
|
|
93
|
+
WHERE ${whereParts.join(' AND ')}
|
|
94
|
+
ORDER BY c.id, c.started_at DESC
|
|
95
95
|
LIMIT $${values.length}`, values);
|
|
96
96
|
return rows.rows.map((row) => normalizeConversation(row));
|
|
97
97
|
}
|
|
@@ -20,31 +20,31 @@ const DEFAULT_CONFIG = {
|
|
|
20
20
|
*/
|
|
21
21
|
function buildFactExtractionPrompt(messages) {
|
|
22
22
|
const messagesText = messages.map(m => `[${m.role}]: ${m.content}`).join('\n\n');
|
|
23
|
-
return `Extract key facts, decisions, and user preferences from this conversation.
|
|
24
|
-
|
|
25
|
-
Format your response as JSON:
|
|
26
|
-
{
|
|
27
|
-
"extractedFacts": [
|
|
28
|
-
{
|
|
29
|
-
"content": "specific fact text",
|
|
30
|
-
"type": "fact|decision|preference|observation",
|
|
31
|
-
"confidence": 0-100
|
|
32
|
-
}
|
|
33
|
-
]
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
Only extract truly meaningful information that should be remembered:
|
|
37
|
-
- Facts that are useful for future work or decisions
|
|
38
|
-
- User preferences and choices
|
|
39
|
-
- Important decisions made
|
|
40
|
-
- Patterns or behaviors observed
|
|
41
|
-
|
|
42
|
-
Do NOT extract:
|
|
43
|
-
- Temporary conversational details
|
|
44
|
-
- Greetings or pleasantries
|
|
45
|
-
- Unless they indicate something significant
|
|
46
|
-
|
|
47
|
-
Conversation messages:
|
|
23
|
+
return `Extract key facts, decisions, and user preferences from this conversation.
|
|
24
|
+
|
|
25
|
+
Format your response as JSON:
|
|
26
|
+
{
|
|
27
|
+
"extractedFacts": [
|
|
28
|
+
{
|
|
29
|
+
"content": "specific fact text",
|
|
30
|
+
"type": "fact|decision|preference|observation",
|
|
31
|
+
"confidence": 0-100
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
Only extract truly meaningful information that should be remembered:
|
|
37
|
+
- Facts that are useful for future work or decisions
|
|
38
|
+
- User preferences and choices
|
|
39
|
+
- Important decisions made
|
|
40
|
+
- Patterns or behaviors observed
|
|
41
|
+
|
|
42
|
+
Do NOT extract:
|
|
43
|
+
- Temporary conversational details
|
|
44
|
+
- Greetings or pleasantries
|
|
45
|
+
- Unless they indicate something significant
|
|
46
|
+
|
|
47
|
+
Conversation messages:
|
|
48
48
|
${messagesText}`;
|
|
49
49
|
}
|
|
50
50
|
/**
|
|
@@ -52,14 +52,14 @@ ${messagesText}`;
|
|
|
52
52
|
*/
|
|
53
53
|
function buildSummaryPrompt(messages) {
|
|
54
54
|
const messagesText = messages.map(m => `[${m.role}]: ${m.content}`).join('\n\n');
|
|
55
|
-
return `Generate a concise summary of this conversation (2-3 sentences, under 300 characters).
|
|
56
|
-
|
|
57
|
-
Focus on:
|
|
58
|
-
- What was accomplished
|
|
59
|
-
- Key decisions made
|
|
60
|
-
- Important context established
|
|
61
|
-
|
|
62
|
-
Conversation messages:
|
|
55
|
+
return `Generate a concise summary of this conversation (2-3 sentences, under 300 characters).
|
|
56
|
+
|
|
57
|
+
Focus on:
|
|
58
|
+
- What was accomplished
|
|
59
|
+
- Key decisions made
|
|
60
|
+
- Important context established
|
|
61
|
+
|
|
62
|
+
Conversation messages:
|
|
63
63
|
${messagesText}`;
|
|
64
64
|
}
|
|
65
65
|
/**
|
|
@@ -86,14 +86,15 @@ async function getConversationsForIteration(maxMessages) {
|
|
|
86
86
|
if (!db)
|
|
87
87
|
return [];
|
|
88
88
|
const schema = await getSchema();
|
|
89
|
+
const sqliteDb = db;
|
|
89
90
|
// Get conversations that:
|
|
90
91
|
// 1. Have ended (endedAt is not null)
|
|
91
92
|
// 2. Haven't been processed yet (metadata.selfIterationProcessed is not set)
|
|
92
93
|
// 3. Have enough messages (messageCount >= minMessageCount)
|
|
93
|
-
const conversations = await
|
|
94
|
+
const conversations = await sqliteDb.select()
|
|
94
95
|
.from(schema.conversations)
|
|
95
|
-
.where(sql `${schema.conversations.endedAt} IS NOT NULL
|
|
96
|
-
AND (${schema.conversations.metadata}->>'selfIterationProcessed') IS NULL
|
|
96
|
+
.where(sql `${schema.conversations.endedAt} IS NOT NULL
|
|
97
|
+
AND (${schema.conversations.metadata}->>'selfIterationProcessed') IS NULL
|
|
97
98
|
AND ${schema.conversations.messageCount} >= ?`)
|
|
98
99
|
.limit(10);
|
|
99
100
|
return conversations;
|
|
@@ -106,7 +107,8 @@ async function getConversationMessages(conversationId) {
|
|
|
106
107
|
if (!db)
|
|
107
108
|
return [];
|
|
108
109
|
const schema = await getSchema();
|
|
109
|
-
const
|
|
110
|
+
const sqliteDb = db;
|
|
111
|
+
const messages = await sqliteDb.select()
|
|
110
112
|
.from(schema.messages)
|
|
111
113
|
.where(eq(schema.messages.conversationId, conversationId))
|
|
112
114
|
.orderBy(schema.messages.createdAt);
|
|
@@ -126,7 +128,8 @@ async function markConversationProcessed(conversationId) {
|
|
|
126
128
|
if (!db)
|
|
127
129
|
return;
|
|
128
130
|
const schema = await getSchema();
|
|
129
|
-
|
|
131
|
+
const sqliteDb = db;
|
|
132
|
+
await sqliteDb.update(schema.conversations)
|
|
130
133
|
.set({
|
|
131
134
|
metadata: sql `json_set(${schema.conversations.metadata}, 'selfIterationProcessed', true)`,
|
|
132
135
|
})
|
|
@@ -208,7 +211,8 @@ async function processConversation(conversation, config) {
|
|
|
208
211
|
// Update conversation with summary
|
|
209
212
|
const db = await getDb();
|
|
210
213
|
const schema = await getSchema();
|
|
211
|
-
|
|
214
|
+
const sqliteDb = db;
|
|
215
|
+
await sqliteDb.update(schema.conversations)
|
|
212
216
|
.set({ summary })
|
|
213
217
|
.where(eq(schema.conversations.id, conversation.id));
|
|
214
218
|
summariesCreated++;
|
|
@@ -18,8 +18,9 @@ export async function onSessionEnd(sessionId) {
|
|
|
18
18
|
return;
|
|
19
19
|
}
|
|
20
20
|
const schema = await getSchema();
|
|
21
|
+
const sqliteDb = db;
|
|
21
22
|
// Mark conversation as ended
|
|
22
|
-
await
|
|
23
|
+
await sqliteDb.update(schema.conversations)
|
|
23
24
|
.set({ endedAt: new Date() })
|
|
24
25
|
.where(eq(schema.conversations.sessionId, sessionId));
|
|
25
26
|
logger.info(`[SessionHooks] Session ${sessionId} marked as ended`);
|
|
@@ -32,7 +33,8 @@ export async function getActiveSessions(projectId) {
|
|
|
32
33
|
if (!db)
|
|
33
34
|
return [];
|
|
34
35
|
const schema = await getSchema();
|
|
35
|
-
const
|
|
36
|
+
const sqliteDb = db;
|
|
37
|
+
const sessions = await sqliteDb.select()
|
|
36
38
|
.from(schema.conversations)
|
|
37
39
|
.where(eq(schema.conversations.projectId, projectId))
|
|
38
40
|
.where(sql `${schema.conversations.endedAt} IS NULL`);
|
|
@@ -46,7 +48,8 @@ export async function endAllProjectSessions(projectId) {
|
|
|
46
48
|
if (!db)
|
|
47
49
|
return 0;
|
|
48
50
|
const schema = await getSchema();
|
|
49
|
-
const
|
|
51
|
+
const sqliteDb = db;
|
|
52
|
+
const result = await sqliteDb.update(schema.conversations)
|
|
50
53
|
.set({ endedAt: new Date() })
|
|
51
54
|
.where(eq(schema.conversations.projectId, projectId));
|
|
52
55
|
logger.info(`[SessionHooks] Ended ${result.rowCount} sessions for project ${projectId}`);
|
|
@@ -17,10 +17,11 @@ export async function startTrace(sessionId, query) {
|
|
|
17
17
|
return '';
|
|
18
18
|
}
|
|
19
19
|
const schema = await getSchema();
|
|
20
|
+
const sqliteDb = db;
|
|
20
21
|
const traceId = crypto.randomUUID();
|
|
21
22
|
const timestamp = new Date();
|
|
22
23
|
// Create trace record
|
|
23
|
-
await
|
|
24
|
+
await sqliteDb.insert(schema.searchTraces).values({
|
|
24
25
|
id: traceId,
|
|
25
26
|
sessionId,
|
|
26
27
|
query,
|
|
@@ -39,8 +40,9 @@ export async function addQueryRewriteStage(traceId, stage) {
|
|
|
39
40
|
if (!db)
|
|
40
41
|
return;
|
|
41
42
|
const schema = await getSchema();
|
|
43
|
+
const sqliteDb = db;
|
|
42
44
|
const data = JSON.stringify(stage);
|
|
43
|
-
await
|
|
45
|
+
await sqliteDb.update(schema.searchTraces)
|
|
44
46
|
.set({
|
|
45
47
|
queryRewrite: sql `CAST(? AS jsonb)`,
|
|
46
48
|
})
|
|
@@ -56,8 +58,9 @@ export async function addCandidateRetrievalStage(traceId, stage) {
|
|
|
56
58
|
if (!db)
|
|
57
59
|
return;
|
|
58
60
|
const schema = await getSchema();
|
|
61
|
+
const sqliteDb = db;
|
|
59
62
|
const data = JSON.stringify(stage);
|
|
60
|
-
await
|
|
63
|
+
await sqliteDb.update(schema.searchTraces)
|
|
61
64
|
.set({ candidateRetrieval: data })
|
|
62
65
|
.where(eq(schema.searchTraces.id, traceId));
|
|
63
66
|
logger.debug(`[Tracing] Added candidateRetrieval stage to trace ${traceId}`);
|
|
@@ -70,8 +73,9 @@ export async function addEntityFilteringStage(traceId, stage) {
|
|
|
70
73
|
if (!db)
|
|
71
74
|
return;
|
|
72
75
|
const schema = await getSchema();
|
|
76
|
+
const sqliteDb = db;
|
|
73
77
|
const data = JSON.stringify(stage);
|
|
74
|
-
await
|
|
78
|
+
await sqliteDb.update(schema.searchTraces)
|
|
75
79
|
.set({ entityFiltering: data })
|
|
76
80
|
.where(eq(schema.searchTraces.id, traceId));
|
|
77
81
|
logger.debug(`[Tracing] Added entityFiltering stage to trace ${traceId}`);
|
|
@@ -84,8 +88,9 @@ export async function addHybridScoringStage(traceId, stage) {
|
|
|
84
88
|
if (!db)
|
|
85
89
|
return;
|
|
86
90
|
const schema = await getSchema();
|
|
91
|
+
const sqliteDb = db;
|
|
87
92
|
const data = JSON.stringify(stage);
|
|
88
|
-
await
|
|
93
|
+
await sqliteDb.update(schema.searchTraces)
|
|
89
94
|
.set({ hybridScoring: data })
|
|
90
95
|
.where(eq(schema.searchTraces.id, traceId));
|
|
91
96
|
logger.debug(`[Tracing] Added hybridScoring stage to trace ${traceId}`);
|
|
@@ -98,8 +103,9 @@ export async function addRerankingStage(traceId, stage) {
|
|
|
98
103
|
if (!db)
|
|
99
104
|
return;
|
|
100
105
|
const schema = await getSchema();
|
|
106
|
+
const sqliteDb = db;
|
|
101
107
|
const data = JSON.stringify(stage);
|
|
102
|
-
await
|
|
108
|
+
await sqliteDb.update(schema.searchTraces)
|
|
103
109
|
.set({ reranking: data })
|
|
104
110
|
.where(eq(schema.searchTraces.id, traceId));
|
|
105
111
|
logger.debug(`[Tracing] Added reranking stage to trace ${traceId}`);
|
|
@@ -112,8 +118,9 @@ export async function completeTrace(traceId, results) {
|
|
|
112
118
|
if (!db)
|
|
113
119
|
return;
|
|
114
120
|
const schema = await getSchema();
|
|
121
|
+
const sqliteDb = db;
|
|
115
122
|
// Get trace
|
|
116
|
-
const rows = await
|
|
123
|
+
const rows = await sqliteDb.select()
|
|
117
124
|
.from(schema.searchTraces)
|
|
118
125
|
.where(eq(schema.searchTraces.id, traceId))
|
|
119
126
|
.limit(1);
|
|
@@ -127,7 +134,7 @@ export async function completeTrace(traceId, results) {
|
|
|
127
134
|
const totalDurationMs = endTime - startTime;
|
|
128
135
|
const resultCount = results.length;
|
|
129
136
|
const topResults = results.slice(0, 10);
|
|
130
|
-
await
|
|
137
|
+
await sqliteDb.update(schema.searchTraces)
|
|
131
138
|
.set({
|
|
132
139
|
resultCount,
|
|
133
140
|
topResults: JSON.stringify(topResults),
|
|
@@ -144,6 +151,7 @@ export async function getTraces(options = {}) {
|
|
|
144
151
|
if (!db)
|
|
145
152
|
return [];
|
|
146
153
|
const schema = await getSchema();
|
|
154
|
+
const sqliteDb = db;
|
|
147
155
|
let conditions = [];
|
|
148
156
|
if (options.sessionId) {
|
|
149
157
|
conditions.push(eq(schema.searchTraces.sessionId, options.sessionId));
|
|
@@ -151,7 +159,7 @@ export async function getTraces(options = {}) {
|
|
|
151
159
|
if (options.session && options.session.length > 0) {
|
|
152
160
|
conditions.push(eq(schema.searchTraces.sessionId, options.session));
|
|
153
161
|
}
|
|
154
|
-
const query =
|
|
162
|
+
const query = sqliteDb.select()
|
|
155
163
|
.from(schema.searchTraces)
|
|
156
164
|
.where(conditions.length > 0 ? eq(schema.searchTraces.sessionId, options.sessionId || options.session || '') : undefined)
|
|
157
165
|
.orderBy(desc(schema.searchTraces.timestamp));
|
|
@@ -183,7 +191,8 @@ export async function getTraceById(traceId) {
|
|
|
183
191
|
if (!db)
|
|
184
192
|
return null;
|
|
185
193
|
const schema = await getSchema();
|
|
186
|
-
const
|
|
194
|
+
const sqliteDb = db;
|
|
195
|
+
const rows = await sqliteDb.select()
|
|
187
196
|
.from(schema.searchTraces)
|
|
188
197
|
.where(eq(schema.searchTraces.id, traceId))
|
|
189
198
|
.limit(1);
|
|
@@ -214,7 +223,8 @@ export async function getRecentTraces(limit = 10) {
|
|
|
214
223
|
if (!db)
|
|
215
224
|
return [];
|
|
216
225
|
const schema = await getSchema();
|
|
217
|
-
const
|
|
226
|
+
const sqliteDb = db;
|
|
227
|
+
const traces = await sqliteDb.select()
|
|
218
228
|
.from(schema.searchTraces)
|
|
219
229
|
.orderBy(desc(schema.searchTraces.timestamp))
|
|
220
230
|
.limit(limit);
|
|
@@ -242,8 +252,9 @@ export async function getSessionTraces(sessionId) {
|
|
|
242
252
|
if (!db)
|
|
243
253
|
return [];
|
|
244
254
|
const schema = await getSchema();
|
|
255
|
+
const sqliteDb = db;
|
|
245
256
|
// Get all traces for this session
|
|
246
|
-
const traces = await
|
|
257
|
+
const traces = await sqliteDb.select()
|
|
247
258
|
.from(schema.searchTraces)
|
|
248
259
|
.where(eq(schema.searchTraces.sessionId, sessionId))
|
|
249
260
|
.orderBy(desc(schema.searchTraces.timestamp));
|
|
@@ -318,7 +329,8 @@ export async function getTraceStats() {
|
|
|
318
329
|
};
|
|
319
330
|
}
|
|
320
331
|
const schema = await getSchema();
|
|
321
|
-
const
|
|
332
|
+
const sqliteDb = db;
|
|
333
|
+
const traces = await sqliteDb.select()
|
|
322
334
|
.from(schema.searchTraces)
|
|
323
335
|
.limit(100);
|
|
324
336
|
const totalTraces = traces.length;
|
package/dist/db/adapter.d.ts
CHANGED
|
@@ -1,2 +1,7 @@
|
|
|
1
|
-
export declare function createDb(): Promise<
|
|
1
|
+
export declare function createDb(): Promise<(import("drizzle-orm/node-postgres").NodePgDatabase<typeof import("../drizzle/schema.js")> & {
|
|
2
|
+
$client: import("pg").Pool;
|
|
3
|
+
}) | (import("drizzle-orm/better-sqlite3").BetterSQLite3Database<typeof import("../drizzle/schema-sqlite.js")> & {
|
|
4
|
+
$client: import("better-sqlite3").Database;
|
|
5
|
+
}) | import("drizzle-orm/sql-js").SQLJsDatabase<typeof import("../drizzle/schema-sqlite.js")>>;
|
|
6
|
+
export default createDb;
|
|
2
7
|
//# sourceMappingURL=adapter.d.ts.map
|
package/dist/db/adapter.js
CHANGED
|
@@ -1,8 +1,19 @@
|
|
|
1
1
|
import { config, getDataDir } from '../config.js';
|
|
2
2
|
import { ensurePostgresSchema, ensureSqliteSchema } from './bootstrap.js';
|
|
3
3
|
import { logger } from '../core/logger.js';
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
async function createBunSqliteDb(dbPath) {
|
|
5
|
+
// @ts-ignore - bun:sqlite module not found in types but works at runtime
|
|
6
|
+
const { drizzle } = await import('drizzle-orm/bun-sqlite');
|
|
7
|
+
const schemaModule = await import('../drizzle/schema-sqlite.js');
|
|
8
|
+
// Bun SQLite doesn't need file path for in-memory, but we'll use file path for persistence
|
|
9
|
+
// @ts-ignore - bun:sqlite module not found in types but works at runtime
|
|
10
|
+
const sqlite = new (await import('bun:sqlite')).default(dbPath);
|
|
11
|
+
// Enable foreign keys
|
|
12
|
+
sqlite.exec('PRAGMA foreign_keys = ON');
|
|
13
|
+
await ensureSqliteSchema(sqlite);
|
|
14
|
+
logger.info('SQLite initialized with bun:sqlite');
|
|
15
|
+
return drizzle(sqlite, { schema: schemaModule });
|
|
16
|
+
}
|
|
6
17
|
export async function createDb() {
|
|
7
18
|
if (config.isTeamMode) {
|
|
8
19
|
return createPostgresDb();
|
|
@@ -24,145 +35,130 @@ async function createPostgresDb() {
|
|
|
24
35
|
}
|
|
25
36
|
async function createSqliteDb() {
|
|
26
37
|
const dbPath = `${getDataDir()}/squish.db`;
|
|
27
|
-
// Try Bun's built-in SQLite
|
|
28
|
-
|
|
38
|
+
// Try bun:sqlite first (Bun's built-in SQLite)
|
|
39
|
+
try {
|
|
40
|
+
return await createBunSqliteDb(dbPath);
|
|
41
|
+
}
|
|
42
|
+
catch (bunSqliteError) {
|
|
43
|
+
logger.warn('bun:sqlite failed, trying better-sqlite3', {
|
|
44
|
+
error: bunSqliteError.message
|
|
45
|
+
});
|
|
46
|
+
// Try better-sqlite3 second (best performance)
|
|
29
47
|
try {
|
|
30
|
-
return await
|
|
48
|
+
return await createBetterSqliteDb(dbPath);
|
|
31
49
|
}
|
|
32
|
-
catch (
|
|
33
|
-
logger.warn('
|
|
50
|
+
catch (betterSqliteError) {
|
|
51
|
+
logger.warn('better-sqlite3 failed, trying sql.js fallback', {
|
|
52
|
+
error: betterSqliteError.message
|
|
53
|
+
});
|
|
54
|
+
// Fallback to sql.js (pure JavaScript, no native module)
|
|
55
|
+
try {
|
|
56
|
+
return await createSqlJsDb(dbPath);
|
|
57
|
+
}
|
|
58
|
+
catch (sqlJsError) {
|
|
59
|
+
// All failed - this is critical, Squish cannot work without DB
|
|
60
|
+
logger.error('CRITICAL: SQLite database initialization failed', {
|
|
61
|
+
bunSqliteError: bunSqliteError.message,
|
|
62
|
+
betterSqliteError: betterSqliteError.message,
|
|
63
|
+
sqlJsError: sqlJsError.message
|
|
64
|
+
});
|
|
65
|
+
throw new Error(`Squish requires SQLite to function. Database initialization failed.\n` +
|
|
66
|
+
`Primary error (bun:sqlite): ${bunSqliteError.message}\n` +
|
|
67
|
+
`Secondary error (better-sqlite3): ${betterSqliteError.message}\n` +
|
|
68
|
+
`Fallback error (sql.js): ${sqlJsError.message}\n\n` +
|
|
69
|
+
`Solutions:\n` +
|
|
70
|
+
`1. Install build tools: npm install -g windows-build-tools (Windows)\n` +
|
|
71
|
+
`2. Or use PostgreSQL instead by setting DATABASE_URL environment variable`);
|
|
72
|
+
}
|
|
34
73
|
}
|
|
35
74
|
}
|
|
36
|
-
// Fallback to better-sqlite3 for Node.js
|
|
37
|
-
try {
|
|
38
|
-
return await createBetterSqliteDb(dbPath);
|
|
39
|
-
}
|
|
40
|
-
catch (error) {
|
|
41
|
-
logger.error('SQLite initialization failed', error);
|
|
42
|
-
throw new Error(`SQLite database unavailable: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
async function createBunSqliteDb(dbPath) {
|
|
46
|
-
// Dynamic import for Bun runtime - wrapped to avoid TS issues
|
|
47
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
48
|
-
// @ts-ignore - bun:sqlite is only available in Bun runtime
|
|
49
|
-
const { Database } = await import('bun:sqlite');
|
|
50
|
-
const { drizzle } = await import('drizzle-orm/bun-sqlite');
|
|
51
|
-
const schemaModule = await import('../drizzle/schema-sqlite.js');
|
|
52
|
-
const sqlite = new Database(dbPath);
|
|
53
|
-
// Enable foreign keys
|
|
54
|
-
sqlite.run('PRAGMA foreign_keys = ON');
|
|
55
|
-
// Run full schema bootstrap from bootstrap.ts (includes ALL tables)
|
|
56
|
-
await ensureSqliteSchema(sqlite);
|
|
57
|
-
return drizzle(sqlite, { schema: schemaModule });
|
|
58
75
|
}
|
|
59
76
|
async function createBetterSqliteDb(dbPath) {
|
|
60
77
|
const DatabaseModule = await import('better-sqlite3');
|
|
61
78
|
const Database = DatabaseModule.default;
|
|
62
79
|
const { drizzle } = await import('drizzle-orm/better-sqlite3');
|
|
63
80
|
const schemaModule = await import('../drizzle/schema-sqlite.js');
|
|
64
|
-
|
|
65
|
-
try {
|
|
66
|
-
sqlite = new Database(dbPath);
|
|
67
|
-
}
|
|
68
|
-
catch (error) {
|
|
69
|
-
// Check if it's a Win32 native module error
|
|
70
|
-
if (error.message?.includes('not a valid Win32 application')) {
|
|
71
|
-
logger.error('better-sqlite3 native module not compiled for this platform');
|
|
72
|
-
logger.error('Solution: Run "npm run web:bun" to use Bun instead, or rebuild with "npm rebuild better-sqlite3"');
|
|
73
|
-
throw new Error('SQLite native module unavailable. Use "npm run web:bun" or rebuild better-sqlite3 for your platform.');
|
|
74
|
-
}
|
|
75
|
-
throw error;
|
|
76
|
-
}
|
|
81
|
+
const sqlite = new Database(dbPath);
|
|
77
82
|
// Enable foreign keys
|
|
78
83
|
sqlite.pragma('foreign_keys = ON');
|
|
79
84
|
await ensureSqliteSchema(sqlite);
|
|
85
|
+
logger.info('SQLite initialized with better-sqlite3');
|
|
80
86
|
return drizzle(sqlite, { schema: schemaModule });
|
|
81
87
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
embedding_json TEXT,
|
|
95
|
-
source TEXT DEFAULT 'mcp',
|
|
96
|
-
tier TEXT DEFAULT 'warm',
|
|
97
|
-
status TEXT DEFAULT 'active',
|
|
98
|
-
importance_score REAL DEFAULT 50,
|
|
99
|
-
relevance_score REAL,
|
|
100
|
-
coactivation_score INTEGER DEFAULT 0,
|
|
101
|
-
access_count INTEGER DEFAULT 0,
|
|
102
|
-
retrieval_count INTEGER DEFAULT 0,
|
|
103
|
-
echo_count INTEGER DEFAULT 0,
|
|
104
|
-
fizzle_count INTEGER DEFAULT 0,
|
|
105
|
-
is_pinned INTEGER DEFAULT 0,
|
|
106
|
-
is_protected INTEGER DEFAULT 0,
|
|
107
|
-
is_immutable INTEGER DEFAULT 0,
|
|
108
|
-
is_mergeable INTEGER DEFAULT 0,
|
|
109
|
-
is_merged INTEGER DEFAULT 0,
|
|
110
|
-
merged_into TEXT,
|
|
111
|
-
merged_at TEXT,
|
|
112
|
-
superseded_by TEXT,
|
|
113
|
-
superseded_at TEXT,
|
|
114
|
-
valid_from TEXT,
|
|
115
|
-
valid_to TEXT,
|
|
116
|
-
expired_at TEXT,
|
|
117
|
-
last_accessed_at TEXT,
|
|
118
|
-
last_retrieved_at TEXT,
|
|
119
|
-
last_echoed_at TEXT,
|
|
120
|
-
last_importance_recalc TEXT,
|
|
121
|
-
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
|
122
|
-
updated_at TEXT DEFAULT CURRENT_TIMESTAMP
|
|
123
|
-
)
|
|
124
|
-
`;
|
|
125
|
-
const createProjectsTable = `
|
|
126
|
-
CREATE TABLE IF NOT EXISTS projects (
|
|
127
|
-
id TEXT PRIMARY KEY,
|
|
128
|
-
name TEXT NOT NULL,
|
|
129
|
-
path TEXT UNIQUE,
|
|
130
|
-
description TEXT,
|
|
131
|
-
metadata TEXT,
|
|
132
|
-
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
|
133
|
-
updated_at TEXT DEFAULT CURRENT_TIMESTAMP
|
|
134
|
-
)
|
|
135
|
-
`;
|
|
136
|
-
const createAssociationsTable = `
|
|
137
|
-
CREATE TABLE IF NOT EXISTS memory_associations (
|
|
138
|
-
id TEXT PRIMARY KEY,
|
|
139
|
-
from_memory_id TEXT NOT NULL,
|
|
140
|
-
to_memory_id TEXT NOT NULL,
|
|
141
|
-
association_type TEXT NOT NULL,
|
|
142
|
-
weight REAL DEFAULT 1,
|
|
143
|
-
coactivation_count INTEGER DEFAULT 1,
|
|
144
|
-
last_coactivated_at TEXT,
|
|
145
|
-
created_at TEXT DEFAULT CURRENT_TIMESTAMP,
|
|
146
|
-
UNIQUE(from_memory_id, to_memory_id)
|
|
147
|
-
)
|
|
148
|
-
`;
|
|
149
|
-
sqlite.run(createMemoriesTable);
|
|
150
|
-
sqlite.run(createProjectsTable);
|
|
151
|
-
sqlite.run(createAssociationsTable);
|
|
152
|
-
// FTS is optional - don't fail if it doesn't work
|
|
153
|
-
try {
|
|
154
|
-
sqlite.run(`
|
|
155
|
-
CREATE VIRTUAL TABLE IF NOT EXISTS memories_fts USING fts5(
|
|
156
|
-
content,
|
|
157
|
-
summary,
|
|
158
|
-
content='memories',
|
|
159
|
-
content_rowid='rowid'
|
|
160
|
-
)
|
|
161
|
-
`);
|
|
162
|
-
}
|
|
163
|
-
catch (e) {
|
|
164
|
-
logger.debug('FTS5 table creation skipped', { error: e?.message || String(e) });
|
|
88
|
+
async function createSqlJsDb(dbPath) {
|
|
89
|
+
// @ts-ignore - sql.js has no types but works fine
|
|
90
|
+
const initSqlJs = await import('sql.js');
|
|
91
|
+
const { drizzle } = await import('drizzle-orm/sql-js');
|
|
92
|
+
const schemaModule = await import('../drizzle/schema-sqlite.js');
|
|
93
|
+
const fs = await import('fs');
|
|
94
|
+
const path = await import('path');
|
|
95
|
+
const SQL = await initSqlJs.default();
|
|
96
|
+
let data;
|
|
97
|
+
// Try to load existing database
|
|
98
|
+
if (fs.existsSync(dbPath)) {
|
|
99
|
+
data = fs.readFileSync(dbPath);
|
|
165
100
|
}
|
|
166
|
-
|
|
101
|
+
const sqlite = new SQL.Database(data);
|
|
102
|
+
// Enable foreign keys
|
|
103
|
+
sqlite.exec('PRAGMA foreign_keys = ON');
|
|
104
|
+
// Schema bootstrap
|
|
105
|
+
await ensureSqliteSchema(sqlite);
|
|
106
|
+
// Persist database on changes (sql.js is in-memory by default)
|
|
107
|
+
const originalExec = sqlite.exec.bind(sqlite);
|
|
108
|
+
sqlite.exec = function (...args) {
|
|
109
|
+
const result = originalExec(...args);
|
|
110
|
+
// Save after each exec
|
|
111
|
+
const data = sqlite.export();
|
|
112
|
+
fs.writeFileSync(dbPath, Buffer.from(data));
|
|
113
|
+
return result;
|
|
114
|
+
};
|
|
115
|
+
// Add prepare method for compatibility with drizzle-orm/sql-js
|
|
116
|
+
sqlite.prepare = (query) => {
|
|
117
|
+
const stmt = sqlite.prepare(query);
|
|
118
|
+
const preparedStatement = {};
|
|
119
|
+
preparedStatement.bind = (bindParams) => {
|
|
120
|
+
bindParams.forEach((param, index) => {
|
|
121
|
+
stmt.bind(param, index + 1);
|
|
122
|
+
});
|
|
123
|
+
return preparedStatement;
|
|
124
|
+
};
|
|
125
|
+
preparedStatement.step = () => {
|
|
126
|
+
return stmt.step();
|
|
127
|
+
};
|
|
128
|
+
preparedStatement.getAsObject = () => {
|
|
129
|
+
return stmt.getAsObject();
|
|
130
|
+
};
|
|
131
|
+
preparedStatement.free = () => {
|
|
132
|
+
stmt.free();
|
|
133
|
+
};
|
|
134
|
+
preparedStatement.run = () => {
|
|
135
|
+
const result = stmt.step() ? { changes: sqlite.changes() } : { changes: 0 };
|
|
136
|
+
stmt.reset();
|
|
137
|
+
return result;
|
|
138
|
+
};
|
|
139
|
+
preparedStatement.get = (bindParams = []) => {
|
|
140
|
+
if (bindParams.length > 0) {
|
|
141
|
+
preparedStatement.bind(bindParams);
|
|
142
|
+
}
|
|
143
|
+
const row = stmt.step() ? stmt.getAsObject() : undefined;
|
|
144
|
+
stmt.reset();
|
|
145
|
+
return row;
|
|
146
|
+
};
|
|
147
|
+
preparedStatement.all = (bindParams = []) => {
|
|
148
|
+
if (bindParams.length > 0) {
|
|
149
|
+
preparedStatement.bind(bindParams);
|
|
150
|
+
}
|
|
151
|
+
const rows = [];
|
|
152
|
+
while (stmt.step()) {
|
|
153
|
+
rows.push(stmt.getAsObject());
|
|
154
|
+
}
|
|
155
|
+
stmt.reset();
|
|
156
|
+
return rows;
|
|
157
|
+
};
|
|
158
|
+
return preparedStatement;
|
|
159
|
+
};
|
|
160
|
+
logger.info('SQLite initialized with sql.js (pure JavaScript fallback)');
|
|
161
|
+
return drizzle(sqlite, { schema: schemaModule });
|
|
167
162
|
}
|
|
163
|
+
export default createDb;
|
|
168
164
|
//# sourceMappingURL=adapter.js.map
|