squish-memory 0.9.2 → 1.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/{.env.mcp → .env.mcp.example} +23 -0
- package/CHANGELOG.md +102 -0
- package/QUICK-START.md +10 -4
- package/README.md +73 -4
- package/config/plugin-manifest.json +152 -0
- package/config/plugin-manifest.schema.json +244 -0
- package/dist/algorithms/{merge/analytics → analytics}/token-estimator.d.ts +1 -1
- package/dist/algorithms/analytics/token-estimator.d.ts.map +1 -0
- package/dist/algorithms/{merge/analytics → analytics}/token-estimator.js +3 -3
- package/dist/algorithms/analytics/token-estimator.js.map +1 -0
- package/dist/algorithms/detection/hash-filters.d.ts.map +1 -0
- package/dist/algorithms/detection/hash-filters.js.map +1 -0
- package/dist/algorithms/{merge/detection → detection}/semantic-ranker.d.ts +1 -1
- package/dist/algorithms/detection/semantic-ranker.d.ts.map +1 -0
- package/dist/algorithms/{merge/detection → detection}/semantic-ranker.js +1 -1
- package/dist/algorithms/detection/semantic-ranker.js.map +1 -0
- package/dist/algorithms/{merge/detection → detection}/two-stage-detector.d.ts +1 -1
- package/dist/algorithms/detection/two-stage-detector.d.ts.map +1 -0
- package/dist/algorithms/{merge/detection → detection}/two-stage-detector.js +4 -4
- package/dist/algorithms/detection/two-stage-detector.js.map +1 -0
- package/dist/algorithms/handlers/approve-merge.d.ts.map +1 -0
- package/dist/algorithms/{merge/handlers → handlers}/approve-merge.js +4 -4
- package/dist/algorithms/handlers/approve-merge.js.map +1 -0
- package/dist/algorithms/{merge/handlers → handlers}/detect-duplicates.d.ts +1 -1
- package/dist/algorithms/handlers/detect-duplicates.d.ts.map +1 -0
- package/dist/algorithms/{merge/handlers → handlers}/detect-duplicates.js +55 -75
- package/dist/algorithms/handlers/detect-duplicates.js.map +1 -0
- package/dist/algorithms/handlers/get-stats.d.ts.map +1 -0
- package/dist/algorithms/{merge/handlers → handlers}/get-stats.js +3 -3
- package/dist/algorithms/handlers/get-stats.js.map +1 -0
- package/dist/algorithms/handlers/list-proposals.d.ts.map +1 -0
- package/dist/algorithms/{merge/handlers → handlers}/list-proposals.js +3 -3
- package/dist/algorithms/handlers/list-proposals.js.map +1 -0
- package/dist/algorithms/handlers/preview-merge.d.ts.map +1 -0
- package/dist/algorithms/{merge/handlers → handlers}/preview-merge.js +3 -3
- package/dist/algorithms/handlers/preview-merge.js.map +1 -0
- package/dist/algorithms/handlers/reject-merge.d.ts.map +1 -0
- package/dist/algorithms/{merge/handlers → handlers}/reject-merge.js +3 -3
- package/dist/algorithms/handlers/reject-merge.js.map +1 -0
- package/dist/algorithms/handlers/reverse-merge.d.ts.map +1 -0
- package/dist/algorithms/{merge/handlers → handlers}/reverse-merge.js +3 -3
- package/dist/algorithms/handlers/reverse-merge.js.map +1 -0
- package/dist/algorithms/{merge/safety → safety}/safety-checks.d.ts +1 -1
- package/dist/algorithms/safety/safety-checks.d.ts.map +1 -0
- package/dist/algorithms/safety/safety-checks.js +179 -0
- package/dist/algorithms/safety/safety-checks.js.map +1 -0
- package/dist/algorithms/{merge/strategies → strategies}/merge-strategies.d.ts +1 -1
- package/dist/algorithms/strategies/merge-strategies.d.ts.map +1 -0
- package/dist/algorithms/strategies/merge-strategies.js.map +1 -0
- package/dist/algorithms/utils/response-builder.d.ts +28 -0
- package/dist/algorithms/utils/response-builder.d.ts.map +1 -0
- package/dist/algorithms/utils/response-builder.js +37 -0
- package/dist/algorithms/utils/response-builder.js.map +1 -0
- package/dist/api/web/web.d.ts.map +1 -1
- package/dist/api/web/web.js +0 -21
- package/dist/api/web/web.js.map +1 -1
- package/dist/commands/mcp-server.js +1 -1
- package/dist/config.d.ts +9 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +35 -32
- package/dist/config.js.map +1 -1
- package/dist/core/associations.js +2 -2
- package/dist/core/associations.js.map +1 -1
- package/dist/core/core-memory.d.ts +5 -0
- package/dist/core/core-memory.d.ts.map +1 -1
- package/dist/core/core-memory.js +17 -5
- package/dist/core/core-memory.js.map +1 -1
- package/dist/core/embeddings.d.ts +9 -0
- package/dist/core/embeddings.d.ts.map +1 -1
- package/dist/core/embeddings.js +153 -16
- package/dist/core/embeddings.js.map +1 -1
- package/dist/core/layers/generator.d.ts +25 -0
- package/dist/core/layers/generator.d.ts.map +1 -0
- package/dist/core/layers/generator.js +76 -0
- package/dist/core/layers/generator.js.map +1 -0
- package/dist/core/mcp/tools.d.ts.map +1 -1
- package/dist/core/mcp/tools.js +71 -0
- package/dist/core/mcp/tools.js.map +1 -1
- package/dist/core/memory/hybrid-retrieval.d.ts.map +1 -1
- package/dist/core/memory/hybrid-retrieval.js +49 -1
- package/dist/core/memory/hybrid-retrieval.js.map +1 -1
- package/dist/core/memory/hybrid-search.d.ts.map +1 -1
- package/dist/core/memory/hybrid-search.js +0 -7
- package/dist/core/memory/hybrid-search.js.map +1 -1
- package/dist/core/memory/memories.d.ts.map +1 -1
- package/dist/core/memory/memories.js +47 -53
- package/dist/core/memory/memories.js.map +1 -1
- package/dist/core/memory/progressive-disclosure.d.ts.map +1 -1
- package/dist/core/memory/progressive-disclosure.js.map +1 -1
- package/dist/core/namespaces/index.d.ts +71 -0
- package/dist/core/namespaces/index.d.ts.map +1 -0
- package/dist/core/namespaces/index.js +296 -0
- package/dist/core/namespaces/index.js.map +1 -0
- package/dist/core/namespaces/uri-parser.d.ts +31 -0
- package/dist/core/namespaces/uri-parser.d.ts.map +1 -0
- package/dist/core/namespaces/uri-parser.js +74 -0
- package/dist/core/namespaces/uri-parser.js.map +1 -0
- package/dist/core/observations.d.ts.map +1 -1
- package/dist/core/observations.js +3 -12
- package/dist/core/observations.js.map +1 -1
- package/dist/core/projects.d.ts.map +1 -1
- package/dist/core/projects.js +0 -12
- package/dist/core/projects.js.map +1 -1
- package/dist/core/scheduler/cron-scheduler.d.ts.map +1 -1
- package/dist/core/scheduler/cron-scheduler.js +14 -0
- package/dist/core/scheduler/cron-scheduler.js.map +1 -1
- package/dist/core/session-hooks/self-iteration-job.d.ts +20 -0
- package/dist/core/session-hooks/self-iteration-job.d.ts.map +1 -0
- package/dist/core/session-hooks/self-iteration-job.js +278 -0
- package/dist/core/session-hooks/self-iteration-job.js.map +1 -0
- package/dist/core/session-hooks/session-hooks.d.ts +18 -0
- package/dist/core/session-hooks/session-hooks.d.ts.map +1 -0
- package/dist/core/session-hooks/session-hooks.js +55 -0
- package/dist/core/session-hooks/session-hooks.js.map +1 -0
- package/dist/core/tracing/collector.d.ts +111 -0
- package/dist/core/tracing/collector.d.ts.map +1 -0
- package/dist/core/tracing/collector.js +338 -0
- package/dist/core/tracing/collector.js.map +1 -0
- package/dist/core/tracing/visualizer.d.ts +32 -0
- package/dist/core/tracing/visualizer.d.ts.map +1 -0
- package/dist/core/tracing/visualizer.js +165 -0
- package/dist/core/tracing/visualizer.js.map +1 -0
- package/dist/db/bootstrap.d.ts.map +1 -1
- package/dist/db/bootstrap.js +33 -6
- package/dist/db/bootstrap.js.map +1 -1
- package/dist/drizzle/schema-sqlite.d.ts +401 -0
- package/dist/drizzle/schema-sqlite.d.ts.map +1 -1
- package/dist/drizzle/schema-sqlite.js +66 -0
- package/dist/drizzle/schema-sqlite.js.map +1 -1
- package/dist/drizzle/schema.d.ts +385 -0
- package/dist/drizzle/schema.d.ts.map +1 -1
- package/dist/drizzle/schema.js +64 -0
- package/dist/drizzle/schema.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +101 -62
- package/dist/index.js.map +1 -1
- package/generated/mcp/manifest.json +23 -0
- package/generated/mcp/mcp-servers.json +25 -0
- package/generated/mcp/mcporter.json +34 -0
- package/generated/mcp/openclaw-memory-qmd.json +17 -0
- package/generated/mcp/runtime.json +12 -0
- package/package.json +68 -26
- package/packages/plugin-claude-code/README.md +73 -0
- package/packages/plugin-claude-code/dist/plugin-wrapper.d.ts +35 -0
- package/packages/plugin-claude-code/dist/plugin-wrapper.d.ts.map +1 -0
- package/packages/plugin-claude-code/dist/plugin-wrapper.js +191 -0
- package/packages/plugin-claude-code/dist/plugin-wrapper.js.map +1 -0
- package/packages/plugin-claude-code/package.json +31 -0
- package/packages/plugin-openclaw/README.md +70 -0
- package/packages/plugin-openclaw/dist/index.d.ts +49 -0
- package/packages/plugin-openclaw/dist/index.d.ts.map +1 -0
- package/packages/plugin-openclaw/dist/index.js +262 -0
- package/packages/plugin-openclaw/dist/index.js.map +1 -0
- package/packages/plugin-openclaw/openclaw.plugin.json +94 -0
- package/packages/plugin-openclaw/package.json +31 -0
- package/packages/plugin-opencode/install.mjs +217 -0
- package/packages/plugin-opencode/package.json +21 -0
- package/scripts/build-release.sh +20 -17
- package/scripts/check-secrets.js +132 -0
- package/scripts/dependency-manager.mjs +217 -0
- package/scripts/detect-clients.mjs +78 -0
- package/scripts/github-release.sh +43 -27
- package/scripts/install-interactive.mjs +674 -0
- package/scripts/install-plugin.mjs +415 -0
- package/scripts/test-interactive.mjs +131 -0
- package/commands/managed-sync.ts +0 -69
- package/commands/mcp-server.ts +0 -519
- package/dist/algorithms/merge/analytics/token-estimator.d.ts.map +0 -1
- package/dist/algorithms/merge/analytics/token-estimator.js.map +0 -1
- package/dist/algorithms/merge/detection/hash-filters.d.ts.map +0 -1
- package/dist/algorithms/merge/detection/hash-filters.js.map +0 -1
- package/dist/algorithms/merge/detection/semantic-ranker.d.ts.map +0 -1
- package/dist/algorithms/merge/detection/semantic-ranker.js.map +0 -1
- package/dist/algorithms/merge/detection/two-stage-detector.d.ts.map +0 -1
- package/dist/algorithms/merge/detection/two-stage-detector.js.map +0 -1
- package/dist/algorithms/merge/handlers/approve-merge.d.ts.map +0 -1
- package/dist/algorithms/merge/handlers/approve-merge.js.map +0 -1
- package/dist/algorithms/merge/handlers/detect-duplicates.d.ts.map +0 -1
- package/dist/algorithms/merge/handlers/detect-duplicates.js.map +0 -1
- package/dist/algorithms/merge/handlers/get-stats.d.ts.map +0 -1
- package/dist/algorithms/merge/handlers/get-stats.js.map +0 -1
- package/dist/algorithms/merge/handlers/list-proposals.d.ts.map +0 -1
- package/dist/algorithms/merge/handlers/list-proposals.js.map +0 -1
- package/dist/algorithms/merge/handlers/preview-merge.d.ts.map +0 -1
- package/dist/algorithms/merge/handlers/preview-merge.js.map +0 -1
- package/dist/algorithms/merge/handlers/reject-merge.d.ts.map +0 -1
- package/dist/algorithms/merge/handlers/reject-merge.js.map +0 -1
- package/dist/algorithms/merge/handlers/reverse-merge.d.ts.map +0 -1
- package/dist/algorithms/merge/handlers/reverse-merge.js.map +0 -1
- package/dist/algorithms/merge/safety/safety-checks.d.ts.map +0 -1
- package/dist/algorithms/merge/safety/safety-checks.js +0 -215
- package/dist/algorithms/merge/safety/safety-checks.js.map +0 -1
- package/dist/algorithms/merge/strategies/merge-strategies.d.ts.map +0 -1
- package/dist/algorithms/merge/strategies/merge-strategies.js.map +0 -1
- package/dist/core/embeddings/qmd-provider.d.ts +0 -65
- package/dist/core/embeddings/qmd-provider.d.ts.map +0 -1
- package/dist/core/embeddings/qmd-provider.js +0 -133
- package/dist/core/embeddings/qmd-provider.js.map +0 -1
- package/scripts/init-dirs.ts +0 -15
- /package/dist/algorithms/{merge/detection → detection}/hash-filters.d.ts +0 -0
- /package/dist/algorithms/{merge/detection → detection}/hash-filters.js +0 -0
- /package/dist/algorithms/{merge/handlers → handlers}/approve-merge.d.ts +0 -0
- /package/dist/algorithms/{merge/handlers → handlers}/get-stats.d.ts +0 -0
- /package/dist/algorithms/{merge/handlers → handlers}/list-proposals.d.ts +0 -0
- /package/dist/algorithms/{merge/handlers → handlers}/preview-merge.d.ts +0 -0
- /package/dist/algorithms/{merge/handlers → handlers}/reject-merge.d.ts +0 -0
- /package/dist/algorithms/{merge/handlers → handlers}/reverse-merge.d.ts +0 -0
- /package/dist/algorithms/{merge/strategies → strategies}/merge-strategies.js +0 -0
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "squish-memory-openclaw",
|
|
3
|
+
"name": "Squish Memory for OpenClaw",
|
|
4
|
+
"description": "Connect OpenClaw to Squish memory system via MCP",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"pluginApiVersion": "1.0.0",
|
|
7
|
+
"author": "michielhdoteth",
|
|
8
|
+
"license": "MIT",
|
|
9
|
+
"homepage": "https://github.com/michielhdoteth/squish",
|
|
10
|
+
"slot": "memory",
|
|
11
|
+
"tools": [
|
|
12
|
+
{
|
|
13
|
+
"name": "memory_search",
|
|
14
|
+
"description": "Search memories using Squish hybrid search",
|
|
15
|
+
"parameters": {
|
|
16
|
+
"type": "object",
|
|
17
|
+
"properties": {
|
|
18
|
+
"query": {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"description": "Search query"
|
|
21
|
+
},
|
|
22
|
+
"maxResults": {
|
|
23
|
+
"type": "number",
|
|
24
|
+
"description": "Maximum results to return",
|
|
25
|
+
"default": 6
|
|
26
|
+
},
|
|
27
|
+
"project": {
|
|
28
|
+
"type": "string",
|
|
29
|
+
"description": "Project path to scope search"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"required": ["query"]
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"name": "memory_get",
|
|
37
|
+
"description": "Get memory content by URI or ID",
|
|
38
|
+
"parameters": {
|
|
39
|
+
"type": "object",
|
|
40
|
+
"properties": {
|
|
41
|
+
"uri": {
|
|
42
|
+
"type": "string",
|
|
43
|
+
"description": "Memory URI (e.g., squish://memory/<id>) or file path"
|
|
44
|
+
},
|
|
45
|
+
"lineRange": {
|
|
46
|
+
"type": "array",
|
|
47
|
+
"items": { "type": "number" },
|
|
48
|
+
"minItems": 2,
|
|
49
|
+
"maxItems": 2,
|
|
50
|
+
"description": "Line range [start, end]"
|
|
51
|
+
},
|
|
52
|
+
"overview": {
|
|
53
|
+
"type": "boolean",
|
|
54
|
+
"description": "Get overview instead of full content",
|
|
55
|
+
"default": false
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"required": ["uri"]
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
],
|
|
62
|
+
"config": {
|
|
63
|
+
"baseUrl": {
|
|
64
|
+
"type": "string",
|
|
65
|
+
"default": "http://127.0.0.1:8767",
|
|
66
|
+
"description": "Squish MCP server URL"
|
|
67
|
+
},
|
|
68
|
+
"autoStart": {
|
|
69
|
+
"type": "boolean",
|
|
70
|
+
"default": false,
|
|
71
|
+
"description": "Auto-start Squish MCP server if not running"
|
|
72
|
+
},
|
|
73
|
+
"sync": {
|
|
74
|
+
"type": "object",
|
|
75
|
+
"properties": {
|
|
76
|
+
"enabled": {
|
|
77
|
+
"type": "boolean",
|
|
78
|
+
"default": true
|
|
79
|
+
},
|
|
80
|
+
"interval": {
|
|
81
|
+
"type": "string",
|
|
82
|
+
"default": "5m",
|
|
83
|
+
"description": "Sync interval (e.g., 5m, 1h)"
|
|
84
|
+
},
|
|
85
|
+
"extraPaths": {
|
|
86
|
+
"type": "array",
|
|
87
|
+
"items": { "type": "string" },
|
|
88
|
+
"default": ["notes", "docs/memory"],
|
|
89
|
+
"description": "Extra directories to sync"
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@squish/memory-openclaw",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "OpenClaw memory plugin for Squish - provides memory_search and memory_get tools via Squish MCP",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"dev": "bun --hot src/index.ts",
|
|
10
|
+
"prepublishOnly": "npm run clean && npm run build",
|
|
11
|
+
"prepare": "npm run build",
|
|
12
|
+
"clean": "rm -rf dist"
|
|
13
|
+
},
|
|
14
|
+
"keywords": ["openclaw", "plugin", "memory", "mcp", "squish"],
|
|
15
|
+
"author": "michielhdoteth",
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@modelcontextprotocol/sdk": "^1.27.0"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@types/node": "^22.0.0",
|
|
22
|
+
"typescript": "^5.7.0",
|
|
23
|
+
"vitest": "^4.0.17"
|
|
24
|
+
},
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"squish-memory": ">=1.0.0"
|
|
27
|
+
},
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=18.0.0"
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* OpenCode Plugin Installer for Squish
|
|
5
|
+
* Auto-installs CLI + configures OpenCode to use Squish as MCP server
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import fs from "node:fs";
|
|
9
|
+
import path from "node:path";
|
|
10
|
+
import os from "node:os";
|
|
11
|
+
import { spawnSync } from "node:child_process";
|
|
12
|
+
|
|
13
|
+
const CONFIG_DIR = path.join(os.homedir(), ".config", "opencode");
|
|
14
|
+
const CONFIG_PATH = path.join(CONFIG_DIR, "config.json");
|
|
15
|
+
|
|
16
|
+
const OPENCODE_SCHEMA = "https://opencode.ai/config.json";
|
|
17
|
+
|
|
18
|
+
function ensureDir(dirPath) {
|
|
19
|
+
if (!fs.existsSync(dirPath)) {
|
|
20
|
+
fs.mkdirSync(dirPath, { recursive: true });
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function getSquishMcpConfig() {
|
|
25
|
+
return {
|
|
26
|
+
type: "local",
|
|
27
|
+
command: ["squish-mcp"],
|
|
28
|
+
enabled: true,
|
|
29
|
+
environment: {}
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function loadOpenCodeConfig() {
|
|
34
|
+
if (!fs.existsSync(CONFIG_PATH)) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
const content = fs.readFileSync(CONFIG_PATH, "utf8");
|
|
40
|
+
return JSON.parse(content);
|
|
41
|
+
} catch (error) {
|
|
42
|
+
console.error(`[ERROR] Failed to parse OpenCode config: ${error.message}`);
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function saveOpenCodeConfig(config) {
|
|
48
|
+
ensureDir(CONFIG_DIR);
|
|
49
|
+
fs.writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function createNewConfig() {
|
|
53
|
+
return {
|
|
54
|
+
$schema: OPENCODE_SCHEMA,
|
|
55
|
+
mcp: {
|
|
56
|
+
squish: getSquishMcpConfig()
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function installForOpenCode(options = {}) {
|
|
62
|
+
console.log("[INSTALL] Installing Squish for OpenCode...");
|
|
63
|
+
|
|
64
|
+
let config = loadOpenCodeConfig();
|
|
65
|
+
let created = false;
|
|
66
|
+
|
|
67
|
+
if (!config) {
|
|
68
|
+
if (options.dryRun) {
|
|
69
|
+
console.log("[DRY-RUN] Would create new OpenCode config at:", CONFIG_PATH);
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
config = createNewConfig();
|
|
74
|
+
created = true;
|
|
75
|
+
console.log("[INSTALL] Created new OpenCode config");
|
|
76
|
+
} else {
|
|
77
|
+
if (options.dryRun) {
|
|
78
|
+
console.log("[DRY-RUN] Would update existing OpenCode config at:", CONFIG_PATH);
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Ensure mcp section exists
|
|
83
|
+
if (!config.mcp) {
|
|
84
|
+
config.mcp = {};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Add or update squish MCP config
|
|
88
|
+
config.mcp.squish = getSquishMcpConfig();
|
|
89
|
+
console.log("[INSTALL] Updated existing OpenCode config");
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
saveOpenCodeConfig(config);
|
|
93
|
+
console.log(`[INSTALL] ${created ? 'Created' : 'Updated'}: ${CONFIG_PATH}`);
|
|
94
|
+
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function uninstallForOpenCode(options = {}) {
|
|
99
|
+
console.log("[UNINSTALL] Removing Squish from OpenCode...");
|
|
100
|
+
|
|
101
|
+
const config = loadOpenCodeConfig();
|
|
102
|
+
if (!config) {
|
|
103
|
+
console.log("[UNINSTALL] No OpenCode config found");
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (!config.mcp || !config.mcp.squish) {
|
|
108
|
+
console.log("[UNINSTALL] Squish not found in OpenCode config");
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (options.dryRun) {
|
|
113
|
+
console.log("[DRY-RUN] Would remove Squish from OpenCode config");
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
delete config.mcp.squish;
|
|
118
|
+
|
|
119
|
+
// Clean up empty mcp section
|
|
120
|
+
if (Object.keys(config.mcp).length === 0) {
|
|
121
|
+
delete config.mcp;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
saveOpenCodeConfig(config);
|
|
125
|
+
console.log("[UNINSTALL] Removed Squish from OpenCode config");
|
|
126
|
+
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function verifyOpenCodeInstallation() {
|
|
131
|
+
console.log("[VERIFY] Checking OpenCode installation...");
|
|
132
|
+
|
|
133
|
+
const config = loadOpenCodeConfig();
|
|
134
|
+
if (!config) {
|
|
135
|
+
return { ok: false, error: "OpenCode config not found" };
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
if (!config.mcp || !config.mcp.squish) {
|
|
139
|
+
return { ok: false, error: "Squish MCP not configured" };
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const squishConfig = config.mcp.squish;
|
|
143
|
+
|
|
144
|
+
if (squishConfig.type !== "local") {
|
|
145
|
+
return { ok: false, error: `Expected type 'local', got '${squishConfig.type}'` };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (!squishConfig.enabled) {
|
|
149
|
+
return { ok: false, error: "Squish MCP is disabled" };
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Check if squish-mcp command is available
|
|
153
|
+
const result = spawnSync("which", ["squish-mcp"], { encoding: "utf8", shell: true });
|
|
154
|
+
if (result.status !== 0) {
|
|
155
|
+
return { ok: false, error: "squish-mcp command not found in PATH" };
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
console.log("[VERIFY] OpenCode config:", CONFIG_PATH);
|
|
159
|
+
console.log("[VERIFY] Squish MCP configured:", squishConfig.command.join(" "));
|
|
160
|
+
console.log("[VERIFY] Status: enabled");
|
|
161
|
+
|
|
162
|
+
return { ok: true, message: "OpenCode installation verified" };
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function main() {
|
|
166
|
+
const args = process.argv.slice(2);
|
|
167
|
+
const options = {
|
|
168
|
+
dryRun: args.includes("--dry-run") || args.includes("-d"),
|
|
169
|
+
uninstall: args.includes("--uninstall") || args.includes("-u"),
|
|
170
|
+
verify: args.includes("--verify") || args.includes("-v")
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
console.log("[OpenCode Plugin for Squish]");
|
|
174
|
+
console.log();
|
|
175
|
+
|
|
176
|
+
try {
|
|
177
|
+
if (options.verify) {
|
|
178
|
+
const result = verifyOpenCodeInstallation();
|
|
179
|
+
if (result.ok) {
|
|
180
|
+
console.log("\n[VERIFY] " + result.message);
|
|
181
|
+
process.exit(0);
|
|
182
|
+
} else {
|
|
183
|
+
console.error("\n[VERIFY] Failed:", result.error);
|
|
184
|
+
process.exit(1);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if (options.uninstall) {
|
|
189
|
+
const success = uninstallForOpenCode(options);
|
|
190
|
+
process.exit(success ? 0 : 1);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
const success = installForOpenCode(options);
|
|
194
|
+
|
|
195
|
+
if (success && !options.dryRun) {
|
|
196
|
+
const verify = verifyOpenCodeInstallation();
|
|
197
|
+
if (verify.ok) {
|
|
198
|
+
console.log("\n[SUCCESS] OpenCode plugin installed successfully!");
|
|
199
|
+
console.log("\nTo use Squish in OpenCode:");
|
|
200
|
+
console.log(" 1. Restart OpenCode if it's running");
|
|
201
|
+
console.log(" 2. Start a conversation and ask about memories");
|
|
202
|
+
console.log(" 3. Or explicitly: 'use the squish tool to search for...'");
|
|
203
|
+
} else {
|
|
204
|
+
console.error("\n[WARNING] Installation succeeded but verification failed:");
|
|
205
|
+
console.error(" ", verify.error);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
process.exit(success ? 0 : 1);
|
|
210
|
+
|
|
211
|
+
} catch (error) {
|
|
212
|
+
console.error("[ERROR]", error.message);
|
|
213
|
+
process.exit(1);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
main();
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@squish/plugin-opencode",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "OpenCode plugin for Squish - auto-installs CLI and configures OpenCode to use Squish as MCP server",
|
|
5
|
+
"main": "install.mjs",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"install": "node install.mjs",
|
|
9
|
+
"verify": "node install.mjs --verify",
|
|
10
|
+
"uninstall": "node install.mjs --uninstall"
|
|
11
|
+
},
|
|
12
|
+
"keywords": ["opencode", "plugin", "memory", "mcp", "squish"],
|
|
13
|
+
"author": "michielhdoteth",
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"peerDependencies": {
|
|
16
|
+
"squish-memory": ">=1.0.0"
|
|
17
|
+
},
|
|
18
|
+
"engines": {
|
|
19
|
+
"node": ">=18.0.0"
|
|
20
|
+
}
|
|
21
|
+
}
|
package/scripts/build-release.sh
CHANGED
|
@@ -5,29 +5,32 @@
|
|
|
5
5
|
|
|
6
6
|
set -e
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
# Auto-detect version from package.json
|
|
9
|
+
VERSION=$(node -p "require('./package.json').version")
|
|
10
|
+
echo "Building Squish v$VERSION..."
|
|
9
11
|
|
|
10
12
|
# Clean previous builds
|
|
11
13
|
npm run clean
|
|
12
14
|
|
|
13
|
-
# Build the project
|
|
14
|
-
echo "Building
|
|
15
|
-
|
|
16
|
-
npx tsc features/web/web.ts --outDir dist/features/web --skipLibCheck --esModuleInterop --module commonjs
|
|
17
|
-
npx tsc features/web/web-server.ts --outDir dist/features/web --skipLibCheck --esModuleInterop --module commonjs
|
|
15
|
+
# Build the project using standard build script
|
|
16
|
+
echo "Building project..."
|
|
17
|
+
npm run build
|
|
18
18
|
|
|
19
|
-
#
|
|
20
|
-
|
|
19
|
+
# Verify MCP artifacts are generated
|
|
20
|
+
echo "🔨 Generating MCP artifacts..."
|
|
21
|
+
node scripts/generate-mcp.mjs
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
# Verify MCP artifacts
|
|
24
|
+
echo "🧪 Verifying MCP artifacts..."
|
|
25
|
+
node scripts/verify-mcp.mjs
|
|
23
26
|
|
|
24
|
-
|
|
25
|
-
echo "🧪 Testing build..."
|
|
26
|
-
timeout 5 node dist/index.js &
|
|
27
|
-
sleep 2
|
|
28
|
-
curl -s http://localhost:37777/api/health | grep -q "ok" && echo "✅ API working" || echo "❌ API failed"
|
|
27
|
+
echo "Build complete!"
|
|
29
28
|
|
|
30
|
-
#
|
|
31
|
-
|
|
29
|
+
# Optional: Test the build (uncomment if needed)
|
|
30
|
+
# echo "🧪 Testing build..."
|
|
31
|
+
# timeout 5 node dist/index.js &
|
|
32
|
+
# sleep 2
|
|
33
|
+
# curl -s http://localhost:37777/api/health | grep -q "ok" && echo "✅ API working" || echo "❌ API failed"
|
|
34
|
+
# pkill -f "node dist/index.js" || true
|
|
32
35
|
|
|
33
|
-
echo "
|
|
36
|
+
echo "Ready for release!"
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Secret Scanner - Checks for accidentally committed secrets
|
|
5
|
+
* Run this before committing or use the pre-commit hook
|
|
6
|
+
*
|
|
7
|
+
* Usage: node scripts/check-secrets.js
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { execSync } from 'child_process';
|
|
11
|
+
import { existsSync, readFileSync } from 'fs';
|
|
12
|
+
|
|
13
|
+
// Common secret patterns
|
|
14
|
+
const SECRET_PATTERNS = [
|
|
15
|
+
// API Keys
|
|
16
|
+
{ pattern: /(sk|sg)-[0-9a-zA-Z]{24,}/gi, name: 'Stripe/General API Key' },
|
|
17
|
+
{ pattern: /AIza[0-9A-Za-z\\-_]{35}/gi, name: 'Google API Key' },
|
|
18
|
+
{ pattern: /xox[baprs]-[0-9a-zA-Z-]{10,}/gi, name: 'Slack Token' },
|
|
19
|
+
{ pattern: /xox[baprs]-[0-9a-zA-Z-]{10,}/gi, name: 'Slack Token' },
|
|
20
|
+
{ pattern: /ghp_[0-9a-zA-Z]{36}/gi, name: 'GitHub Personal Access Token' },
|
|
21
|
+
{ pattern: /github_pat_[0-9a-zA-Z]{22}_[0-9a-zA-Z]{59}/gi, name: 'GitHub Fine-grained Token' },
|
|
22
|
+
{ pattern: /Bearer\s+[A-Za-z0-9\-_]+/gi, name: 'Bearer Token' },
|
|
23
|
+
{ pattern: /Authorization:\s*Bearer\s+[A-Za-z0-9\-_]+/gi, name: 'Authorization Header' },
|
|
24
|
+
{ pattern: /eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/gi, name: 'JWT Token' },
|
|
25
|
+
|
|
26
|
+
// AWS
|
|
27
|
+
{ pattern: /(?:A3T[A-Z0-9]|AKIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASIA)[A-Z0-9]{16}/gi, name: 'AWS Access Key' },
|
|
28
|
+
{ pattern: /(?:\")?aws_access_key_id(?:\\s*:\\s*\")([A-Z0-9]{20})(?:\"|$)/gi, name: 'AWS Access Key ID' },
|
|
29
|
+
{ pattern: /(?:\")?aws_secret_access_key(?:\\s*:\\s*\")([A-Za-z0-9/+=]{40})(?:\"|$)/gi, name: 'AWS Secret Access Key' },
|
|
30
|
+
|
|
31
|
+
// Database
|
|
32
|
+
{ pattern: /(?:mongodb|mysql|postgres|postgresql|redis):\/\/[^\s]+:[^\s]+@/gi, name: 'Database Connection String' },
|
|
33
|
+
{ pattern: /(?:password|passwd|pwd)\s*[=:]\s*['"]?[^'"]{8,}['"]?/gi, name: 'Password in config' },
|
|
34
|
+
|
|
35
|
+
// .env specific
|
|
36
|
+
{ pattern: /^[A-Z_]+=sk-|^[A-Z_]+=AIza/gi, name: 'API Key in .env format' },
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
// File extensions to check
|
|
40
|
+
const TEXT_EXTENSIONS = [
|
|
41
|
+
'.ts', '.js', '.json', '.md', '.txt', '.yml', '.yaml', '.toml',
|
|
42
|
+
'.sh', '.bash', '.zsh', '.ini', '.cfg', '.conf', '.env', '.env.local'
|
|
43
|
+
];
|
|
44
|
+
|
|
45
|
+
function isTextFile(filePath) {
|
|
46
|
+
return TEXT_EXTENSIONS.some(ext => filePath.endsWith(ext)) || filePath.includes('.env');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function getStagedFiles() {
|
|
50
|
+
try {
|
|
51
|
+
const output = execSync('git diff --cached --name-only', { encoding: 'utf-8' });
|
|
52
|
+
return output.split('\n').filter(f => f.trim());
|
|
53
|
+
} catch (error) {
|
|
54
|
+
console.error('Failed to get staged files:', error.message);
|
|
55
|
+
return [];
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function readFileContent(filePath) {
|
|
60
|
+
try {
|
|
61
|
+
return readFileSync(filePath, 'utf-8');
|
|
62
|
+
} catch (error) {
|
|
63
|
+
// File may have been removed or unreadable
|
|
64
|
+
return '';
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function scanContent(content, filePath) {
|
|
69
|
+
const findings = [];
|
|
70
|
+
|
|
71
|
+
for (const { pattern, name } of SECRET_PATTERNS) {
|
|
72
|
+
let match;
|
|
73
|
+
const regex = new RegExp(pattern);
|
|
74
|
+
while ((match = regex.exec(content)) !== null) {
|
|
75
|
+
const lineNumber = content.substring(0, match.index).split('\n').length;
|
|
76
|
+
findings.push({
|
|
77
|
+
file: filePath,
|
|
78
|
+
line: lineNumber,
|
|
79
|
+
type: name,
|
|
80
|
+
value: maskSecret(match[0]),
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return findings;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function maskSecret(secret) {
|
|
89
|
+
if (secret.length <= 8) return '***';
|
|
90
|
+
return secret.substring(0, 6) + '...' + secret.substring(secret.length - 4);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function main() {
|
|
94
|
+
console.log('🔍 Scanning for secrets...\n');
|
|
95
|
+
|
|
96
|
+
const stagedFiles = getStagedFiles();
|
|
97
|
+
const textFiles = stagedFiles.filter(isTextFile);
|
|
98
|
+
|
|
99
|
+
if (textFiles.length === 0) {
|
|
100
|
+
console.log('No text files to scan.');
|
|
101
|
+
process.exit(0);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
let totalFindings = 0;
|
|
105
|
+
|
|
106
|
+
for (const file of textFiles) {
|
|
107
|
+
const content = readFileContent(file);
|
|
108
|
+
if (!content) continue;
|
|
109
|
+
|
|
110
|
+
const findings = scanContent(content, file);
|
|
111
|
+
if (findings.length > 0) {
|
|
112
|
+
console.log(`❌ ${file}:`);
|
|
113
|
+
for (const finding of findings) {
|
|
114
|
+
console.log(` Line ${finding.line}: ${finding.type} - ${finding.value}`);
|
|
115
|
+
totalFindings++;
|
|
116
|
+
}
|
|
117
|
+
console.log('');
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (totalFindings > 0) {
|
|
122
|
+
console.log(`\n🚨 Found ${totalFindings} potential secret(s).`);
|
|
123
|
+
console.log(' Please remove these before committing!');
|
|
124
|
+
console.log(' Use environment variables or a secret manager instead.\n');
|
|
125
|
+
process.exit(1);
|
|
126
|
+
} else {
|
|
127
|
+
console.log('✅ No secrets detected.\n');
|
|
128
|
+
process.exit(0);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
main();
|