@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.
Files changed (76) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +238 -0
  3. package/dist/dashboard/public/assets/index-B-Y-3-0l.js +2 -0
  4. package/dist/dashboard/public/assets/index-B5YhpIl3.js +2 -0
  5. package/dist/dashboard/public/assets/index-BnFclxvN.css +1 -0
  6. package/dist/dashboard/public/assets/index-BtA9rnyI.js +2 -0
  7. package/dist/dashboard/public/assets/index-BzLTzidY.js +2 -0
  8. package/dist/dashboard/public/assets/index-C6PkDB7y.css +1 -0
  9. package/dist/dashboard/public/assets/index-D8yUCdOQ.js +2 -0
  10. package/dist/dashboard/public/assets/index-fQywB2df.js +2 -0
  11. package/dist/dashboard/public/assets/index-kZdrdi3K.css +1 -0
  12. package/dist/dashboard/public/assets/index-kgZrboBN.js +4 -0
  13. package/dist/dashboard/public/favicon.svg +1 -0
  14. package/dist/dashboard/public/icons.svg +24 -0
  15. package/dist/dashboard/public/index.html +16 -0
  16. package/dist/dashboard/server.d.ts +6 -0
  17. package/dist/dashboard/server.d.ts.map +1 -0
  18. package/dist/dashboard/server.js +385 -0
  19. package/dist/data-movement.d.ts +5 -0
  20. package/dist/data-movement.d.ts.map +1 -0
  21. package/dist/data-movement.js +257 -0
  22. package/dist/doctor.d.ts +3 -0
  23. package/dist/doctor.d.ts.map +1 -0
  24. package/dist/doctor.js +109 -0
  25. package/dist/index.d.ts +42 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +1015 -0
  28. package/dist/install.d.ts +3 -0
  29. package/dist/install.d.ts.map +1 -0
  30. package/dist/install.js +311 -0
  31. package/dist/interactive.d.ts +2 -0
  32. package/dist/interactive.d.ts.map +1 -0
  33. package/dist/interactive.js +1592 -0
  34. package/dist/logo.d.ts +3 -0
  35. package/dist/logo.d.ts.map +1 -0
  36. package/dist/logo.js +8 -0
  37. package/dist/mcp/audit.d.ts +27 -0
  38. package/dist/mcp/audit.d.ts.map +1 -0
  39. package/dist/mcp/audit.js +36 -0
  40. package/dist/mcp/cluster.d.ts +68 -0
  41. package/dist/mcp/cluster.d.ts.map +1 -0
  42. package/dist/mcp/cluster.js +303 -0
  43. package/dist/mcp/config.d.ts +14 -0
  44. package/dist/mcp/config.d.ts.map +1 -0
  45. package/dist/mcp/config.js +67 -0
  46. package/dist/mcp/http.d.ts +25 -0
  47. package/dist/mcp/http.d.ts.map +1 -0
  48. package/dist/mcp/http.js +588 -0
  49. package/dist/mcp/index.d.ts +5 -0
  50. package/dist/mcp/index.d.ts.map +1 -0
  51. package/dist/mcp/index.js +3 -0
  52. package/dist/mcp/result.d.ts +3 -0
  53. package/dist/mcp/result.d.ts.map +1 -0
  54. package/dist/mcp/result.js +10 -0
  55. package/dist/mcp/server.d.ts +19 -0
  56. package/dist/mcp/server.d.ts.map +1 -0
  57. package/dist/mcp/server.js +51 -0
  58. package/dist/mcp/tools.d.ts +10 -0
  59. package/dist/mcp/tools.d.ts.map +1 -0
  60. package/dist/mcp/tools.js +568 -0
  61. package/dist/mcp-http.d.ts +3 -0
  62. package/dist/mcp-http.d.ts.map +1 -0
  63. package/dist/mcp-http.js +42 -0
  64. package/dist/mcp.d.ts +3 -0
  65. package/dist/mcp.d.ts.map +1 -0
  66. package/dist/mcp.js +22 -0
  67. package/dist/paths.d.ts +4 -0
  68. package/dist/paths.d.ts.map +1 -0
  69. package/dist/paths.js +14 -0
  70. package/dist/rest/helpers.d.ts +17 -0
  71. package/dist/rest/helpers.d.ts.map +1 -0
  72. package/dist/rest/helpers.js +55 -0
  73. package/dist/rest/server.d.ts +4 -0
  74. package/dist/rest/server.d.ts.map +1 -0
  75. package/dist/rest/server.js +317 -0
  76. package/package.json +57 -0
