@thingd/cli 0.31.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/LICENSE +201 -0
- package/README.md +238 -0
- package/dist/dashboard/public/assets/index-B-Y-3-0l.js +2 -0
- package/dist/dashboard/public/assets/index-B5YhpIl3.js +2 -0
- package/dist/dashboard/public/assets/index-BnFclxvN.css +1 -0
- package/dist/dashboard/public/assets/index-BtA9rnyI.js +2 -0
- package/dist/dashboard/public/assets/index-BzLTzidY.js +2 -0
- package/dist/dashboard/public/assets/index-C6PkDB7y.css +1 -0
- package/dist/dashboard/public/assets/index-D8yUCdOQ.js +2 -0
- package/dist/dashboard/public/assets/index-fQywB2df.js +2 -0
- package/dist/dashboard/public/assets/index-kZdrdi3K.css +1 -0
- package/dist/dashboard/public/assets/index-kgZrboBN.js +4 -0
- package/dist/dashboard/public/favicon.svg +1 -0
- package/dist/dashboard/public/icons.svg +24 -0
- package/dist/dashboard/public/index.html +16 -0
- package/dist/dashboard/server.d.ts +6 -0
- package/dist/dashboard/server.d.ts.map +1 -0
- package/dist/dashboard/server.js +385 -0
- package/dist/data-movement.d.ts +5 -0
- package/dist/data-movement.d.ts.map +1 -0
- package/dist/data-movement.js +257 -0
- package/dist/doctor.d.ts +3 -0
- package/dist/doctor.d.ts.map +1 -0
- package/dist/doctor.js +109 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1015 -0
- package/dist/install.d.ts +3 -0
- package/dist/install.d.ts.map +1 -0
- package/dist/install.js +311 -0
- package/dist/interactive.d.ts +2 -0
- package/dist/interactive.d.ts.map +1 -0
- package/dist/interactive.js +1592 -0
- package/dist/logo.d.ts +3 -0
- package/dist/logo.d.ts.map +1 -0
- package/dist/logo.js +8 -0
- package/dist/mcp/audit.d.ts +27 -0
- package/dist/mcp/audit.d.ts.map +1 -0
- package/dist/mcp/audit.js +36 -0
- package/dist/mcp/cluster.d.ts +68 -0
- package/dist/mcp/cluster.d.ts.map +1 -0
- package/dist/mcp/cluster.js +303 -0
- package/dist/mcp/config.d.ts +14 -0
- package/dist/mcp/config.d.ts.map +1 -0
- package/dist/mcp/config.js +67 -0
- package/dist/mcp/http.d.ts +25 -0
- package/dist/mcp/http.d.ts.map +1 -0
- package/dist/mcp/http.js +588 -0
- package/dist/mcp/index.d.ts +5 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +3 -0
- package/dist/mcp/result.d.ts +3 -0
- package/dist/mcp/result.d.ts.map +1 -0
- package/dist/mcp/result.js +10 -0
- package/dist/mcp/server.d.ts +19 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +51 -0
- package/dist/mcp/tools.d.ts +10 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +568 -0
- package/dist/mcp-http.d.ts +3 -0
- package/dist/mcp-http.d.ts.map +1 -0
- package/dist/mcp-http.js +42 -0
- package/dist/mcp.d.ts +3 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +22 -0
- package/dist/paths.d.ts +4 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +14 -0
- package/dist/rest/helpers.d.ts +17 -0
- package/dist/rest/helpers.d.ts.map +1 -0
- package/dist/rest/helpers.js +55 -0
- package/dist/rest/server.d.ts +4 -0
- package/dist/rest/server.d.ts.map +1 -0
- package/dist/rest/server.js +317 -0
- package/package.json +57 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAwB7C,wBAAsB,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAoKnE"}
|
package/dist/install.js
ADDED
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
import { existsSync, readFileSync, realpathSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { homedir, platform } from "node:os";
|
|
3
|
+
import { dirname, join, resolve } from "node:path";
|
|
4
|
+
import { createInterface } from "node:readline/promises";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
import { NativeThingStore } from "@thingd/node";
|
|
7
|
+
import pc from "picocolors";
|
|
8
|
+
import { defaultThingdDbPath, ensureThingdDir } from "./paths.js";
|
|
9
|
+
async function askQuestion(query) {
|
|
10
|
+
const rl = createInterface({
|
|
11
|
+
input: process.stdin,
|
|
12
|
+
output: process.stderr,
|
|
13
|
+
});
|
|
14
|
+
try {
|
|
15
|
+
return await rl.question(query);
|
|
16
|
+
}
|
|
17
|
+
finally {
|
|
18
|
+
rl.close();
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export async function runInstall(context) {
|
|
22
|
+
const nodePath = process.execPath;
|
|
23
|
+
const cliPath = resolveCliPath();
|
|
24
|
+
const dbPathDefault = defaultThingdDbPath();
|
|
25
|
+
const driverDefault = detectDriver();
|
|
26
|
+
ensureThingdDir();
|
|
27
|
+
const isRaw = context.parsed.booleans.has("raw") || context.parsed.flags.has("raw");
|
|
28
|
+
const isClaude = context.parsed.booleans.has("claude") || context.parsed.flags.has("claude");
|
|
29
|
+
const isCursor = context.parsed.booleans.has("cursor") || context.parsed.flags.has("cursor");
|
|
30
|
+
const isAntigravity = context.parsed.booleans.has("antigravity") || context.parsed.flags.has("antigravity");
|
|
31
|
+
if (!isRaw) {
|
|
32
|
+
context.stderr.write(`\n${pc.bold("thingd install")}\n\n`);
|
|
33
|
+
}
|
|
34
|
+
let choice = "1";
|
|
35
|
+
let dbPath = dbPathDefault;
|
|
36
|
+
let driver = driverDefault;
|
|
37
|
+
if (isRaw) {
|
|
38
|
+
choice = "5";
|
|
39
|
+
}
|
|
40
|
+
else if (isClaude && isCursor && isAntigravity) {
|
|
41
|
+
choice = "1";
|
|
42
|
+
}
|
|
43
|
+
else if (isClaude) {
|
|
44
|
+
choice = "2";
|
|
45
|
+
}
|
|
46
|
+
else if (isCursor) {
|
|
47
|
+
choice = "3";
|
|
48
|
+
}
|
|
49
|
+
else if (isAntigravity) {
|
|
50
|
+
choice = "4";
|
|
51
|
+
}
|
|
52
|
+
else if (process.stdin.isTTY) {
|
|
53
|
+
// 1. Where to install
|
|
54
|
+
context.stderr.write(`${pc.bold("Where would you like to install the MCP configuration?")}\n`);
|
|
55
|
+
context.stderr.write(` [1] Claude Desktop, Cursor & Antigravity (Default)\n`);
|
|
56
|
+
context.stderr.write(` [2] Claude Desktop only\n`);
|
|
57
|
+
context.stderr.write(` [3] Cursor only\n`);
|
|
58
|
+
context.stderr.write(` [4] Antigravity only\n`);
|
|
59
|
+
context.stderr.write(` [5] Print raw JSON configuration only\n\n`);
|
|
60
|
+
const answerInstall = await askQuestion(`Select option [1-5] (default 1): `);
|
|
61
|
+
choice = answerInstall.trim() || "1";
|
|
62
|
+
context.stderr.write("\n");
|
|
63
|
+
// 2. Database Path
|
|
64
|
+
const answerPath = await askQuestion(`Database path (default ${pc.cyan(dbPathDefault)}): `);
|
|
65
|
+
const chosenPath = answerPath.trim();
|
|
66
|
+
if (chosenPath) {
|
|
67
|
+
dbPath = chosenPath;
|
|
68
|
+
}
|
|
69
|
+
// 3. Driver
|
|
70
|
+
const answerDriver = await askQuestion(`Driver [native / memory] (default ${pc.cyan(driverDefault)}): `);
|
|
71
|
+
const chosenDriver = answerDriver.trim().toLowerCase();
|
|
72
|
+
if (chosenDriver === "native" || chosenDriver === "memory") {
|
|
73
|
+
driver = chosenDriver;
|
|
74
|
+
}
|
|
75
|
+
context.stderr.write("\n");
|
|
76
|
+
}
|
|
77
|
+
// Honor command line options if explicitly passed
|
|
78
|
+
const cliPathOption = context.parsed.flags.get("path")?.at(-1);
|
|
79
|
+
const cliDriverOption = context.parsed.flags.get("driver")?.at(-1);
|
|
80
|
+
if (cliPathOption) {
|
|
81
|
+
dbPath = cliPathOption;
|
|
82
|
+
}
|
|
83
|
+
if (cliDriverOption === "native" || cliDriverOption === "memory") {
|
|
84
|
+
driver = cliDriverOption;
|
|
85
|
+
}
|
|
86
|
+
const globalBin = findGlobalBinPath();
|
|
87
|
+
const config = globalBin
|
|
88
|
+
? {
|
|
89
|
+
command: globalBin,
|
|
90
|
+
args: ["mcp", "--path", dbPath, "--driver", driver],
|
|
91
|
+
}
|
|
92
|
+
: generateMcpConfig(nodePath, cliPath, dbPath, driver);
|
|
93
|
+
if (!isRaw) {
|
|
94
|
+
const hasNative = await NativeThingStore.isAvailable();
|
|
95
|
+
const bindingStatus = hasNative
|
|
96
|
+
? pc.green("Available/Loaded")
|
|
97
|
+
: pc.red("Unavailable/Not Found");
|
|
98
|
+
context.stderr.write(` ${pc.bold("Configuration Details:")}\n`);
|
|
99
|
+
context.stderr.write(` ${pc.green("✓")} Database path: ${pc.cyan(dbPath)}\n`);
|
|
100
|
+
context.stderr.write(` ${pc.green("✓")} Driver: ${pc.cyan(driver)}\n`);
|
|
101
|
+
context.stderr.write(` ${hasNative ? pc.green("✓") : pc.yellow("⚠")} Native Addon: ${bindingStatus}\n`);
|
|
102
|
+
if (globalBin) {
|
|
103
|
+
context.stderr.write(` ${pc.green("✓")} Command: ${pc.cyan(globalBin)}\n\n`);
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
context.stderr.write(` ${pc.green("✓")} Node: ${pc.cyan(nodePath)}\n`);
|
|
107
|
+
context.stderr.write(` ${pc.green("✓")} CLI: ${pc.cyan(cliPath)}\n\n`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
const showClaude = choice === "1" || choice === "2";
|
|
111
|
+
const showCursor = choice === "1" || choice === "3";
|
|
112
|
+
const showAntigravity = choice === "1" || choice === "4";
|
|
113
|
+
const showRaw = choice === "5";
|
|
114
|
+
if (showClaude) {
|
|
115
|
+
const claudeResult = updateClaudeDesktopConfig(config);
|
|
116
|
+
if (claudeResult.updated) {
|
|
117
|
+
context.stderr.write(` ${pc.bold("Claude Desktop:")}\n`);
|
|
118
|
+
context.stderr.write(` ${pc.green("✓")} Updated ${pc.cyan(claudeResult.path)}\n\n`);
|
|
119
|
+
}
|
|
120
|
+
else if (claudeResult.skipped) {
|
|
121
|
+
context.stderr.write(` ${pc.bold("Claude Desktop:")}\n`);
|
|
122
|
+
context.stderr.write(` ${pc.yellow("⊘")} Skipped: ${claudeResult.reason}\n\n`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (showAntigravity) {
|
|
126
|
+
const antigravityResult = updateAntigravityConfig(config);
|
|
127
|
+
if (antigravityResult.updated) {
|
|
128
|
+
context.stderr.write(` ${pc.bold("Antigravity IDE:")}\n`);
|
|
129
|
+
context.stderr.write(` ${pc.green("✓")} Updated ${pc.cyan(antigravityResult.path)}\n\n`);
|
|
130
|
+
}
|
|
131
|
+
else if (antigravityResult.skipped) {
|
|
132
|
+
context.stderr.write(` ${pc.bold("Antigravity IDE:")}\n`);
|
|
133
|
+
context.stderr.write(` ${pc.yellow("⊘")} Skipped: ${antigravityResult.reason}\n\n`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (showCursor) {
|
|
137
|
+
context.stderr.write(` ${pc.bold("Cursor:")}\n`);
|
|
138
|
+
context.stderr.write(` Paste this into Cursor Settings → Features → MCP → Add New MCP Server:\n\n`);
|
|
139
|
+
const fullConfig = {
|
|
140
|
+
mcpServers: {
|
|
141
|
+
thingd: config,
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
context.stdout.write(`${JSON.stringify(fullConfig, null, 2)}\n`);
|
|
145
|
+
}
|
|
146
|
+
if (showRaw) {
|
|
147
|
+
const fullConfig = {
|
|
148
|
+
mcpServers: {
|
|
149
|
+
thingd: config,
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
context.stdout.write(`${JSON.stringify(fullConfig, null, 2)}\n`);
|
|
153
|
+
}
|
|
154
|
+
if (choice === "1") {
|
|
155
|
+
context.stderr.write(`\n Restart Claude Desktop or Antigravity to activate. Cursor activates immediately.\n\n`);
|
|
156
|
+
}
|
|
157
|
+
else if (choice === "2") {
|
|
158
|
+
context.stderr.write(`\n Restart Claude Desktop to activate.\n\n`);
|
|
159
|
+
}
|
|
160
|
+
else if (choice === "3") {
|
|
161
|
+
context.stderr.write(`\n Cursor activates immediately after pasting.\n\n`);
|
|
162
|
+
}
|
|
163
|
+
else if (choice === "4") {
|
|
164
|
+
context.stderr.write(`\n Restart Antigravity IDE to activate.\n\n`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
function findGlobalBinPath() {
|
|
168
|
+
try {
|
|
169
|
+
const cliPath = resolveCliPath();
|
|
170
|
+
// In standard npm/nvm/pnpm global installations:
|
|
171
|
+
// CLI is at <prefix>/lib/node_modules/thingd-cli/dist/index.js
|
|
172
|
+
// Binary is at <prefix>/bin/thingd
|
|
173
|
+
const candidate = resolve(cliPath, "../../../../../bin/thingd");
|
|
174
|
+
if (existsSync(candidate)) {
|
|
175
|
+
return candidate;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
// Ignore
|
|
180
|
+
}
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
183
|
+
function resolveCliPath() {
|
|
184
|
+
try {
|
|
185
|
+
const currentFile = fileURLToPath(import.meta.url);
|
|
186
|
+
const dir = dirname(currentFile);
|
|
187
|
+
// In compiled dist folder: dist/install.js -> dist/index.js
|
|
188
|
+
let candidate = join(dir, "index.js");
|
|
189
|
+
if (existsSync(candidate)) {
|
|
190
|
+
return realpathSync(candidate);
|
|
191
|
+
}
|
|
192
|
+
// In dev src folder: src/install.ts -> src/index.ts
|
|
193
|
+
candidate = join(dir, "index.ts");
|
|
194
|
+
if (existsSync(candidate)) {
|
|
195
|
+
return realpathSync(candidate);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
catch {
|
|
199
|
+
// Ignore and fallback
|
|
200
|
+
}
|
|
201
|
+
const scriptPath = process.argv[1];
|
|
202
|
+
if (!scriptPath) {
|
|
203
|
+
throw new Error("Could not detect thingd CLI path.");
|
|
204
|
+
}
|
|
205
|
+
try {
|
|
206
|
+
return realpathSync(resolve(scriptPath));
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
return resolve(scriptPath);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
function detectDriver() {
|
|
213
|
+
try {
|
|
214
|
+
// Check if the native .node binary exists relative to the CLI entry point.
|
|
215
|
+
// When installed globally via npm, thingd-native is typically a sibling package.
|
|
216
|
+
const cliDir = join(resolveCliPath(), "..", "..");
|
|
217
|
+
const nativePaths = [
|
|
218
|
+
join(cliDir, "node_modules", "thingd-native", "dist", "thingd_native.node"),
|
|
219
|
+
join(cliDir, "..", "thingd-native", "dist", "thingd_native.node"),
|
|
220
|
+
];
|
|
221
|
+
for (const candidate of nativePaths) {
|
|
222
|
+
if (existsSync(candidate)) {
|
|
223
|
+
return "native";
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
catch {
|
|
228
|
+
// Ignore detection errors.
|
|
229
|
+
}
|
|
230
|
+
// Default to native since most global installs will have it.
|
|
231
|
+
// If it's not available, the SDK will produce a clear error at open time.
|
|
232
|
+
return "native";
|
|
233
|
+
}
|
|
234
|
+
function generateMcpConfig(nodePath, cliPath, dbPath, driver) {
|
|
235
|
+
return {
|
|
236
|
+
command: nodePath,
|
|
237
|
+
args: [cliPath, "mcp", "--path", dbPath, "--driver", driver],
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
function updateClaudeDesktopConfig(config) {
|
|
241
|
+
if (platform() !== "darwin") {
|
|
242
|
+
return { skipped: true, reason: "Claude Desktop auto-config is only supported on macOS." };
|
|
243
|
+
}
|
|
244
|
+
const configPath = join(homedir(), "Library", "Application Support", "Claude", "claude_desktop_config.json");
|
|
245
|
+
if (!existsSync(configPath)) {
|
|
246
|
+
return {
|
|
247
|
+
skipped: true,
|
|
248
|
+
reason: `Config file not found at ${configPath}. Is Claude Desktop installed?`,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
try {
|
|
252
|
+
const raw = readFileSync(configPath, "utf-8");
|
|
253
|
+
const existing = JSON.parse(raw);
|
|
254
|
+
const mcpServers = (existing.mcpServers ?? {});
|
|
255
|
+
mcpServers.thingd = config;
|
|
256
|
+
existing.mcpServers = mcpServers;
|
|
257
|
+
writeFileSync(configPath, `${JSON.stringify(existing, null, 2)}\n`, "utf-8");
|
|
258
|
+
return { updated: true, path: configPath };
|
|
259
|
+
}
|
|
260
|
+
catch (error) {
|
|
261
|
+
return {
|
|
262
|
+
skipped: true,
|
|
263
|
+
reason: `Failed to update config: ${error instanceof Error ? error.message : String(error)}`,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
function updateAntigravityConfig(config) {
|
|
268
|
+
const candidates = [
|
|
269
|
+
join(homedir(), ".gemini", "config", "mcp_config.json"),
|
|
270
|
+
join(homedir(), ".gemini", "antigravity-ide", "mcp_config.json"),
|
|
271
|
+
];
|
|
272
|
+
let updatedAny = false;
|
|
273
|
+
const pathsUpdated = [];
|
|
274
|
+
let lastError = null;
|
|
275
|
+
for (const configPath of candidates) {
|
|
276
|
+
const dir = dirname(configPath);
|
|
277
|
+
if (existsSync(dir)) {
|
|
278
|
+
try {
|
|
279
|
+
let existing = {};
|
|
280
|
+
if (existsSync(configPath)) {
|
|
281
|
+
const raw = readFileSync(configPath, "utf-8").trim();
|
|
282
|
+
if (raw) {
|
|
283
|
+
existing = JSON.parse(raw);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
const mcpServers = (existing.mcpServers ?? {});
|
|
287
|
+
mcpServers.thingd = config;
|
|
288
|
+
existing.mcpServers = mcpServers;
|
|
289
|
+
writeFileSync(configPath, `${JSON.stringify(existing, null, 2)}\n`, "utf-8");
|
|
290
|
+
updatedAny = true;
|
|
291
|
+
pathsUpdated.push(configPath);
|
|
292
|
+
}
|
|
293
|
+
catch (error) {
|
|
294
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
if (updatedAny) {
|
|
299
|
+
return { updated: true, path: pathsUpdated.join(" & ") };
|
|
300
|
+
}
|
|
301
|
+
if (lastError) {
|
|
302
|
+
return {
|
|
303
|
+
skipped: true,
|
|
304
|
+
reason: `Failed to update config: ${lastError.message}`,
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
return {
|
|
308
|
+
skipped: true,
|
|
309
|
+
reason: `Antigravity directory not found in ${candidates.map((c) => dirname(c)).join(" or ")}.`,
|
|
310
|
+
};
|
|
311
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive.d.ts","sourceRoot":"","sources":["../src/interactive.ts"],"names":[],"mappings":"AA2qDA,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAkCvD"}
|