squish-memory 0.9.3 → 1.0.1
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 +14 -11
- package/CHANGELOG.md +68 -0
- package/README.md +82 -9
- package/bin/squish-add.mjs +32 -0
- package/bin/squish-rm.mjs +21 -0
- package/config/plugin-manifest.json +152 -0
- package/config/plugin-manifest.schema.json +244 -0
- package/config/settings.json +51 -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 +452 -472
- package/dist/api/web/web.js.map +1 -1
- package/dist/commands/mcp-server.js +7 -3
- package/dist/commands/mcp-server.js.map +1 -1
- package/dist/config.d.ts +10 -10
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +102 -55
- 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/embeddings.d.ts +1 -1
- package/dist/core/embeddings.d.ts.map +1 -1
- package/dist/core/embeddings.js +10 -67
- 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/local-embeddings.d.ts +3 -11
- package/dist/core/local-embeddings.d.ts.map +1 -1
- package/dist/core/local-embeddings.js +2 -76
- package/dist/core/local-embeddings.js.map +1 -1
- 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/context-collector.d.ts.map +1 -1
- package/dist/core/memory/context-collector.js +3 -2
- package/dist/core/memory/context-collector.js.map +1 -1
- package/dist/core/memory/feedback-tracker.d.ts.map +1 -1
- package/dist/core/memory/feedback-tracker.js +10 -6
- package/dist/core/memory/feedback-tracker.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 +32 -39
- 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 +1 -7
- 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/memory/query-rewriter.js +9 -9
- package/dist/core/memory/stats.js +5 -5
- 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 +305 -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 +26 -7
- package/dist/core/scheduler/cron-scheduler.js.map +1 -1
- package/dist/core/scheduler/job-runner.js +8 -5
- package/dist/core/scheduler/job-runner.js.map +1 -1
- package/dist/core/search/conversations.js +33 -33
- 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 +282 -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 +58 -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 +350 -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/adapter.d.ts +6 -1
- package/dist/db/adapter.d.ts.map +1 -1
- package/dist/db/adapter.js +54 -126
- package/dist/db/adapter.js.map +1 -1
- package/dist/db/bootstrap.js +477 -477
- package/dist/db/index.d.ts +5 -1
- package/dist/db/index.d.ts.map +1 -1
- package/dist/drizzle/schema-sqlite.d.ts +384 -0
- package/dist/drizzle/schema-sqlite.d.ts.map +1 -1
- package/dist/drizzle/schema-sqlite.js +65 -0
- package/dist/drizzle/schema-sqlite.js.map +1 -1
- package/dist/drizzle/schema.d.ts +368 -0
- package/dist/drizzle/schema.d.ts.map +1 -1
- package/dist/drizzle/schema.js +63 -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 +70 -28
- 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/dependency-manager.mjs +217 -0
- package/scripts/detect-clients.mjs +78 -0
- 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,674 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Squish Interactive Plugin Installer
|
|
5
|
+
* Multi-step wizard with clack
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { intro, outro, confirm, multiselect, select, isCancel, cancel, spinner, note } from '@clack/prompts';
|
|
9
|
+
import picocolors from 'picocolors';
|
|
10
|
+
import fs from "node:fs";
|
|
11
|
+
import os from "node:os";
|
|
12
|
+
import path from "node:path";
|
|
13
|
+
import { spawnSync } from "node:child_process";
|
|
14
|
+
|
|
15
|
+
const root = process.cwd();
|
|
16
|
+
const manifestPath = path.join(root, "config", "plugin-manifest.json");
|
|
17
|
+
|
|
18
|
+
const c = picocolors;
|
|
19
|
+
|
|
20
|
+
const icons = {
|
|
21
|
+
squish: "🐙",
|
|
22
|
+
check: "✓",
|
|
23
|
+
cross: "✗",
|
|
24
|
+
package: "📦",
|
|
25
|
+
arrow: "→",
|
|
26
|
+
dot: "●",
|
|
27
|
+
circle: "○",
|
|
28
|
+
diamond: "◆",
|
|
29
|
+
pointer: "❯",
|
|
30
|
+
line: "│",
|
|
31
|
+
corner: "└",
|
|
32
|
+
section: "─",
|
|
33
|
+
cli: "⌨️",
|
|
34
|
+
mcp: "🔌",
|
|
35
|
+
plugin: "🔧",
|
|
36
|
+
settings: "⚙️",
|
|
37
|
+
local: "🏠",
|
|
38
|
+
remote: "☁️",
|
|
39
|
+
brain: "🧠",
|
|
40
|
+
cloud: "☁️"
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const CLIENT_DIRS = {
|
|
44
|
+
"claude-code": path.join(os.homedir(), ".claude"),
|
|
45
|
+
opencode: path.join(os.homedir(), ".config", "opencode"),
|
|
46
|
+
codex: path.join(os.homedir(), ".codex"),
|
|
47
|
+
cursor: path.join(os.homedir(), ".cursor"),
|
|
48
|
+
vscode: path.join(os.homedir(), ".vscode", "mcp"),
|
|
49
|
+
windsurf: path.join(os.homedir(), ".windsurf"),
|
|
50
|
+
openclaw: path.join(os.homedir(), ".openclaw")
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const PLUGINS_DIR = path.join(root, "packages");
|
|
54
|
+
|
|
55
|
+
function printLogo() {
|
|
56
|
+
console.log(c.cyan(`
|
|
57
|
+
███████╗ ██████╗ ██╗ ██╗██╗███████╗██╗ ██╗
|
|
58
|
+
██╔════╝██╔═══██╗██║ ██║██║██╔════╝██║ ██║
|
|
59
|
+
███████╗██║ ██║██║ ██║██║███████╗███████║
|
|
60
|
+
╚════██║██║ ██║██║ ██║██║╚════██║██╔══██║
|
|
61
|
+
███████║╚██████╔╝╚██████╔╝██║███████║██║ ██║
|
|
62
|
+
╚══════╝ ╚═════╝ ╚═════╝ ╚═╝╚══════╝╚═╝ ╚═╝
|
|
63
|
+
`));
|
|
64
|
+
console.log(c.gray(" Universal Memory System for AI Agents\n"));
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function loadManifest() {
|
|
68
|
+
if (!fs.existsSync(manifestPath)) {
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
return JSON.parse(fs.readFileSync(manifestPath, "utf8"));
|
|
73
|
+
} catch {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function detectInstalledClients() {
|
|
79
|
+
const installed = {};
|
|
80
|
+
for (const [client, dir] of Object.entries(CLIENT_DIRS)) {
|
|
81
|
+
try {
|
|
82
|
+
installed[client] = fs.existsSync(dir);
|
|
83
|
+
} catch {
|
|
84
|
+
installed[client] = false;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return installed;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function checkPluginSource(pluginId) {
|
|
91
|
+
const pluginDirs = {
|
|
92
|
+
"claude-code": path.join(PLUGINS_DIR, "plugin-claude-code"),
|
|
93
|
+
"openclaw": path.join(PLUGINS_DIR, "plugin-openclaw"),
|
|
94
|
+
"opencode": path.join(PLUGINS_DIR, "plugin-opencode")
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const pluginDir = pluginDirs[pluginId];
|
|
98
|
+
if (!pluginDir) return false;
|
|
99
|
+
|
|
100
|
+
return fs.existsSync(pluginDir) && fs.existsSync(path.join(pluginDir, "package.json"));
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function shouldUseNonInteractive() {
|
|
104
|
+
return process.env.CI === 'true' ||
|
|
105
|
+
process.env.NON_INTERACTIVE === '1' ||
|
|
106
|
+
process.env.AUTOMATION === 'true' ||
|
|
107
|
+
!process.stdin.isTTY;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function parseArgs(argv) {
|
|
111
|
+
const flags = {
|
|
112
|
+
auto: false,
|
|
113
|
+
select: [],
|
|
114
|
+
all: false,
|
|
115
|
+
list: false,
|
|
116
|
+
dryRun: false,
|
|
117
|
+
help: false,
|
|
118
|
+
verbose: false,
|
|
119
|
+
quick: false
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
for (let i = 2; i < argv.length; i++) {
|
|
123
|
+
const token = argv[i];
|
|
124
|
+
|
|
125
|
+
if (token === "--auto" || token === "-a") {
|
|
126
|
+
flags.auto = true;
|
|
127
|
+
} else if (token === "--all") {
|
|
128
|
+
flags.all = true;
|
|
129
|
+
} else if (token === "--list" || token === "-l") {
|
|
130
|
+
flags.list = true;
|
|
131
|
+
} else if (token === "--dry-run" || token === "-n") {
|
|
132
|
+
flags.dryRun = true;
|
|
133
|
+
} else if (token === "--verbose" || token === "-v") {
|
|
134
|
+
flags.verbose = true;
|
|
135
|
+
} else if (token === "--help" || token === "-h") {
|
|
136
|
+
flags.help = true;
|
|
137
|
+
} else if (token === "--quick" || token === "-q") {
|
|
138
|
+
flags.quick = true;
|
|
139
|
+
} else if (token.startsWith("--select=")) {
|
|
140
|
+
flags.select = token.slice(9).split(",").map(s => s.trim());
|
|
141
|
+
} else if (token === "--select") {
|
|
142
|
+
flags.select = [argv[i + 1]];
|
|
143
|
+
i++;
|
|
144
|
+
} else {
|
|
145
|
+
console.log(c.red(`Unknown flag: ${token}`));
|
|
146
|
+
console.log(`Run ${c.cyan("--help")} for usage information`);
|
|
147
|
+
process.exit(1);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return flags;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function printHelp() {
|
|
155
|
+
printLogo();
|
|
156
|
+
console.log(c.white("USAGE:"));
|
|
157
|
+
console.log(` ${c.cyan("bun run install:interactive")} [OPTIONS]\n`);
|
|
158
|
+
|
|
159
|
+
console.log(c.white("OPTIONS:"));
|
|
160
|
+
console.log(` ${c.cyan("--auto")}, ${c.cyan("-a")} Skip menu, install all available plugins`);
|
|
161
|
+
console.log(` ${c.cyan("--quick")}, ${c.cyan("-q")} Quick install (CLI + all plugins)`);
|
|
162
|
+
console.log(` ${c.cyan("--select")}=<list> Pre-select plugins (comma-separated)`);
|
|
163
|
+
console.log(` ${c.cyan("--all")} Install all available plugins`);
|
|
164
|
+
console.log(` ${c.cyan("--list")}, ${c.cyan("-l")} List available plugins and exit`);
|
|
165
|
+
console.log(` ${c.cyan("--dry-run")}, ${c.cyan("-n")} Preview changes without installing`);
|
|
166
|
+
console.log(` ${c.cyan("--verbose")}, ${c.cyan("-v")} Show detailed output`);
|
|
167
|
+
console.log(` ${c.cyan("--help")}, ${c.cyan("-h")} Show this help message\n`);
|
|
168
|
+
|
|
169
|
+
console.log(c.white("ENVIRONMENT VARIABLES:"));
|
|
170
|
+
console.log(` ${c.cyan("CI=true")} Force non-interactive mode`);
|
|
171
|
+
console.log(` ${c.cyan("NON_INTERACTIVE=1")} Force non-interactive mode`);
|
|
172
|
+
console.log(` ${c.cyan("AUTOMATION=true")} Force non-interactive mode\n`);
|
|
173
|
+
|
|
174
|
+
console.log(c.white("INTERACTIVE WIZARD:"));
|
|
175
|
+
console.log(` ${c.gray("1.")} Select components: CLI, MCP Server, Plugins`);
|
|
176
|
+
console.log(` ${c.gray("2.")} Choose plugins (if selected)`);
|
|
177
|
+
console.log(` ${c.gray("3.")} Configure mode (local/remote)`);
|
|
178
|
+
console.log(` ${c.gray("4.")} Review and install\n`);
|
|
179
|
+
|
|
180
|
+
console.log(c.white("EXAMPLES:"));
|
|
181
|
+
console.log(` ${c.gray("# Interactive wizard (default)")}`);
|
|
182
|
+
console.log(` ${c.gray("$")} bun run install:interactive\n`);
|
|
183
|
+
console.log(` ${c.gray("# Quick install (CLI + all plugins)")}`);
|
|
184
|
+
console.log(` ${c.gray("$")} bun run install:interactive --quick\n`);
|
|
185
|
+
console.log(` ${c.gray("# Non-interactive: install all")}`);
|
|
186
|
+
console.log(` ${c.gray("$")} bun run install:interactive --auto\n`);
|
|
187
|
+
|
|
188
|
+
console.log(c.gray("────────────────────────────────────────────────────"));
|
|
189
|
+
console.log(c.gray("Documentation: https://github.com/michielhdoteth/squish"));
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function listPlugins() {
|
|
193
|
+
const manifest = loadManifest();
|
|
194
|
+
if (!manifest || !manifest.targets) {
|
|
195
|
+
console.log(c.red("Error: Plugin manifest not found"));
|
|
196
|
+
process.exit(1);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const installed = detectInstalledClients();
|
|
200
|
+
const clientNames = {
|
|
201
|
+
"claude-code": "Claude Code",
|
|
202
|
+
"openclaw": "OpenClaw",
|
|
203
|
+
"opencode": "OpenCode",
|
|
204
|
+
"codex": "Codex",
|
|
205
|
+
"cursor": "Cursor",
|
|
206
|
+
"vscode": "VS Code",
|
|
207
|
+
"windsurf": "Windsurf"
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
printLogo();
|
|
211
|
+
console.log(c.white("Available Plugins:"));
|
|
212
|
+
console.log(c.gray("────────────────────────────────────────────────────"));
|
|
213
|
+
console.log();
|
|
214
|
+
|
|
215
|
+
let i = 1;
|
|
216
|
+
for (const [client, config] of Object.entries(manifest.targets)) {
|
|
217
|
+
const isInstalled = installed[client];
|
|
218
|
+
const hasSource = checkPluginSource(client);
|
|
219
|
+
|
|
220
|
+
const status = isInstalled
|
|
221
|
+
? `${c.green(icons.check)} installed`
|
|
222
|
+
: `${c.yellow(icons.dot)} not installed`;
|
|
223
|
+
|
|
224
|
+
const source = hasSource
|
|
225
|
+
? `${c.cyan(icons.package)} source`
|
|
226
|
+
: `${c.red(icons.cross)} no source`;
|
|
227
|
+
|
|
228
|
+
console.log(` ${i}. ${c.white(clientNames[client] || client)}`);
|
|
229
|
+
console.log(` ${c.gray("Type:")} ${config.type || 'unknown'}`);
|
|
230
|
+
console.log(` ${status} ${source}`);
|
|
231
|
+
console.log();
|
|
232
|
+
i++;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
console.log(c.gray("────────────────────────────────────────────────────"));
|
|
236
|
+
console.log(c.gray(`Total: ${i - 1} plugins available`));
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function getPluginChoices() {
|
|
240
|
+
const manifest = loadManifest();
|
|
241
|
+
if (!manifest || !manifest.targets) {
|
|
242
|
+
return [];
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
const installed = detectInstalledClients();
|
|
246
|
+
const clientNames = {
|
|
247
|
+
"claude-code": "Claude Code",
|
|
248
|
+
"openclaw": "OpenClaw",
|
|
249
|
+
"opencode": "OpenCode",
|
|
250
|
+
"codex": "Codex",
|
|
251
|
+
"cursor": "Cursor",
|
|
252
|
+
"vscode": "VS Code",
|
|
253
|
+
"windsurf": "Windsurf"
|
|
254
|
+
};
|
|
255
|
+
|
|
256
|
+
const typeDescriptions = {
|
|
257
|
+
"hooks": "Session hooks for auto-memory",
|
|
258
|
+
"plugin-slot": "Memory slot via MCP bridge",
|
|
259
|
+
"mcp": "MCP server configuration"
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
return Object.entries(manifest.targets).map(([client, config]) => {
|
|
263
|
+
const isInstalled = installed[client];
|
|
264
|
+
const hasSource = checkPluginSource(client);
|
|
265
|
+
|
|
266
|
+
const name = clientNames[client] || client;
|
|
267
|
+
const type = typeDescriptions[config.type] || config.type || 'Plugin';
|
|
268
|
+
|
|
269
|
+
let label = name;
|
|
270
|
+
if (isInstalled) label += ` ${c.green(icons.check)}`;
|
|
271
|
+
if (hasSource) label += ` ${c.cyan(icons.package)}`;
|
|
272
|
+
|
|
273
|
+
return {
|
|
274
|
+
value: client,
|
|
275
|
+
label: label,
|
|
276
|
+
hint: type
|
|
277
|
+
};
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
async function wizardComponentSelection() {
|
|
282
|
+
const components = await multiselect({
|
|
283
|
+
message: 'What would you like to install?',
|
|
284
|
+
options: [
|
|
285
|
+
{
|
|
286
|
+
value: 'cli',
|
|
287
|
+
label: `${icons.cli} CLI - Command line interface`,
|
|
288
|
+
hint: 'squish command for terminal use'
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
value: 'plugins',
|
|
292
|
+
label: `${icons.plugin} AI Agent Plugins`,
|
|
293
|
+
hint: 'Claude Code, OpenClaw, OpenCode, etc.'
|
|
294
|
+
}
|
|
295
|
+
],
|
|
296
|
+
required: false
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
if (isCancel(components)) {
|
|
300
|
+
cancel('Installation cancelled');
|
|
301
|
+
process.exit(0);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
return components;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
async function wizardPluginSelection() {
|
|
308
|
+
const choices = getPluginChoices();
|
|
309
|
+
|
|
310
|
+
if (choices.length === 0) {
|
|
311
|
+
console.log(c.yellow("No plugins available"));
|
|
312
|
+
return [];
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
const plugins = await multiselect({
|
|
316
|
+
message: 'Which AI agents do you want to integrate with?',
|
|
317
|
+
options: choices,
|
|
318
|
+
required: false
|
|
319
|
+
});
|
|
320
|
+
|
|
321
|
+
if (isCancel(plugins)) {
|
|
322
|
+
cancel('Installation cancelled');
|
|
323
|
+
process.exit(0);
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
return plugins;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
async function wizardConfiguration() {
|
|
330
|
+
const mode = await select({
|
|
331
|
+
message: 'Select operation mode:',
|
|
332
|
+
options: [
|
|
333
|
+
{
|
|
334
|
+
value: 'local',
|
|
335
|
+
label: `${icons.local} Local Mode`,
|
|
336
|
+
hint: 'Everything runs locally (default, recommended)'
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
value: 'remote',
|
|
340
|
+
label: `${icons.remote} Remote Mode`,
|
|
341
|
+
hint: 'Connect to remote Squish server'
|
|
342
|
+
}
|
|
343
|
+
]
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
if (isCancel(mode)) {
|
|
347
|
+
cancel('Installation cancelled');
|
|
348
|
+
process.exit(0);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
const embeddings = await select({
|
|
352
|
+
message: 'Select embeddings provider:',
|
|
353
|
+
options: [
|
|
354
|
+
{
|
|
355
|
+
value: 'local',
|
|
356
|
+
label: `${icons.brain} Local Embeddings`,
|
|
357
|
+
hint: 'Uses local CPU (default, free, private)'
|
|
358
|
+
},
|
|
359
|
+
{
|
|
360
|
+
value: 'openai',
|
|
361
|
+
label: `${icons.cloud} OpenAI Embeddings`,
|
|
362
|
+
hint: 'Requires OPENAI_API_KEY (better quality)'
|
|
363
|
+
},
|
|
364
|
+
{
|
|
365
|
+
value: 'cohere',
|
|
366
|
+
label: `${icons.cloud} Cohere Embeddings`,
|
|
367
|
+
hint: 'Requires COHERE_API_KEY'
|
|
368
|
+
}
|
|
369
|
+
]
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
if (isCancel(embeddings)) {
|
|
373
|
+
cancel('Installation cancelled');
|
|
374
|
+
process.exit(0);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
return { mode, embeddings };
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
async function wizardReview(installConfig) {
|
|
381
|
+
const { components, plugins, config } = installConfig;
|
|
382
|
+
|
|
383
|
+
let summary = `${c.white("Installation Summary:")}\n\n`;
|
|
384
|
+
|
|
385
|
+
summary += `${c.cyan("Components:")}\n`;
|
|
386
|
+
if (components.includes('cli')) summary += ` ${icons.check} CLI\n`;
|
|
387
|
+
if (components.includes('mcp')) summary += ` ${icons.check} MCP Server\n`;
|
|
388
|
+
if (components.includes('plugins')) summary += ` ${icons.check} AI Agent Plugins\n`;
|
|
389
|
+
|
|
390
|
+
if (components.includes('plugins') && plugins.length > 0) {
|
|
391
|
+
summary += `\n${c.cyan("Plugins:")}\n`;
|
|
392
|
+
plugins.forEach(p => {
|
|
393
|
+
summary += ` ${icons.check} ${p}\n`;
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
summary += `\n${c.cyan("Configuration:")}\n`;
|
|
398
|
+
summary += ` ${icons.settings} Mode: ${config.mode}\n`;
|
|
399
|
+
summary += ` ${icons.brain} Embeddings: ${config.embeddings}\n`;
|
|
400
|
+
|
|
401
|
+
note(summary, 'Review');
|
|
402
|
+
|
|
403
|
+
const shouldInstall = await confirm({
|
|
404
|
+
message: 'Proceed with installation?',
|
|
405
|
+
initialValue: true
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
if (isCancel(shouldInstall) || !shouldInstall) {
|
|
409
|
+
cancel('Installation cancelled');
|
|
410
|
+
process.exit(0);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
return shouldInstall;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
async function performInstallation(installConfig, options = {}) {
|
|
417
|
+
const { components, plugins, config } = installConfig;
|
|
418
|
+
const s = spinner();
|
|
419
|
+
|
|
420
|
+
if (options.dryRun) {
|
|
421
|
+
console.log();
|
|
422
|
+
note(`${c.yellow("Dry-run mode - no changes made")}\n\nRemove --dry-run flag to perform actual installation.`, 'Preview');
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
// Install dependencies
|
|
427
|
+
if (components.length > 0 || plugins.length > 0) {
|
|
428
|
+
s.start('Installing dependencies...');
|
|
429
|
+
|
|
430
|
+
const depResult = spawnSync(
|
|
431
|
+
process.execPath,
|
|
432
|
+
[path.join(root, "scripts", "dependency-manager.mjs")],
|
|
433
|
+
{ encoding: "utf8", stdio: "pipe", timeout: 120000 }
|
|
434
|
+
);
|
|
435
|
+
|
|
436
|
+
if (depResult.status !== 0) {
|
|
437
|
+
s.stop(c.red(`${icons.cross} Dependency installation failed`));
|
|
438
|
+
if (options.verbose && depResult.stderr) {
|
|
439
|
+
console.log(c.gray(`Error: ${depResult.stderr}`));
|
|
440
|
+
}
|
|
441
|
+
process.exit(1);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
s.stop(c.green(`${icons.check} Dependencies installed`));
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// Install CLI
|
|
448
|
+
if (components.includes('cli')) {
|
|
449
|
+
s.start('Setting up CLI...');
|
|
450
|
+
// CLI is already available via npm install, but we could add global link
|
|
451
|
+
s.stop(c.green(`${icons.check} CLI ready`));
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
// Install plugins
|
|
455
|
+
if (components.includes('plugins') && plugins.length > 0) {
|
|
456
|
+
// Handle OpenCode specially - use its own installer
|
|
457
|
+
const opencodeIndex = plugins.indexOf('opencode');
|
|
458
|
+
if (opencodeIndex > -1) {
|
|
459
|
+
plugins.splice(opencodeIndex, 1);
|
|
460
|
+
|
|
461
|
+
s.start('Installing OpenCode plugin...');
|
|
462
|
+
const opencodeResult = spawnSync(
|
|
463
|
+
process.execPath,
|
|
464
|
+
[path.join(root, "packages", "plugin-opencode", "install.mjs")],
|
|
465
|
+
{ encoding: "utf8", stdio: "pipe", timeout: 60000 }
|
|
466
|
+
);
|
|
467
|
+
|
|
468
|
+
if (opencodeResult.status !== 0) {
|
|
469
|
+
s.stop(c.red(`${icons.cross} OpenCode plugin installation failed`));
|
|
470
|
+
if (options.verbose && opencodeResult.stderr) {
|
|
471
|
+
console.log(c.gray(`Error: ${opencodeResult.stderr}`));
|
|
472
|
+
}
|
|
473
|
+
} else {
|
|
474
|
+
s.stop(c.green(`${icons.check} OpenCode plugin installed`));
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
// Install remaining plugins using general installer
|
|
479
|
+
if (plugins.length > 0) {
|
|
480
|
+
s.start(`Installing ${plugins.length} plugin(s)...`);
|
|
481
|
+
|
|
482
|
+
const installResult = spawnSync(
|
|
483
|
+
process.execPath,
|
|
484
|
+
[path.join(root, "scripts", "install-plugin.mjs"), "--client=" + plugins.join(",")],
|
|
485
|
+
{ encoding: "utf8", stdio: "pipe", timeout: 300000 }
|
|
486
|
+
);
|
|
487
|
+
|
|
488
|
+
if (installResult.status !== 0) {
|
|
489
|
+
s.stop(c.red(`${icons.cross} Plugin installation failed`));
|
|
490
|
+
if (options.verbose && installResult.stderr) {
|
|
491
|
+
console.log(c.gray(`Error: ${installResult.stderr}`));
|
|
492
|
+
}
|
|
493
|
+
process.exit(1);
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
s.stop(c.green(`${icons.check} Plugins installed`));
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
// Save configuration
|
|
501
|
+
if (config) {
|
|
502
|
+
s.start('Saving configuration...');
|
|
503
|
+
// Save config to ~/.squish/config.json
|
|
504
|
+
const configPath = path.join(os.homedir(), '.squish', 'config.json');
|
|
505
|
+
const configDir = path.dirname(configPath);
|
|
506
|
+
|
|
507
|
+
if (!fs.existsSync(configDir)) {
|
|
508
|
+
fs.mkdirSync(configDir, { recursive: true });
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
fs.writeFileSync(configPath, JSON.stringify({
|
|
512
|
+
mode: config.mode,
|
|
513
|
+
embeddingsProvider: config.embeddings,
|
|
514
|
+
installedAt: new Date().toISOString(),
|
|
515
|
+
version: '1.0.0'
|
|
516
|
+
}, null, 2));
|
|
517
|
+
|
|
518
|
+
s.stop(c.green(`${icons.check} Configuration saved`));
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
async function runWizard(options = {}) {
|
|
523
|
+
printLogo();
|
|
524
|
+
|
|
525
|
+
intro(c.cyan(`${icons.squish} Squish Memory Installer`));
|
|
526
|
+
|
|
527
|
+
// Step 1: Component selection
|
|
528
|
+
const components = await wizardComponentSelection();
|
|
529
|
+
|
|
530
|
+
if (components.length === 0) {
|
|
531
|
+
cancel('No components selected. Exiting.');
|
|
532
|
+
process.exit(0);
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
// Step 2: Plugin selection (if chosen)
|
|
536
|
+
let plugins = [];
|
|
537
|
+
if (components.includes('plugins')) {
|
|
538
|
+
plugins = await wizardPluginSelection();
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
// Step 3: Configuration
|
|
542
|
+
const config = await wizardConfiguration();
|
|
543
|
+
|
|
544
|
+
// Step 4: Review
|
|
545
|
+
const installConfig = { components, plugins, config };
|
|
546
|
+
await wizardReview(installConfig);
|
|
547
|
+
|
|
548
|
+
// Step 5: Install
|
|
549
|
+
console.log();
|
|
550
|
+
await performInstallation(installConfig, options);
|
|
551
|
+
|
|
552
|
+
// Success
|
|
553
|
+
console.log();
|
|
554
|
+
outro(c.green(`${icons.check} Installation Complete!`));
|
|
555
|
+
|
|
556
|
+
// Next steps
|
|
557
|
+
console.log();
|
|
558
|
+
console.log(c.white("What's next?"));
|
|
559
|
+
console.log(` ${c.cyan(icons.arrow)} Restart your AI assistant(s)`);
|
|
560
|
+
console.log(` ${c.cyan(icons.arrow)} Try: ${c.gray("squish health")}`);
|
|
561
|
+
console.log(` ${c.cyan(icons.arrow)} Try: ${c.cyan("squish remember \"Your first memory\"")}`);
|
|
562
|
+
console.log();
|
|
563
|
+
console.log(c.gray("Documentation: https://github.com/michielhdoteth/squish"));
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
async function handleNonInteractive(flags, options) {
|
|
567
|
+
const choices = getPluginChoices();
|
|
568
|
+
|
|
569
|
+
if (choices.length === 0) {
|
|
570
|
+
console.log(c.red("No plugins available"));
|
|
571
|
+
process.exit(1);
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
let pluginIds = [];
|
|
575
|
+
let components = ['cli'];
|
|
576
|
+
|
|
577
|
+
if (flags.quick) {
|
|
578
|
+
// Quick install: CLI + all plugins
|
|
579
|
+
pluginIds = choices.map(c => c.value);
|
|
580
|
+
components = ['cli', 'plugins'];
|
|
581
|
+
if (options.verbose) {
|
|
582
|
+
printLogo();
|
|
583
|
+
console.log(`${c.cyan("[QUICK MODE]")} Installing CLI + all plugins...\n`);
|
|
584
|
+
}
|
|
585
|
+
} else if (flags.all) {
|
|
586
|
+
pluginIds = choices.map(c => c.value);
|
|
587
|
+
components = ['cli', 'mcp', 'plugins'];
|
|
588
|
+
if (options.verbose) {
|
|
589
|
+
printLogo();
|
|
590
|
+
console.log(`${c.cyan("[AUTO MODE]")} Installing all components...\n`);
|
|
591
|
+
}
|
|
592
|
+
} else if (flags.select.length > 0) {
|
|
593
|
+
const validIds = choices.map(c => c.value);
|
|
594
|
+
const invalid = flags.select.filter(s => !validIds.includes(s));
|
|
595
|
+
|
|
596
|
+
if (invalid.length > 0) {
|
|
597
|
+
console.log(c.red(`Invalid plugins: ${invalid.join(", ")}`));
|
|
598
|
+
console.log(c.gray(`Available: ${validIds.join(", ")}`));
|
|
599
|
+
process.exit(1);
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
pluginIds = flags.select;
|
|
603
|
+
components = ['cli', 'plugins'];
|
|
604
|
+
if (options.verbose) {
|
|
605
|
+
printLogo();
|
|
606
|
+
console.log(`${c.cyan("[AUTO MODE]")} Installing: ${pluginIds.join(", ")}...\n`);
|
|
607
|
+
}
|
|
608
|
+
} else {
|
|
609
|
+
console.log(c.yellow("Auto mode requires --all, --quick, or --select flag"));
|
|
610
|
+
const validIds = choices.map(c => c.value);
|
|
611
|
+
console.log(c.gray(`Available: ${validIds.join(", ")}`));
|
|
612
|
+
console.log(`Use ${c.cyan("--list")} to see all options`);
|
|
613
|
+
process.exit(1);
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
const installConfig = {
|
|
617
|
+
components,
|
|
618
|
+
plugins: pluginIds,
|
|
619
|
+
config: { mode: 'local', embeddings: 'local' }
|
|
620
|
+
};
|
|
621
|
+
|
|
622
|
+
await performInstallation(installConfig, options);
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
async function main() {
|
|
626
|
+
const flags = parseArgs(process.argv);
|
|
627
|
+
|
|
628
|
+
if (flags.help) {
|
|
629
|
+
printHelp();
|
|
630
|
+
process.exit(0);
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
if (flags.list) {
|
|
634
|
+
listPlugins();
|
|
635
|
+
process.exit(0);
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
const manifest = loadManifest();
|
|
639
|
+
if (!manifest) {
|
|
640
|
+
console.log(c.red("Error: Plugin manifest not found"));
|
|
641
|
+
console.log(c.gray(`Expected: ${manifestPath}`));
|
|
642
|
+
process.exit(1);
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
const options = {
|
|
646
|
+
dryRun: flags.dryRun,
|
|
647
|
+
verbose: flags.verbose
|
|
648
|
+
};
|
|
649
|
+
|
|
650
|
+
// Non-interactive mode
|
|
651
|
+
if (flags.auto || flags.quick || flags.select.length > 0 || shouldUseNonInteractive()) {
|
|
652
|
+
await handleNonInteractive(flags, options);
|
|
653
|
+
return;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
// Interactive wizard mode
|
|
657
|
+
await runWizard(options);
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
process.on("SIGINT", () => {
|
|
661
|
+
console.log(`\n${c.yellow("Installation cancelled.")}`);
|
|
662
|
+
process.exit(0);
|
|
663
|
+
});
|
|
664
|
+
|
|
665
|
+
process.on("SIGTERM", () => {
|
|
666
|
+
console.log(`\n${c.yellow("Installation cancelled.")}`);
|
|
667
|
+
process.exit(0);
|
|
668
|
+
});
|
|
669
|
+
|
|
670
|
+
main().catch((err) => {
|
|
671
|
+
console.log(c.red(`Fatal error: ${err.message}`));
|
|
672
|
+
console.error(err);
|
|
673
|
+
process.exit(1);
|
|
674
|
+
});
|