thingd-cli 0.12.0 → 0.14.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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AASA,OAAO,EAOL,MAAM,EACN,KAAK,YAAY,EAClB,MAAM,QAAQ,CAAC;AAKhB,KAAK,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAEjD,KAAK,YAAY,GAAG;IAClB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB,CAAC;AAEF,KAAK,UAAU,GAAG;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7B,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,EAAE,UAAU,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AA0DF,wBAAsB,MAAM,CAC1B,IAAI,WAAwB,EAC5B,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAiEjB;AA8jBD,wBAAsB,MAAM,CAC1B,OAAO,EAAE,UAAU,EACnB,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GACtC,OAAO,CAAC,IAAI,CAAC,CAcf;AA4BD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,UAAU,GAAG,iBAAiB,CA2BxE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AASA,OAAO,EAOL,MAAM,EACN,KAAK,YAAY,EAClB,MAAM,QAAQ,CAAC;AAKhB,KAAK,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAEjD,KAAK,YAAY,GAAG;IAClB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB,CAAC;AAEF,KAAK,UAAU,GAAG;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7B,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,MAAM,EAAE,UAAU,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,YAAY,CAAC;IACrB,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;CAChB,CAAC;AA2DF,wBAAsB,MAAM,CAC1B,IAAI,WAAwB,EAC5B,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAiEjB;AA8jBD,wBAAsB,MAAM,CAC1B,OAAO,EAAE,UAAU,EACnB,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GACtC,OAAO,CAAC,IAAI,CAAC,CAcf;AA4BD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,UAAU,GAAG,iBAAiB,CA2BxE"}
package/dist/index.js CHANGED
@@ -17,7 +17,7 @@ Admin and operator CLI for thingd.
17
17
  Usage:
18
18
  thingd status [--url <url>]
19
19
  thingd tools --url <url>
20
- thingd install [--raw] [--claude] [--cursor]
20
+ thingd install [--raw] [--claude] [--cursor] [--antigravity]
21
21
  thingd doctor
22
22
  thingd mcp [--path <path>] [--driver <driver>]
23
23
  thingd mcp-http [--path <path>] [--driver <driver>] [--host <host>] [--port <port>] [--auth-token <tok>] [--allow-unauthenticated]
@@ -62,6 +62,7 @@ const BOOLEAN_FLAGS = new Set([
62
62
  "raw",
63
63
  "claude",
64
64
  "cursor",
65
+ "antigravity",
65
66
  "smoke",
66
67
  ]);
67
68
  export async function runCli(args = process.argv.slice(2), options = {}) {
@@ -816,5 +817,14 @@ if (process.argv[1]) {
816
817
  }
817
818
  }
818
819
  if (isMain) {
819
- process.exitCode = await runCli();
820
+ runCli()
821
+ .then((code) => {
822
+ if (code !== 0) {
823
+ process.exit(code);
824
+ }
825
+ })
826
+ .catch((error) => {
827
+ console.error(error);
828
+ process.exit(1);
829
+ });
820
830
  }