package/dist/doctor.js ADDED
@@ -0,0 +1,109 @@
1
+ import { NativeThingStore } from "@thingd/node";
2
+ import pc from "picocolors";
3
+ import { resolveConnection } from "./index.js";
4
+ export async function runDoctor(context) {
5
+ context.stderr.write(`\n${pc.bold("thingd doctor")}\n`);
6
+ context.stderr.write(`${pc.dim("Running system diagnostics and connectivity tests...")}\n\n`);
7
+ let healthy = true;
8
+ // 1. Check Node version
9
+ const nodeVersion = process.version;
10
+ const majorVersion = Number.parseInt(nodeVersion.slice(1).split(".")[0] ?? "0", 10);
11
+ if (majorVersion >= 20) {
12
+ context.stderr.write(` ${pc.green("✓")} Node version: ${pc.cyan(nodeVersion)} (OK)\n`);
13
+ }
14
+ else {
15
+ healthy = false;
16
+ context.stderr.write(` ${pc.red("×")} Node version: ${pc.yellow(nodeVersion)} (Requires >= v20.x)\n`);
17
+ }
18
+ // 2. Resolve connection options
19
+ const connection = resolveConnection(context);
20
+ // 3. Native Driver Checks
21
+ if (connection.driver === "native") {
22
+ try {
23
+ const hasNative = await NativeThingStore.isAvailable();
24
+ if (hasNative) {
25
+ const loadedPath = (await NativeThingStore.getLoadedPath()) ?? "unknown";
26
+ const buildType = loadedPath.includes("prebuilds")
27
+ ? pc.cyan("Loaded prebuilt driver")
28
+ : pc.cyan("Loaded local development build");
29
+ context.stderr.write(` ${pc.green("✓")} Native Addon: ${buildType} (${pc.dim(loadedPath)})\n`);
30
+ }
31
+ else {
32
+ healthy = false;
33
+ context.stderr.write(` ${pc.red("×")} Native Addon: ${pc.yellow('Not found. Run "pnpm --filter thingd-native build" or configure THINGD_NATIVE_PATH.')}\n`);
34
+ }
35
+ }
36
+ catch (error) {
37
+ healthy = false;
38
+ context.stderr.write(` ${pc.red("×")} Native Addon: ${pc.yellow(`Failed to load native addon: ${error instanceof Error ? error.message : String(error)}`)}\n`);
39
+ }
40
+ }
41
+ else {
42
+ context.stderr.write(` ${pc.dim("○")} Native Addon: Skipped (Using driver: "${connection.driver ?? "memory"}")\n`);
43
+ }
44
+ // 4. Remote Sidecar Reachability & Auth Checks
45
+ if (connection.cloud) {
46
+ const rawUrl = connection.path;
47
+ const isLocal = rawUrl.includes("localhost") || rawUrl.includes("127.0.0.1");
48
+ if (!connection.authToken && !isLocal) {
49
+ context.stderr.write(` ${pc.yellow("⚠")} Auth Token: ${pc.yellow("Missing THINGD_AUTH_TOKEN for remote server (might fail)")}\n`);
50
+ }
51
+ else if (connection.authToken) {
52
+ context.stderr.write(` ${pc.green("✓")} Auth Token: ${pc.cyan("Configured")}\n`);
53
+ }
54
+ else {
55
+ context.stderr.write(` ${pc.green("✓")} Auth Token: ${pc.dim("Not required for local sidecar")}\n`);
56
+ }
57
+ try {
58
+ const normalizeUrl = (val) => val.startsWith("thingd://") ? `http://${val.slice("thingd://".length)}` : val;
59
+ const targetUrl = new URL(normalizeUrl(rawUrl));
60
+ if (targetUrl.pathname === "/mcp" || targetUrl.pathname === "") {
61
+ targetUrl.pathname = "/healthz";
62
+ }
63
+ else {
64
+ targetUrl.pathname = `${targetUrl.pathname.replace(/\/mcp$/, "")}/healthz`;
65
+ }
66
+ context.stderr.write(` ${pc.dim("○")} Connectivity: Checking reachability to ${pc.cyan(targetUrl.toString())}...\n`);
67
+ const controller = new AbortController();
68
+ const timeoutId = setTimeout(() => controller.abort(), 3000);
69
+ const headers = {};
70
+ if (connection.authToken) {
71
+ headers.Authorization = `Bearer ${connection.authToken}`;
72
+ }
73
+ try {
74
+ const response = await fetch(targetUrl, {
75
+ signal: controller.signal,
76
+ headers,
77
+ });
78
+ clearTimeout(timeoutId);
79
+ if (response.ok) {
80
+ context.stderr.write(` ${pc.green("✓")} Connectivity: ${pc.cyan("Connected successfully!")} (${pc.dim(`HTTP ${response.status}`)})\n`);
81
+ }
82
+ else {
83
+ healthy = false;
84
+ context.stderr.write(` ${pc.red("×")} Connectivity: ${pc.yellow(`Server responded with non-2xx status`)} (${pc.dim(`HTTP ${response.status}`)})\n`);
85
+ }
86
+ }
87
+ catch (fetchError) {
88
+ clearTimeout(timeoutId);
89
+ healthy = false;
90
+ context.stderr.write(` ${pc.red("×")} Connectivity: ${pc.yellow(`Failed to connect. Connection refused or timed out.`)} (${pc.dim(fetchError instanceof Error ? fetchError.message : String(fetchError))})\n`);
91
+ }
92
+ }
93
+ catch (urlError) {
94
+ healthy = false;
95
+ context.stderr.write(` ${pc.red("×")} Connectivity: ${pc.yellow(`Invalid URL structure: ${urlError instanceof Error ? urlError.message : String(urlError)}`)}\n`);
96
+ }
97
+ }
98
+ else {
99
+ context.stderr.write(` ${pc.green("✓")} Connectivity: ${pc.cyan("Local SQLite Store")} (${pc.dim(connection.path)})\n`);
100
+ }
101
+ // Final Summary Report
102
+ context.stderr.write("\n");
103
+ if (healthy) {
104
+ context.stderr.write(` ${pc.bold(pc.green("Diagnosis: Everything looks healthy!"))}\n\n`);
105
+ }
106
+ else {
107
+ context.stderr.write(` ${pc.bold(pc.yellow("Diagnosis: Some items require attention (see errors above)."))}\n\n`);
108
+ }
109
+ }
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env node
2
+ import { ThingD, type ThingDDriver } from "@thingd/node";
3
+ type CliEnv = Record<string, string | undefined>;
4
+ type WritableLike = {
5
+ write(chunk: string): void;
6
+ };
7
+ export type RunCliOptions = {
8
+ env?: CliEnv;
9
+ stdout?: WritableLike;
10
+ stderr?: WritableLike;
11
+ };
12
+ export type ParsedArgs = {
13
+ tokens: string[];
14
+ flags: Map<string, string[]>;
15
+ booleans: Set<string>;
16
+ };
17
+ export type CliContext = {
18
+ parsed: ParsedArgs;
19
+ env: CliEnv;
20
+ stdout: WritableLike;
21
+ stderr: WritableLike;
22
+ pretty: boolean;
23
+ };
24
+ export type ConnectionOptions = {
25
+ path: string;
26
+ driver?: ThingDDriver;
27
+ authToken?: string;
28
+ cloud: boolean;
29
+ };
30
+ export declare function runCli(args?: string[], options?: RunCliOptions): Promise<number>;
31
+ export declare function withDb(context: CliContext, callback: (db: ThingD) => Promise<void>): Promise<void>;
32
+ export declare function resolveConnection(context: CliContext): ConnectionOptions;
33
+ export declare function hasFlag(parsed: ParsedArgs, name: string): boolean;
34
+ export declare function stringFlag(parsed: ParsedArgs, name: string): string | undefined;
35
+ export declare function stringFlags(parsed: ParsedArgs, name: string): string[] | undefined;
36
+ export declare function requiredFlag(parsed: ParsedArgs, name: string): string;
37
+ export declare function optionalToken(parsed: ParsedArgs, index: number): string | undefined;
38
+ export declare function requiredToken(parsed: ParsedArgs, index: number, name: string): string;
39
+ export declare function writeJson(target: WritableLike, data: unknown, pretty: boolean): void;
40
+ export declare function writeText(target: WritableLike, text: string): void;
41
+ export {};
42
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAQA,OAAO,EASL,MAAM,EACN,KAAK,YAAY,EAClB,MAAM,cAAc,CAAC;AAOtB,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,MAAM,MAAM,UAAU,GAAG;IACvB,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;AAsCF,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;AAmEF,wBAAsB,MAAM,CAC1B,IAAI,WAAwB,EAC5B,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,MAAM,CAAC,CA6EjB;AAkxBD,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;AAiDD,wBAAgB,OAAO,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjE;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE/E;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAGlF;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMrE;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAEnF;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMrF;AAyFD,wBAAgB,SAAS,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI,CAEpF;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAElE"}