squish-memory 1.0.1 → 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 +4 -0
- package/README.md +35 -17
- package/config/plugin-manifest.json +1 -1
- package/dist/api/web/web.js +27 -1
- package/dist/commands/mcp-server.js +1 -1
- package/dist/core/mcp/server.js +27 -1
- package/dist/core/mcp/types.d.ts +4 -4
- package/dist/core/memory/memories.js +9 -6
- package/dist/core/scheduler/cron-scheduler.js +66 -13
- package/dist/db/adapter.js +88 -20
- package/dist/db/bootstrap.js +145 -71
- package/dist/index.d.ts +1 -1
- package/dist/index.js +195 -49
- package/generated/mcp/manifest.json +23 -23
- package/package.json +30 -18
- 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
package/dist/db/bootstrap.js
CHANGED
|
@@ -330,6 +330,44 @@ CREATE TABLE IF NOT EXISTS memory_hash_cache (
|
|
|
330
330
|
|
|
331
331
|
CREATE INDEX IF NOT EXISTS memory_hash_cache_project_id_idx ON memory_hash_cache(project_id);
|
|
332
332
|
CREATE INDEX IF NOT EXISTS memory_hash_cache_simhash_idx ON memory_hash_cache(simhash);
|
|
333
|
+
|
|
334
|
+
-- Namespaces table (v1.0.x) - Hierarchical organization
|
|
335
|
+
CREATE TABLE IF NOT EXISTS namespaces (
|
|
336
|
+
id TEXT PRIMARY KEY,
|
|
337
|
+
project_id TEXT REFERENCES projects(id) ON DELETE CASCADE,
|
|
338
|
+
name TEXT NOT NULL,
|
|
339
|
+
path TEXT,
|
|
340
|
+
description TEXT,
|
|
341
|
+
parent_id TEXT REFERENCES namespaces(id) ON DELETE SET NULL,
|
|
342
|
+
created_at INTEGER DEFAULT (strftime('%s','now')) NOT NULL,
|
|
343
|
+
updated_at INTEGER DEFAULT (strftime('%s','now')) NOT NULL
|
|
344
|
+
);
|
|
345
|
+
CREATE INDEX IF NOT EXISTS namespaces_project_idx ON namespaces(project_id);
|
|
346
|
+
CREATE INDEX IF NOT EXISTS namespaces_parent_idx ON namespaces(parent_id);
|
|
347
|
+
|
|
348
|
+
-- Maintenance jobs table (v1.0.x) - Cron scheduler
|
|
349
|
+
CREATE TABLE IF NOT EXISTS maintenance_jobs (
|
|
350
|
+
id TEXT PRIMARY KEY,
|
|
351
|
+
job_name TEXT NOT NULL UNIQUE,
|
|
352
|
+
job_type TEXT NOT NULL,
|
|
353
|
+
cron_expression TEXT,
|
|
354
|
+
enabled INTEGER DEFAULT 1 NOT NULL,
|
|
355
|
+
last_run_at INTEGER,
|
|
356
|
+
last_run_duration INTEGER,
|
|
357
|
+
last_run_status TEXT,
|
|
358
|
+
last_run_error TEXT,
|
|
359
|
+
total_runs INTEGER DEFAULT 0,
|
|
360
|
+
success_count INTEGER DEFAULT 0,
|
|
361
|
+
failure_count INTEGER DEFAULT 0,
|
|
362
|
+
job_config TEXT,
|
|
363
|
+
next_run_at INTEGER,
|
|
364
|
+
created_at INTEGER DEFAULT (strftime('%s','now')) NOT NULL,
|
|
365
|
+
updated_at INTEGER DEFAULT (strftime('%s','now')) NOT NULL
|
|
366
|
+
);
|
|
367
|
+
CREATE INDEX IF NOT EXISTS maintenance_jobs_name_idx ON maintenance_jobs(job_name);
|
|
368
|
+
CREATE INDEX IF NOT EXISTS maintenance_jobs_next_run_idx ON maintenance_jobs(next_run_at);
|
|
369
|
+
CREATE INDEX IF NOT EXISTS maintenance_jobs_type_idx ON maintenance_jobs(job_type);
|
|
370
|
+
CREATE INDEX IF NOT EXISTS maintenance_jobs_enabled_idx ON maintenance_jobs(enabled);
|
|
333
371
|
`;
|
|
334
372
|
const postgresStatements = [
|
|
335
373
|
`CREATE EXTENSION IF NOT EXISTS pgcrypto;`,
|
|
@@ -565,97 +603,71 @@ async function runSqliteMigrations(sqlite) {
|
|
|
565
603
|
// No migrations needed
|
|
566
604
|
return;
|
|
567
605
|
}
|
|
568
|
-
// Migrations for memories table
|
|
606
|
+
// Migrations for memories table (deduplicated, ordered by version)
|
|
569
607
|
const memoriesMigrations = [
|
|
608
|
+
// Base columns (v0.1.x - v0.5.x)
|
|
570
609
|
{ col: 'embedding', sql: 'ALTER TABLE memories ADD COLUMN embedding BLOB' },
|
|
571
|
-
{ col: 'is_private', sql: 'ALTER TABLE memories ADD COLUMN is_private INTEGER DEFAULT 0' },
|
|
572
|
-
{ col: 'has_secrets', sql: 'ALTER TABLE memories ADD COLUMN has_secrets INTEGER DEFAULT 0' },
|
|
573
610
|
{ col: 'relevance_score', sql: 'ALTER TABLE memories ADD COLUMN relevance_score INTEGER DEFAULT 50' },
|
|
611
|
+
// Merge tracking (v0.6.x)
|
|
574
612
|
{ col: 'is_merged', sql: 'ALTER TABLE memories ADD COLUMN is_merged INTEGER DEFAULT 0' },
|
|
575
613
|
{ col: 'merged_into_id', sql: 'ALTER TABLE memories ADD COLUMN merged_into_id TEXT' },
|
|
576
614
|
{ col: 'is_mergeable', sql: 'ALTER TABLE memories ADD COLUMN is_mergeable INTEGER DEFAULT 1' },
|
|
577
615
|
{ col: 'is_canonical', sql: 'ALTER TABLE memories ADD COLUMN is_canonical INTEGER DEFAULT 0' },
|
|
578
|
-
|
|
616
|
+
{ col: 'merged_at', sql: 'ALTER TABLE memories ADD COLUMN merged_at INTEGER' },
|
|
617
|
+
{ col: 'merge_source_ids', sql: 'ALTER TABLE memories ADD COLUMN merge_source_ids TEXT' },
|
|
618
|
+
{ col: 'merge_version', sql: 'ALTER TABLE memories ADD COLUMN merge_version INTEGER DEFAULT 1' },
|
|
619
|
+
// Importance scoring (v0.8.0)
|
|
579
620
|
{ col: 'importance_score', sql: 'ALTER TABLE memories ADD COLUMN importance_score INTEGER DEFAULT 50' },
|
|
580
621
|
{ col: 'importance_decay_rate', sql: 'ALTER TABLE memories ADD COLUMN importance_decay_rate INTEGER DEFAULT 30' },
|
|
581
622
|
{ col: 'last_importance_recalc', sql: 'ALTER TABLE memories ADD COLUMN last_importance_recalc INTEGER' },
|
|
582
|
-
// v0.8.0
|
|
623
|
+
// Consolidation (v0.8.0)
|
|
583
624
|
{ col: 'consolidated_into', sql: 'ALTER TABLE memories ADD COLUMN consolidated_into TEXT' },
|
|
584
625
|
{ col: 'consolidated_at', sql: 'ALTER TABLE memories ADD COLUMN consolidated_at INTEGER' },
|
|
585
626
|
{ col: 'is_consolidated', sql: 'ALTER TABLE memories ADD COLUMN is_consolidated INTEGER DEFAULT 0' },
|
|
586
|
-
|
|
627
|
+
// Memory lifecycle (v0.8.0)
|
|
587
628
|
{ col: 'sector', sql: 'ALTER TABLE memories ADD COLUMN sector TEXT DEFAULT "episodic"' },
|
|
588
629
|
{ col: 'tier', sql: 'ALTER TABLE memories ADD COLUMN tier TEXT DEFAULT "hot"' },
|
|
589
630
|
{ col: 'context_status', sql: 'ALTER TABLE memories ADD COLUMN context_status TEXT DEFAULT "out-of-context"' },
|
|
590
631
|
{ col: 'decay_rate', sql: 'ALTER TABLE memories ADD COLUMN decay_rate INTEGER DEFAULT 30' },
|
|
591
632
|
{ col: 'coactivation_score', sql: 'ALTER TABLE memories ADD COLUMN coactivation_score INTEGER DEFAULT 0' },
|
|
592
633
|
{ col: 'last_decay_at', sql: 'ALTER TABLE memories ADD COLUMN last_decay_at INTEGER DEFAULT (strftime(\'%s\',\'now\'))' },
|
|
634
|
+
// Agent tracking (v0.8.0)
|
|
593
635
|
{ col: 'agent_id', sql: 'ALTER TABLE memories ADD COLUMN agent_id TEXT' },
|
|
594
636
|
{ col: 'agent_role', sql: 'ALTER TABLE memories ADD COLUMN agent_role TEXT' },
|
|
595
637
|
{ col: 'retrieval_priority', sql: 'ALTER TABLE memories ADD COLUMN retrieval_priority INTEGER DEFAULT 50' },
|
|
596
|
-
// v0.9.0
|
|
638
|
+
// Data governance (v0.9.0)
|
|
597
639
|
{ col: 'recorded_at', sql: 'ALTER TABLE memories ADD COLUMN recorded_at INTEGER DEFAULT (strftime(\'%s\',\'now\'))' },
|
|
598
640
|
{ col: 'confidence', sql: 'ALTER TABLE memories ADD COLUMN confidence INTEGER DEFAULT 100' },
|
|
599
|
-
{ col: 'is_private', sql: 'ALTER TABLE memories ADD COLUMN is_private INTEGER DEFAULT 0' },
|
|
600
|
-
{ col: 'has_secrets', sql: 'ALTER TABLE memories ADD COLUMN has_secrets INTEGER DEFAULT 0' },
|
|
601
641
|
{ col: 'valid_from', sql: 'ALTER TABLE memories ADD COLUMN valid_from INTEGER' },
|
|
602
642
|
{ col: 'valid_to', sql: 'ALTER TABLE memories ADD COLUMN valid_to INTEGER' },
|
|
603
643
|
{ col: 'superseded_by', sql: 'ALTER TABLE memories ADD COLUMN superseded_by TEXT' },
|
|
604
644
|
{ col: 'version', sql: 'ALTER TABLE memories ADD COLUMN version INTEGER DEFAULT 1' },
|
|
605
|
-
{ col: 'merge_source_ids', sql: 'ALTER TABLE memories ADD COLUMN merge_source_ids TEXT' },
|
|
606
|
-
{ col: 'merge_version', sql: 'ALTER TABLE memories ADD COLUMN merge_version INTEGER DEFAULT 1' },
|
|
607
|
-
{ col: 'user_id', sql: 'ALTER TABLE memories ADD COLUMN user_id TEXT' },
|
|
608
|
-
{ col: 'confidence', sql: 'ALTER TABLE memories ADD COLUMN confidence INTEGER DEFAULT 100' },
|
|
609
645
|
{ col: 'is_active', sql: 'ALTER TABLE memories ADD COLUMN is_active INTEGER DEFAULT 1' },
|
|
610
646
|
{ col: 'expires_at', sql: 'ALTER TABLE memories ADD COLUMN expires_at INTEGER' },
|
|
611
|
-
|
|
612
|
-
{ col: '
|
|
613
|
-
{ col: '
|
|
614
|
-
{ col: 'agent_id', sql: 'ALTER TABLE memories ADD COLUMN agent_id TEXT' },
|
|
615
|
-
{ col: 'agent_role', sql: 'ALTER TABLE memories ADD COLUMN agent_role TEXT' },
|
|
616
|
-
{ col: 'retrieval_priority', sql: 'ALTER TABLE memories ADD COLUMN retrieval_priority INTEGER DEFAULT 50' },
|
|
617
|
-
// v0.8.0: Consolidation
|
|
618
|
-
{ col: 'consolidated_into', sql: 'ALTER TABLE memories ADD COLUMN consolidated_into TEXT' },
|
|
619
|
-
{ col: 'consolidated_at', sql: 'ALTER TABLE memories ADD COLUMN consolidated_at INTEGER' },
|
|
620
|
-
{ col: 'is_consolidated', sql: 'ALTER TABLE memories ADD COLUMN is_consolidated INTEGER DEFAULT 0' },
|
|
621
|
-
{ col: 'merged_at', sql: 'ALTER TABLE memories ADD COLUMN merged_at INTEGER' },
|
|
622
|
-
{ col: 'sector', sql: 'ALTER TABLE memories ADD COLUMN sector TEXT DEFAULT "episodic"' },
|
|
623
|
-
{ col: 'tier', sql: 'ALTER TABLE memories ADD COLUMN tier TEXT DEFAULT "hot"' },
|
|
624
|
-
{ col: 'context_status', sql: 'ALTER TABLE memories ADD COLUMN context_status TEXT DEFAULT "out-of-context"' },
|
|
625
|
-
{ col: 'decay_rate', sql: 'ALTER TABLE memories ADD COLUMN decay_rate INTEGER DEFAULT 30' },
|
|
626
|
-
{ col: 'coactivation_score', sql: 'ALTER TABLE memories ADD COLUMN coactivation_score INTEGER DEFAULT 0' },
|
|
627
|
-
{ col: 'last_decay_at', sql: 'ALTER TABLE memories ADD COLUMN last_decay_at INTEGER DEFAULT (strftime(\'%s\',\'now\'))' },
|
|
628
|
-
{ col: 'agent_id', sql: 'ALTER TABLE memories ADD COLUMN agent_id TEXT' },
|
|
629
|
-
{ col: 'agent_role', sql: 'ALTER TABLE memories ADD COLUMN agent_role TEXT' },
|
|
647
|
+
// Privacy & access (v0.9.0)
|
|
648
|
+
{ col: 'is_private', sql: 'ALTER TABLE memories ADD COLUMN is_private INTEGER DEFAULT 0' },
|
|
649
|
+
{ col: 'has_secrets', sql: 'ALTER TABLE memories ADD COLUMN has_secrets INTEGER DEFAULT 0' },
|
|
630
650
|
{ col: 'visibility_scope', sql: 'ALTER TABLE memories ADD COLUMN visibility_scope TEXT DEFAULT "private"' },
|
|
631
651
|
{ col: 'is_protected', sql: 'ALTER TABLE memories ADD COLUMN is_protected INTEGER DEFAULT 0' },
|
|
632
652
|
{ col: 'is_pinned', sql: 'ALTER TABLE memories ADD COLUMN is_pinned INTEGER DEFAULT 0' },
|
|
633
653
|
{ col: 'is_immutable', sql: 'ALTER TABLE memories ADD COLUMN is_immutable INTEGER DEFAULT 0' },
|
|
634
654
|
{ col: 'write_scope', sql: 'ALTER TABLE memories ADD COLUMN write_scope TEXT' },
|
|
635
655
|
{ col: 'read_scope', sql: 'ALTER TABLE memories ADD COLUMN read_scope TEXT' },
|
|
656
|
+
// Usage tracking (v0.9.0)
|
|
636
657
|
{ col: 'triggered_by', sql: 'ALTER TABLE memories ADD COLUMN triggered_by TEXT' },
|
|
637
658
|
{ col: 'capture_reason', sql: 'ALTER TABLE memories ADD COLUMN capture_reason TEXT' },
|
|
638
659
|
{ col: 'last_used_at', sql: 'ALTER TABLE memories ADD COLUMN last_used_at INTEGER' },
|
|
639
660
|
{ col: 'usage_count', sql: 'ALTER TABLE memories ADD COLUMN usage_count INTEGER DEFAULT 0' },
|
|
640
|
-
{ col: 'valid_from', sql: 'ALTER TABLE memories ADD COLUMN valid_from INTEGER' },
|
|
641
|
-
{ col: 'valid_to', sql: 'ALTER TABLE memories ADD COLUMN valid_to INTEGER' },
|
|
642
|
-
{ col: 'superseded_by', sql: 'ALTER TABLE memories ADD COLUMN superseded_by TEXT' },
|
|
643
|
-
{ col: 'version', sql: 'ALTER TABLE memories ADD COLUMN version INTEGER DEFAULT 1' },
|
|
644
|
-
{ col: 'merge_source_ids', sql: 'ALTER TABLE memories ADD COLUMN merge_source_ids TEXT' },
|
|
645
|
-
{ col: 'merge_version', sql: 'ALTER TABLE memories ADD COLUMN merge_version INTEGER DEFAULT 1' },
|
|
646
661
|
{ col: 'user_id', sql: 'ALTER TABLE memories ADD COLUMN user_id TEXT' },
|
|
647
|
-
|
|
648
|
-
{ col: '
|
|
649
|
-
{ col: '
|
|
650
|
-
{ col: '
|
|
651
|
-
|
|
652
|
-
{ col: '
|
|
653
|
-
{ col: '
|
|
654
|
-
|
|
655
|
-
{ col: '
|
|
656
|
-
{ col: 'importance_score', sql: 'ALTER TABLE memories ADD COLUMN importance_score INTEGER DEFAULT 50' },
|
|
657
|
-
{ col: 'importance_decay_rate', sql: 'ALTER TABLE memories ADD COLUMN importance_decay_rate INTEGER DEFAULT 30' },
|
|
658
|
-
{ col: 'last_importance_recalc', sql: 'ALTER TABLE memories ADD COLUMN last_importance_recalc INTEGER' },
|
|
662
|
+
// Layer tracking (v0.9.x)
|
|
663
|
+
{ col: 'has_l0_abstract', sql: 'ALTER TABLE memories ADD COLUMN has_l0_abstract INTEGER DEFAULT 0' },
|
|
664
|
+
{ col: 'has_l1_overview', sql: 'ALTER TABLE memories ADD COLUMN has_l1_overview INTEGER DEFAULT 0' },
|
|
665
|
+
{ col: 'last_layer_update', sql: 'ALTER TABLE memories ADD COLUMN last_layer_update INTEGER' },
|
|
666
|
+
// Namespace support (v1.0.x)
|
|
667
|
+
{ col: 'namespace_id', sql: 'ALTER TABLE memories ADD COLUMN namespace_id TEXT REFERENCES namespaces(id) ON DELETE SET NULL' },
|
|
668
|
+
{ col: 'namespace_path', sql: 'ALTER TABLE memories ADD COLUMN namespace_path TEXT' },
|
|
669
|
+
// Token tracking (v1.0.x)
|
|
670
|
+
{ col: 'tokens_estimate', sql: 'ALTER TABLE memories ADD COLUMN tokens_estimate INTEGER DEFAULT 0' },
|
|
659
671
|
];
|
|
660
672
|
// Get existing columns for memories table
|
|
661
673
|
const tableInfo = sqlite.prepare("PRAGMA table_info(memories)").all();
|
|
@@ -676,28 +688,90 @@ async function runSqliteMigrations(sqlite) {
|
|
|
676
688
|
throw new Error(`Migration failed for column ${migration.col}: ${msg}`);
|
|
677
689
|
}
|
|
678
690
|
}
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
// v0.9.2: Add tokens_estimate to core_memory
|
|
694
|
+
const coreMemoryTableCheck = sqlite.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='core_memory'").get();
|
|
695
|
+
if (coreMemoryTableCheck) {
|
|
696
|
+
const coreMemoryInfo = sqlite.prepare("PRAGMA table_info(core_memory)").all();
|
|
697
|
+
const existingCoreMemoryColumns = new Set(coreMemoryInfo.map(col => col.name));
|
|
698
|
+
const coreMemoryMigrations = [
|
|
699
|
+
{ col: 'tokens_estimate', sql: 'ALTER TABLE core_memory ADD COLUMN tokens_estimate INTEGER DEFAULT 0 NOT NULL' },
|
|
700
|
+
];
|
|
701
|
+
for (const migration of coreMemoryMigrations) {
|
|
702
|
+
if (!existingCoreMemoryColumns.has(migration.col)) {
|
|
703
|
+
try {
|
|
704
|
+
sqlite.exec(migration.sql);
|
|
705
|
+
logger.info(`Migration: Added column ${migration.col} to core_memory table`);
|
|
706
|
+
}
|
|
707
|
+
catch (error) {
|
|
708
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
709
|
+
if (msg.includes('duplicate column name')) {
|
|
710
|
+
logger.debug(`Migration skipped for ${migration.col}: column already exists`);
|
|
711
|
+
}
|
|
712
|
+
else {
|
|
713
|
+
throw new Error(`Migration failed for column ${migration.col}: ${msg}`);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
// Migrations for maintenance_jobs table (v1.0.x)
|
|
720
|
+
const maintenanceJobsTableCheck = sqlite.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='maintenance_jobs'").get();
|
|
721
|
+
if (maintenanceJobsTableCheck) {
|
|
722
|
+
const maintenanceJobsInfo = sqlite.prepare("PRAGMA table_info(maintenance_jobs)").all();
|
|
723
|
+
const existingMaintenanceJobsColumns = new Set(maintenanceJobsInfo.map(col => col.name));
|
|
724
|
+
// Check if table has wrong schema (camelCase columns from bug in earlier version)
|
|
725
|
+
const hasCamelCaseColumns = existingMaintenanceJobsColumns.has('jobName') ||
|
|
726
|
+
existingMaintenanceJobsColumns.has('jobType') ||
|
|
727
|
+
existingMaintenanceJobsColumns.has('cronExpression');
|
|
728
|
+
if (hasCamelCaseColumns) {
|
|
729
|
+
// Table has incorrect camelCase schema - need to recreate it
|
|
730
|
+
logger.warn('Maintenance jobs table has incorrect schema (camelCase columns). Recreating...');
|
|
731
|
+
try {
|
|
732
|
+
// Drop the malformed table
|
|
733
|
+
sqlite.exec('DROP TABLE IF EXISTS maintenance_jobs');
|
|
734
|
+
// Recreate with correct schema - it will be created by the schema SQL
|
|
735
|
+
logger.info('Dropped malformed maintenance_jobs table. It will be recreated with correct schema.');
|
|
736
|
+
}
|
|
737
|
+
catch (error) {
|
|
738
|
+
logger.error('Failed to recreate maintenance_jobs table:', error);
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
else {
|
|
742
|
+
// Normal migrations for correct schema
|
|
743
|
+
const maintenanceJobsMigrations = [
|
|
744
|
+
{ col: 'schedule', sql: 'ALTER TABLE maintenance_jobs DROP COLUMN schedule' },
|
|
745
|
+
{ col: 'cron_expression', sql: 'ALTER TABLE maintenance_jobs ADD COLUMN cron_expression TEXT' },
|
|
746
|
+
{ col: 'last_run_at', sql: 'ALTER TABLE maintenance_jobs ADD COLUMN last_run_at INTEGER' },
|
|
747
|
+
{ col: 'last_run_duration', sql: 'ALTER TABLE maintenance_jobs ADD COLUMN last_run_duration INTEGER' },
|
|
748
|
+
{ col: 'last_run_status', sql: 'ALTER TABLE maintenance_jobs ADD COLUMN last_run_status TEXT' },
|
|
749
|
+
{ col: 'last_run_error', sql: 'ALTER TABLE maintenance_jobs ADD COLUMN last_run_error TEXT' },
|
|
750
|
+
{ col: 'total_runs', sql: 'ALTER TABLE maintenance_jobs ADD COLUMN total_runs INTEGER DEFAULT 0' },
|
|
751
|
+
{ col: 'success_count', sql: 'ALTER TABLE maintenance_jobs ADD COLUMN success_count INTEGER DEFAULT 0' },
|
|
752
|
+
{ col: 'failure_count', sql: 'ALTER TABLE maintenance_jobs ADD COLUMN failure_count INTEGER DEFAULT 0' },
|
|
753
|
+
{ col: 'job_config', sql: 'ALTER TABLE maintenance_jobs ADD COLUMN job_config TEXT' },
|
|
754
|
+
{ col: 'next_run_at', sql: 'ALTER TABLE maintenance_jobs ADD COLUMN next_run_at INTEGER' },
|
|
755
|
+
{ col: 'run_count', sql: 'ALTER TABLE maintenance_jobs DROP COLUMN run_count' },
|
|
756
|
+
];
|
|
757
|
+
for (const migration of maintenanceJobsMigrations) {
|
|
758
|
+
// For DROP migrations, only run if column EXISTS
|
|
759
|
+
// For ADD migrations, only run if column does NOT exist
|
|
760
|
+
const shouldRun = migration.sql.startsWith('ALTER TABLE maintenance_jobs DROP COLUMN')
|
|
761
|
+
? existingMaintenanceJobsColumns.has(migration.col)
|
|
762
|
+
: !existingMaintenanceJobsColumns.has(migration.col);
|
|
763
|
+
if (shouldRun) {
|
|
764
|
+
try {
|
|
765
|
+
sqlite.exec(migration.sql);
|
|
766
|
+
logger.info(`Migration: ${migration.col} on maintenance_jobs table`);
|
|
767
|
+
}
|
|
768
|
+
catch (error) {
|
|
769
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
770
|
+
if (msg.includes('duplicate column name') || msg.includes('no such column')) {
|
|
771
|
+
logger.debug(`Migration skipped for ${migration.col}: ${msg.includes('duplicate column name') ? 'column already exists' : 'column does not exist'}`);
|
|
692
772
|
}
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
if (msg.includes('duplicate column name')) {
|
|
696
|
-
logger.debug(`Migration skipped for ${migration.col}: column already exists`);
|
|
697
|
-
}
|
|
698
|
-
else {
|
|
699
|
-
throw new Error(`Migration failed for column ${migration.col}: ${msg}`);
|
|
700
|
-
}
|
|
773
|
+
else {
|
|
774
|
+
throw new Error(`Migration failed for column ${migration.col}: ${msg}`);
|
|
701
775
|
}
|
|
702
776
|
}
|
|
703
777
|
}
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* Squish v1.0.
|
|
3
|
+
* Squish v1.0.2 - Universal Memory Plugin System
|
|
4
4
|
*
|
|
5
5
|
* Modes:
|
|
6
6
|
* - CLI Mode: For any MCP client bash execution (e.g., `squish remember "text"`)
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import 'dotenv/config';
|
|
19
19
|
import fs from 'node:fs';
|
|
20
|
+
import { existsSync } from 'node:fs';
|
|
20
21
|
import os from 'node:os';
|
|
21
22
|
import path from 'node:path';
|
|
22
23
|
import { fileURLToPath } from 'node:url';
|
|
@@ -48,11 +49,12 @@ import { searchWithQMD, isQMDAvailable } from './core/search/qmd-search.js';
|
|
|
48
49
|
import { initializeCoreMemory, getCoreMemory, editCoreMemorySection, appendCoreMemorySection, getCoreMemoryStats, } from './core/core-memory.js';
|
|
49
50
|
import { loadMemoryToContext, evictMemoryFromContext, viewLoadedMemories, getContextStatus, } from './core/context-paging.js';
|
|
50
51
|
import { ensureDataDirectory } from './db/bootstrap.js';
|
|
52
|
+
import { getDataDir } from './config.js';
|
|
51
53
|
import { performAutoLoad, shouldAutoLoad, getAutoLoadConfig } from './core/session/auto-load.js';
|
|
52
54
|
import { initializeScheduler, registerJobHandler } from './core/scheduler/cron-scheduler.js';
|
|
53
55
|
import { startHeartbeatChecking, heartbeat } from './core/scheduler/heartbeat.js';
|
|
54
56
|
import { runNightlyJob, runWeeklyJob } from './core/scheduler/job-runner.js';
|
|
55
|
-
const VERSION = '1.0.
|
|
57
|
+
const VERSION = '1.0.2';
|
|
56
58
|
// Load plugin manifest for self-verification
|
|
57
59
|
function loadPluginManifest() {
|
|
58
60
|
try {
|
|
@@ -89,21 +91,197 @@ function verifyManifest(manifest) {
|
|
|
89
91
|
return { ok: errors.length === 0, errors };
|
|
90
92
|
}
|
|
91
93
|
// ============================================================================
|
|
92
|
-
//
|
|
94
|
+
// HELPER FUNCTIONS
|
|
93
95
|
// ============================================================================
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
96
|
+
function showHelp() {
|
|
97
|
+
console.log(`
|
|
98
|
+
Squish Memory v${VERSION} - Universal Memory Plugin System
|
|
99
|
+
|
|
100
|
+
Usage:
|
|
101
|
+
squish Start interactive wizard
|
|
102
|
+
squish run mcp Start MCP server
|
|
103
|
+
squish run web Start Web UI only
|
|
104
|
+
squish <command> [options] Run CLI commands for agents
|
|
105
|
+
|
|
106
|
+
CLI Commands (for agents):
|
|
107
|
+
squish remember <content> Store a memory
|
|
108
|
+
squish search <query> Search memories
|
|
109
|
+
squish health Check system health
|
|
110
|
+
squish stats View statistics
|
|
111
|
+
squish core_memory Manage core memory
|
|
112
|
+
|
|
113
|
+
Examples:
|
|
114
|
+
squish run mcp # Start MCP server (for Claude Code)
|
|
115
|
+
squish run web # Start Web UI only
|
|
116
|
+
squish remember "Hello" # Store memory via CLI
|
|
117
|
+
squish search "query" # Search memories via CLI
|
|
118
|
+
|
|
119
|
+
For more info: https://github.com/michielhdoteth/squish
|
|
120
|
+
`);
|
|
121
|
+
}
|
|
122
|
+
async function runInteractiveInstaller() {
|
|
123
|
+
const { select } = await import('@clack/prompts');
|
|
124
|
+
const { isCancel } = await import('@clack/prompts');
|
|
125
|
+
const { log } = await import('@clack/prompts');
|
|
126
|
+
const { intro, outro } = await import('@clack/prompts');
|
|
127
|
+
intro(`Squish Memory v${VERSION}`);
|
|
128
|
+
const options = [
|
|
129
|
+
{ value: 'mcp', label: 'Start MCP Server (for AI Assistants: Claude Code, OpenCode, etc.)' },
|
|
130
|
+
{ value: 'web', label: 'Start Web UI Only' },
|
|
131
|
+
{ value: 'health', label: 'Health & Stats' },
|
|
132
|
+
{ value: 'help', label: 'Show Help' },
|
|
133
|
+
{ value: 'exit', label: 'Exit' }
|
|
134
|
+
];
|
|
135
|
+
const selected = await select({
|
|
136
|
+
message: 'What would you like to do?',
|
|
137
|
+
options: options,
|
|
138
|
+
});
|
|
139
|
+
if (isCancel(selected)) {
|
|
140
|
+
outro('Cancelled');
|
|
141
|
+
process.exit(0);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
switch (selected) {
|
|
145
|
+
case 'mcp':
|
|
146
|
+
log.step('Starting MCP server...');
|
|
147
|
+
await runMcpMode();
|
|
148
|
+
break;
|
|
149
|
+
case 'web':
|
|
150
|
+
log.step('Starting Web UI...');
|
|
151
|
+
await runWebOnly();
|
|
152
|
+
break;
|
|
153
|
+
case 'health':
|
|
154
|
+
log.step('Checking health...');
|
|
155
|
+
await runCliCommand('health');
|
|
156
|
+
await runCliCommand('stats');
|
|
157
|
+
break;
|
|
158
|
+
case 'help':
|
|
159
|
+
showHelp();
|
|
160
|
+
process.exit(0);
|
|
161
|
+
break;
|
|
162
|
+
case 'exit':
|
|
163
|
+
outro('Goodbye! 👋');
|
|
164
|
+
process.exit(0);
|
|
165
|
+
break;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
async function runCliCommand(command) {
|
|
169
|
+
// Run CLI command programmatically
|
|
170
|
+
const program = new Command();
|
|
171
|
+
program.hook('preAction', async () => {
|
|
172
|
+
await ensureDataDirectory();
|
|
173
|
+
});
|
|
174
|
+
if (command === 'health') {
|
|
175
|
+
const dbHealth = await checkDatabaseHealth();
|
|
176
|
+
const redisHealth = await checkRedisHealth();
|
|
177
|
+
const dataDir = process.env.SQUISH_DATA_DIR || path.join(os.homedir(), '.squish');
|
|
178
|
+
const dirExists = fs.existsSync(dataDir);
|
|
179
|
+
console.log(`\n Squish Memory v${VERSION}`);
|
|
180
|
+
console.log(` ====================`);
|
|
181
|
+
console.log(` Mode: ${config.isTeamMode ? 'team' : 'local'}`);
|
|
182
|
+
console.log(` Database: ${dbHealth ? 'ok' : 'error'}`);
|
|
183
|
+
console.log(` Cache: ${redisHealth ? 'ok' : 'unavailable'}`);
|
|
184
|
+
console.log(` Data Dir: ${dataDir}`);
|
|
185
|
+
console.log(` Status: ${dbHealth ? 'HEALTHY' : 'UNHEALTHY'}\n`);
|
|
186
|
+
}
|
|
187
|
+
else if (command === 'stats') {
|
|
188
|
+
const stats = await getMemoryStats(process.cwd());
|
|
189
|
+
console.log(JSON.stringify({ ok: true, ...stats }, null, 2));
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
async function spawnInstallerWizard() {
|
|
193
|
+
const distDir = path.dirname(fileURLToPath(import.meta.url));
|
|
194
|
+
const packageDir = path.dirname(distDir);
|
|
195
|
+
const installScript = path.join(packageDir, 'scripts', 'install-interactive.mjs');
|
|
196
|
+
if (!fs.existsSync(installScript)) {
|
|
197
|
+
console.error('Installer not found at:', installScript);
|
|
100
198
|
process.exit(1);
|
|
199
|
+
}
|
|
200
|
+
console.log('\nLaunching full installer wizard...\n');
|
|
201
|
+
const result = spawnSync('node', [`"${installScript}"`], {
|
|
202
|
+
stdio: 'inherit',
|
|
203
|
+
shell: true,
|
|
204
|
+
cwd: packageDir
|
|
101
205
|
});
|
|
206
|
+
process.exit(result.status || 0);
|
|
207
|
+
}
|
|
208
|
+
function isDatabaseInitialized() {
|
|
209
|
+
try {
|
|
210
|
+
const dataDir = getDataDir();
|
|
211
|
+
const dbPath = path.join(dataDir, 'squish.db');
|
|
212
|
+
return existsSync(dataDir) && existsSync(dbPath);
|
|
213
|
+
}
|
|
214
|
+
catch (error) {
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
async function runWebOnly() {
|
|
219
|
+
console.log(`[squish] Starting Web UI only...`);
|
|
220
|
+
await ensureDataDirectory();
|
|
221
|
+
startWebServer();
|
|
222
|
+
}
|
|
223
|
+
// ============================================================================
|
|
224
|
+
// CLI MODE DETECTION
|
|
225
|
+
// ============================================================================
|
|
226
|
+
const args = process.argv.slice(2);
|
|
227
|
+
const firstArg = args[0];
|
|
228
|
+
// Detect command type
|
|
229
|
+
const isNoArgs = args.length === 0;
|
|
230
|
+
const isRunCommand = firstArg === 'run';
|
|
231
|
+
const isHelpCommand = firstArg === '--help' || firstArg === '-h' || firstArg === 'help';
|
|
232
|
+
if (isNoArgs) {
|
|
233
|
+
// Check if database exists - if not, run installer automatically
|
|
234
|
+
if (!isDatabaseInitialized()) {
|
|
235
|
+
console.log(`[squish] No existing database found. Launching installer wizard...\n`);
|
|
236
|
+
await spawnInstallerWizard();
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
// === INTERACTIVE WIZARD (default when no args) ===
|
|
240
|
+
runInteractiveInstaller().catch((e) => {
|
|
241
|
+
console.error('Installer error:', e.message);
|
|
242
|
+
process.exit(1);
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
else if (isRunCommand) {
|
|
247
|
+
// === RUN SUBCOMMAND ===
|
|
248
|
+
const subcommand = args[1];
|
|
249
|
+
if (subcommand === 'mcp') {
|
|
250
|
+
runMcpMode().catch((e) => {
|
|
251
|
+
logger.error('Fatal error', e);
|
|
252
|
+
process.exit(1);
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
else if (subcommand === 'web') {
|
|
256
|
+
runWebOnly().catch((e) => {
|
|
257
|
+
logger.error('Web server error', e);
|
|
258
|
+
process.exit(1);
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
console.log(`
|
|
263
|
+
Usage: squish run <command>
|
|
264
|
+
|
|
265
|
+
Commands:
|
|
266
|
+
mcp Start MCP server
|
|
267
|
+
web Start Web UI only
|
|
268
|
+
|
|
269
|
+
Examples:
|
|
270
|
+
squish run mcp # Start MCP server with web UI
|
|
271
|
+
squish run web # Start Web UI only
|
|
272
|
+
`);
|
|
273
|
+
process.exit(subcommand ? 1 : 0);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
else if (isHelpCommand) {
|
|
277
|
+
// === SHOW HELP ===
|
|
278
|
+
showHelp();
|
|
279
|
+
process.exit(0);
|
|
102
280
|
}
|
|
103
281
|
else {
|
|
104
|
-
// ===
|
|
105
|
-
|
|
106
|
-
|
|
282
|
+
// === CLI MODE (for agents/OpenClaw) ===
|
|
283
|
+
runCliMode().catch((e) => {
|
|
284
|
+
console.error(JSON.stringify({ error: e.message }, null, 2));
|
|
107
285
|
process.exit(1);
|
|
108
286
|
});
|
|
109
287
|
}
|
|
@@ -365,7 +543,7 @@ async function runCliMode() {
|
|
|
365
543
|
// squish stats
|
|
366
544
|
program
|
|
367
545
|
.command('stats')
|
|
368
|
-
.description('
|
|
546
|
+
.description('View statistics')
|
|
369
547
|
.option('-p, --project <project>', 'Project path', process.cwd())
|
|
370
548
|
.action(async (options) => {
|
|
371
549
|
try {
|
|
@@ -377,44 +555,12 @@ async function runCliMode() {
|
|
|
377
555
|
process.exit(1);
|
|
378
556
|
}
|
|
379
557
|
});
|
|
380
|
-
// squish install
|
|
558
|
+
// squish install
|
|
381
559
|
program
|
|
382
560
|
.command('install')
|
|
383
|
-
.description('
|
|
384
|
-
.
|
|
385
|
-
|
|
386
|
-
.option('--skip-install', 'Skip global npm install step', false)
|
|
387
|
-
.action(async (options) => {
|
|
388
|
-
// Find the install script - it's in scripts/ relative to the package root
|
|
389
|
-
// When running from dist/index.js, scripts is at ../scripts/
|
|
390
|
-
const distDir = path.dirname(fileURLToPath(import.meta.url));
|
|
391
|
-
const packageDir = path.dirname(distDir);
|
|
392
|
-
const installScript = path.join(packageDir, 'scripts', 'install.mjs');
|
|
393
|
-
// Check if the script exists
|
|
394
|
-
if (!fs.existsSync(installScript)) {
|
|
395
|
-
console.log(JSON.stringify({
|
|
396
|
-
ok: false,
|
|
397
|
-
error: `Install script not found at: ${installScript}`,
|
|
398
|
-
hint: 'Please ensure squish-memory is installed correctly'
|
|
399
|
-
}, null, 2));
|
|
400
|
-
process.exit(1);
|
|
401
|
-
}
|
|
402
|
-
// Build command with quoted path for Windows compatibility
|
|
403
|
-
const args = [`"${installScript}"`];
|
|
404
|
-
if (options.dryRun)
|
|
405
|
-
args.push('--dry-run');
|
|
406
|
-
if (options.openclawDir)
|
|
407
|
-
args.push('--openclaw-dir', `"${options.openclawDir}"`);
|
|
408
|
-
if (options.skipInstall)
|
|
409
|
-
args.push('--skip-install');
|
|
410
|
-
const result = spawnSync('node', args, {
|
|
411
|
-
stdio: 'inherit',
|
|
412
|
-
shell: true,
|
|
413
|
-
cwd: packageDir
|
|
414
|
-
});
|
|
415
|
-
if (result.status !== 0) {
|
|
416
|
-
process.exit(result.status || 1);
|
|
417
|
-
}
|
|
561
|
+
.description('Run the interactive installer wizard')
|
|
562
|
+
.action(async () => {
|
|
563
|
+
await spawnInstallerWizard();
|
|
418
564
|
});
|
|
419
565
|
await program.parseAsync(process.argv);
|
|
420
566
|
}
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
{
|
|
2
|
-
"mode": "universal",
|
|
3
|
-
"generatedAt": "2026-03-
|
|
4
|
-
"source": "config/mcp.json",
|
|
5
|
-
"files": [
|
|
6
|
-
{
|
|
7
|
-
"file": "mcp-servers.json",
|
|
8
|
-
"sha256": "2c90cc52893f55bc92cc4f29c77bfeeb635c1c73fa46038d287548caeb35ca6a"
|
|
9
|
-
},
|
|
10
|
-
{
|
|
11
|
-
"file": "mcporter.json",
|
|
12
|
-
"sha256": "af42e1c03d44f66fcbe2a9b7694f1d3a126527147c66b760236e72348e1e4573"
|
|
13
|
-
},
|
|
14
|
-
{
|
|
15
|
-
"file": "openclaw-memory-qmd.json",
|
|
16
|
-
"sha256": "8a158ff45e98e0db7a7aff41dba7be76652b72aea82443773f9efc7fb056d615"
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
"file": "runtime.json",
|
|
20
|
-
"sha256": "4afbdec03de92c6a29fc24df32f01305c2e9cf69ed2d02866a01e361492d14b6"
|
|
21
|
-
}
|
|
22
|
-
]
|
|
23
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"mode": "universal",
|
|
3
|
+
"generatedAt": "2026-03-18T18:13:29.152Z",
|
|
4
|
+
"source": "config/mcp.json",
|
|
5
|
+
"files": [
|
|
6
|
+
{
|
|
7
|
+
"file": "mcp-servers.json",
|
|
8
|
+
"sha256": "2c90cc52893f55bc92cc4f29c77bfeeb635c1c73fa46038d287548caeb35ca6a"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"file": "mcporter.json",
|
|
12
|
+
"sha256": "af42e1c03d44f66fcbe2a9b7694f1d3a126527147c66b760236e72348e1e4573"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"file": "openclaw-memory-qmd.json",
|
|
16
|
+
"sha256": "8a158ff45e98e0db7a7aff41dba7be76652b72aea82443773f9efc7fb056d615"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"file": "runtime.json",
|
|
20
|
+
"sha256": "4afbdec03de92c6a29fc24df32f01305c2e9cf69ed2d02866a01e361492d14b6"
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
}
|