@@ -1 +1 @@
1
- {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAwB7C,wBAAsB,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAyInE"}
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../src/install.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAwB7C,wBAAsB,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CA4JnE"}
package/dist/install.js CHANGED
@@ -1,7 +1,8 @@
1
1
  import { existsSync, readFileSync, realpathSync, writeFileSync } from "node:fs";
2
2
  import { homedir, platform } from "node:os";
3
- import { join, resolve } from "node:path";
3
+ import { dirname, join, resolve } from "node:path";
4
4
  import { createInterface } from "node:readline/promises";
5
+ import { fileURLToPath } from "node:url";
5
6
  import pc from "picocolors";
6
7
  import { defaultThingdDbPath, ensureThingdDir } from "./paths.js";
7
8
  async function askQuestion(query) {
@@ -25,6 +26,7 @@ export async function runInstall(context) {
25
26
  const isRaw = context.parsed.booleans.has("raw") || context.parsed.flags.has("raw");
26
27
  const isClaude = context.parsed.booleans.has("claude") || context.parsed.flags.has("claude");
27
28
  const isCursor = context.parsed.booleans.has("cursor") || context.parsed.flags.has("cursor");
29
+ const isAntigravity = context.parsed.booleans.has("antigravity") || context.parsed.flags.has("antigravity");
28
30
  if (!isRaw) {
29
31
  context.stderr.write(`\n${pc.bold("thingd install")}\n\n`);
30
32
  }
@@ -32,9 +34,9 @@ export async function runInstall(context) {
32
34
  let dbPath = dbPathDefault;
33
35
  let driver = driverDefault;
34
36
  if (isRaw) {
35
- choice = "4";
37
+ choice = "5";
36
38
  }
37
- else if (isClaude && isCursor) {
39
+ else if (isClaude && isCursor && isAntigravity) {
38
40
  choice = "1";
39
41
  }
40
42
  else if (isClaude) {
@@ -43,14 +45,18 @@ export async function runInstall(context) {
43
45
  else if (isCursor) {
44
46
  choice = "3";
45
47
  }
48
+ else if (isAntigravity) {
49
+ choice = "4";
50
+ }
46
51
  else if (process.stdin.isTTY) {
47
52
  // 1. Where to install
48
53
  context.stderr.write(`${pc.bold("Where would you like to install the MCP configuration?")}\n`);
49
- context.stderr.write(` [1] Claude Desktop & Cursor (Default)\n`);
54
+ context.stderr.write(` [1] Claude Desktop, Cursor & Antigravity (Default)\n`);
50
55
  context.stderr.write(` [2] Claude Desktop only\n`);
51
56
  context.stderr.write(` [3] Cursor only\n`);
52
- context.stderr.write(` [4] Print raw JSON configuration only\n\n`);
53
- const answerInstall = await askQuestion(`Select option [1-4] (default 1): `);
57
+ context.stderr.write(` [4] Antigravity only\n`);
58
+ context.stderr.write(` [5] Print raw JSON configuration only\n\n`);
59
+ const answerInstall = await askQuestion(`Select option [1-5] (default 1): `);
54
60
  choice = answerInstall.trim() || "1";
55
61
  context.stderr.write("\n");
56
62
  // 2. Database Path
@@ -97,7 +103,8 @@ export async function runInstall(context) {
97
103
  }
98
104
  const showClaude = choice === "1" || choice === "2";
99
105
  const showCursor = choice === "1" || choice === "3";
100
- const showRaw = choice === "4";
106
+ const showAntigravity = choice === "1" || choice === "4";
107
+ const showRaw = choice === "5";
101
108
  if (showClaude) {
102
109
  const claudeResult = updateClaudeDesktopConfig(config);
103
110
  if (claudeResult.updated) {
@@ -109,6 +116,17 @@ export async function runInstall(context) {
109
116
  context.stderr.write(` ${pc.yellow("⊘")} Skipped: ${claudeResult.reason}\n\n`);
110
117
  }
111
118
  }
119
+ if (showAntigravity) {
120
+ const antigravityResult = updateAntigravityConfig(config);
121
+ if (antigravityResult.updated) {
122
+ context.stderr.write(` ${pc.bold("Antigravity IDE:")}\n`);
123
+ context.stderr.write(` ${pc.green("✓")} Updated ${pc.cyan(antigravityResult.path)}\n\n`);
124
+ }
125
+ else if (antigravityResult.skipped) {
126
+ context.stderr.write(` ${pc.bold("Antigravity IDE:")}\n`);
127
+ context.stderr.write(` ${pc.yellow("⊘")} Skipped: ${antigravityResult.reason}\n\n`);
128
+ }
129
+ }
112
130
  if (showCursor) {
113
131
  context.stderr.write(` ${pc.bold("Cursor:")}\n`);
114
132
  context.stderr.write(` Paste this into Cursor Settings → Features → MCP → Add New MCP Server:\n\n`);
@@ -128,7 +146,7 @@ export async function runInstall(context) {
128
146
  context.stdout.write(`${JSON.stringify(fullConfig, null, 2)}\n`);
129
147
  }
130
148
  if (choice === "1") {
131
- context.stderr.write(`\n Restart Claude Desktop to activate. Cursor activates immediately after pasting.\n\n`);
149
+ context.stderr.write(`\n Restart Claude Desktop or Antigravity to activate. Cursor activates immediately.\n\n`);
132
150
  }
133
151
  else if (choice === "2") {
134
152
  context.stderr.write(`\n Restart Claude Desktop to activate.\n\n`);
@@ -136,6 +154,9 @@ export async function runInstall(context) {
136
154
  else if (choice === "3") {
137
155
  context.stderr.write(`\n Cursor activates immediately after pasting.\n\n`);
138
156
  }
157
+ else if (choice === "4") {
158
+ context.stderr.write(`\n Restart Antigravity IDE to activate.\n\n`);
159
+ }
139
160
  }
140
161
  function findGlobalBinPath() {
141
162
  try {
@@ -154,9 +175,26 @@ function findGlobalBinPath() {
154
175
  return null;
155
176
  }
156
177
  function resolveCliPath() {
178
+ try {
179
+ const currentFile = fileURLToPath(import.meta.url);
180
+ const dir = dirname(currentFile);
181
+ // In compiled dist folder: dist/install.js -> dist/index.js
182
+ let candidate = join(dir, "index.js");
183
+ if (existsSync(candidate)) {
184
+ return realpathSync(candidate);
185
+ }
186
+ // In dev src folder: src/install.ts -> src/index.ts
187
+ candidate = join(dir, "index.ts");
188
+ if (existsSync(candidate)) {
189
+ return realpathSync(candidate);
190
+ }
191
+ }
192
+ catch {
193
+ // Ignore and fallback
194
+ }
157
195
  const scriptPath = process.argv[1];
158
196
  if (!scriptPath) {
159
- throw new Error("Could not detect thingd CLI path from process.argv[1].");
197
+ throw new Error("Could not detect thingd CLI path.");
160
198
  }
161
199
  try {
162
200
  return realpathSync(resolve(scriptPath));
@@ -220,3 +258,48 @@ function updateClaudeDesktopConfig(config) {
220
258
  };
221
259
  }
222
260
  }
261
+ function updateAntigravityConfig(config) {
262
+ const candidates = [
263
+ join(homedir(), ".gemini", "config", "mcp_config.json"),
264
+ join(homedir(), ".gemini", "antigravity-ide", "mcp_config.json"),
265
+ ];
266
+ let updatedAny = false;
267
+ const pathsUpdated = [];
268
+ let lastError = null;
269
+ for (const configPath of candidates) {
270
+ const dir = dirname(configPath);
271
+ if (existsSync(dir)) {
272
+ try {
273
+ let existing = {};
274
+ if (existsSync(configPath)) {
275
+ const raw = readFileSync(configPath, "utf-8").trim();
276
+ if (raw) {
277
+ existing = JSON.parse(raw);
278
+ }
279
+ }
280
+ const mcpServers = (existing.mcpServers ?? {});
281
+ mcpServers.thingd = config;
282
+ existing.mcpServers = mcpServers;
283
+ writeFileSync(configPath, `${JSON.stringify(existing, null, 2)}\n`, "utf-8");
284
+ updatedAny = true;
285
+ pathsUpdated.push(configPath);
286
+ }
287
+ catch (error) {
288
+ lastError = error instanceof Error ? error : new Error(String(error));
289
+ }
290
+ }
291
+ }
292
+ if (updatedAny) {
293
+ return { updated: true, path: pathsUpdated.join(" & ") };
294
+ }
295
+ if (lastError) {
296
+ return {
297
+ skipped: true,
298
+ reason: `Failed to update config: ${lastError.message}`,
299
+ };
300
+ }
301
+ return {
302
+ skipped: true,
303
+ reason: `Antigravity directory not found in ${candidates.map((c) => dirname(c)).join(" or ")}.`,
304
+ };
305
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "thingd-cli",
3
- "version": "0.12.0",
3
+ "version": "0.14.0",
4
4
  "description": "Command-line interface, Interactive TUI Dashboard, and MCP server for thingd.",
5
5
  "type": "module",
6
6
  "author": "Sayan Mohsin",
@@ -33,7 +33,7 @@
33
33
  "cli-table3": "^0.6.5",
34
34
  "picocolors": "^1.1.1",
35
35
  "zod": "^4.4.3",
36
- "thingd": "0.12.0"
36
+ "thingd": "0.14.0"
37
37
  },
38
38
  "engines": {
39
39
  "node": ">=20"