straylight-ai 0.1.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/bin/cli.js +39 -0
- package/bin/mcp-shim.js +85 -0
- package/dist/commands/setup.d.ts +9 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +61 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/start.d.ts +6 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +33 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/status.d.ts +11 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +40 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/stop.d.ts +6 -0
- package/dist/commands/stop.d.ts.map +1 -0
- package/dist/commands/stop.js +25 -0
- package/dist/commands/stop.js.map +1 -0
- package/dist/docker.d.ts +42 -0
- package/dist/docker.d.ts.map +1 -0
- package/dist/docker.js +126 -0
- package/dist/docker.js.map +1 -0
- package/dist/health.d.ts +22 -0
- package/dist/health.d.ts.map +1 -0
- package/dist/health.js +44 -0
- package/dist/health.js.map +1 -0
- package/dist/mcp-register.d.ts +19 -0
- package/dist/mcp-register.d.ts.map +1 -0
- package/dist/mcp-register.js +59 -0
- package/dist/mcp-register.js.map +1 -0
- package/dist/open.d.ts +6 -0
- package/dist/open.d.ts.map +1 -0
- package/dist/open.js +70 -0
- package/dist/open.js.map +1 -0
- package/package.json +39 -0
- package/src/__tests__/commands.test.ts +272 -0
- package/src/__tests__/docker.test.ts +139 -0
- package/src/__tests__/health.test.ts +107 -0
- package/src/__tests__/mcp-register.test.ts +123 -0
- package/src/__tests__/open.test.ts +61 -0
- package/src/commands/setup.ts +72 -0
- package/src/commands/start.ts +44 -0
- package/src/commands/status.ts +51 -0
- package/src/commands/stop.ts +31 -0
- package/src/docker.ts +102 -0
- package/src/health.ts +55 -0
- package/src/mcp-register.ts +62 -0
- package/src/open.ts +33 -0
package/bin/cli.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
const path = require("path");
|
|
5
|
+
|
|
6
|
+
const command = process.argv[2] || "setup";
|
|
7
|
+
|
|
8
|
+
const validCommands = ["setup", "start", "stop", "status", "mcp"];
|
|
9
|
+
|
|
10
|
+
if (!validCommands.includes(command)) {
|
|
11
|
+
console.error(`Unknown command: ${command}`);
|
|
12
|
+
console.error(`Valid commands: ${validCommands.join(", ")}`);
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// The MCP command proxies to the mcp-shim
|
|
17
|
+
if (command === "mcp") {
|
|
18
|
+
require(path.join(__dirname, "mcp-shim.js"));
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Dynamically require compiled TypeScript output from dist/
|
|
23
|
+
const commandModule = require(path.join(__dirname, "..", "dist", "commands", command + ".js"));
|
|
24
|
+
|
|
25
|
+
let runner;
|
|
26
|
+
if (command === "setup") runner = commandModule.runSetup;
|
|
27
|
+
else if (command === "start") runner = commandModule.runStart;
|
|
28
|
+
else if (command === "stop") runner = commandModule.runStop;
|
|
29
|
+
else if (command === "status") runner = commandModule.runStatus;
|
|
30
|
+
|
|
31
|
+
if (typeof runner !== "function") {
|
|
32
|
+
console.error(`Internal error: could not find runner for command "${command}"`);
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
runner().catch((err) => {
|
|
37
|
+
console.error(`Error: ${err.message}`);
|
|
38
|
+
process.exit(1);
|
|
39
|
+
});
|
package/bin/mcp-shim.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* MCP binary launcher for Straylight-AI.
|
|
6
|
+
*
|
|
7
|
+
* Resolution order:
|
|
8
|
+
* 1. Platform-specific binary from optionalDependencies
|
|
9
|
+
* (@straylight-ai/bin-<platform>-<arch>)
|
|
10
|
+
* 2. Docker exec fallback: `docker exec -i straylight-ai straylight-mcp`
|
|
11
|
+
*
|
|
12
|
+
* stdin/stdout/stderr are passed through so the MCP host can communicate
|
|
13
|
+
* over stdio as required by the MCP protocol.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
const { spawn } = require("child_process");
|
|
17
|
+
const path = require("path");
|
|
18
|
+
const os = require("os");
|
|
19
|
+
|
|
20
|
+
const CONTAINER_NAME = "straylight-ai";
|
|
21
|
+
const BIN_NAME = os.platform() === "win32" ? "straylight-mcp.exe" : "straylight-mcp";
|
|
22
|
+
|
|
23
|
+
function tryLocalBinary() {
|
|
24
|
+
const platform = os.platform();
|
|
25
|
+
// Map Node's os.arch() to the arch strings used in package names
|
|
26
|
+
const archMap = { x64: "x64", arm64: "arm64" };
|
|
27
|
+
const arch = archMap[os.arch()];
|
|
28
|
+
if (!arch) return null;
|
|
29
|
+
|
|
30
|
+
const pkgName = `@straylight-ai/bin-${platform}-${arch}`;
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
const pkgJsonPath = require.resolve(`${pkgName}/package.json`);
|
|
34
|
+
const binPath = path.join(path.dirname(pkgJsonPath), BIN_NAME);
|
|
35
|
+
return binPath;
|
|
36
|
+
} catch {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function execBinary(binPath, args) {
|
|
42
|
+
const child = spawn(binPath, args, { stdio: "inherit" });
|
|
43
|
+
child.on("error", (err) => {
|
|
44
|
+
console.error(`Failed to launch ${binPath}: ${err.message}`);
|
|
45
|
+
process.exit(1);
|
|
46
|
+
});
|
|
47
|
+
child.on("exit", (code) => {
|
|
48
|
+
process.exit(code ?? 1);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function execDockerFallback(args) {
|
|
53
|
+
// Check that docker (or podman) is available
|
|
54
|
+
const { execSync } = require("child_process");
|
|
55
|
+
let runtime = null;
|
|
56
|
+
for (const rt of ["docker", "podman"]) {
|
|
57
|
+
try {
|
|
58
|
+
execSync(`${rt} --version`, { stdio: "pipe" });
|
|
59
|
+
runtime = rt;
|
|
60
|
+
break;
|
|
61
|
+
} catch {
|
|
62
|
+
// continue
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (!runtime) {
|
|
67
|
+
console.error(
|
|
68
|
+
"straylight-mcp: no local binary and no container runtime found.\n" +
|
|
69
|
+
"Install Docker: https://docs.docker.com/get-docker/\n" +
|
|
70
|
+
"or run `npx straylight-ai setup` first."
|
|
71
|
+
);
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
execBinary(runtime, ["exec", "-i", CONTAINER_NAME, "straylight-mcp", ...args]);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const localBin = tryLocalBinary();
|
|
79
|
+
const extraArgs = process.argv.slice(2);
|
|
80
|
+
|
|
81
|
+
if (localBin) {
|
|
82
|
+
execBinary(localBin, extraArgs);
|
|
83
|
+
} else {
|
|
84
|
+
execDockerFallback(extraArgs);
|
|
85
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Full bootstrap: pull image if needed, create/start container, wait for
|
|
3
|
+
* health check, register MCP server, and open the browser.
|
|
4
|
+
*
|
|
5
|
+
* This operation is idempotent: calling it when the container is already
|
|
6
|
+
* running will skip the create/start steps and go straight to health + open.
|
|
7
|
+
*/
|
|
8
|
+
export declare function runSetup(): Promise<void>;
|
|
9
|
+
//# sourceMappingURL=setup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":"AAeA;;;;;;GAMG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAiD9C"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runSetup = runSetup;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
const docker_js_1 = require("../docker.js");
|
|
6
|
+
const health_js_1 = require("../health.js");
|
|
7
|
+
const mcp_register_js_1 = require("../mcp-register.js");
|
|
8
|
+
const open_js_1 = require("../open.js");
|
|
9
|
+
const HEALTH_URL = "http://localhost:9470/api/v1/health";
|
|
10
|
+
const HEALTH_TIMEOUT_MS = 30_000;
|
|
11
|
+
const UI_URL = "http://localhost:9470";
|
|
12
|
+
/**
|
|
13
|
+
* Full bootstrap: pull image if needed, create/start container, wait for
|
|
14
|
+
* health check, register MCP server, and open the browser.
|
|
15
|
+
*
|
|
16
|
+
* This operation is idempotent: calling it when the container is already
|
|
17
|
+
* running will skip the create/start steps and go straight to health + open.
|
|
18
|
+
*/
|
|
19
|
+
async function runSetup() {
|
|
20
|
+
const runtime = (0, docker_js_1.detectRuntime)();
|
|
21
|
+
if (!runtime) {
|
|
22
|
+
throw new Error("Neither Docker nor Podman was found on your PATH.\n" +
|
|
23
|
+
"Install Docker Desktop: https://docs.docker.com/get-docker/\n" +
|
|
24
|
+
"or Podman: https://podman.io/getting-started/installation");
|
|
25
|
+
}
|
|
26
|
+
console.log(`Using container runtime: ${runtime}`);
|
|
27
|
+
const status = await (0, docker_js_1.getContainerStatus)(runtime);
|
|
28
|
+
if (status === "not_found") {
|
|
29
|
+
console.log("Creating and starting Straylight-AI container...");
|
|
30
|
+
(0, child_process_1.execSync)((0, docker_js_1.buildRunCommand)(runtime), { stdio: "inherit" });
|
|
31
|
+
}
|
|
32
|
+
else if (status === "stopped") {
|
|
33
|
+
console.log("Starting existing Straylight-AI container...");
|
|
34
|
+
(0, child_process_1.execSync)((0, docker_js_1.buildStartCommand)(runtime), { stdio: "inherit" });
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
console.log("Straylight-AI container is already running.");
|
|
38
|
+
}
|
|
39
|
+
console.log("Waiting for Straylight-AI to be ready...");
|
|
40
|
+
await (0, health_js_1.waitForHealth)(HEALTH_URL, HEALTH_TIMEOUT_MS);
|
|
41
|
+
console.log("Straylight-AI is ready.");
|
|
42
|
+
const registered = await (0, mcp_register_js_1.registerMCP)();
|
|
43
|
+
if (registered) {
|
|
44
|
+
console.log("MCP server registered with Claude Code.");
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
console.log((0, mcp_register_js_1.manualRegistrationInstructions)());
|
|
48
|
+
}
|
|
49
|
+
await (0, open_js_1.openBrowser)(UI_URL);
|
|
50
|
+
console.log([
|
|
51
|
+
"",
|
|
52
|
+
"Straylight-AI is running at http://localhost:9470",
|
|
53
|
+
"",
|
|
54
|
+
"Next steps:",
|
|
55
|
+
" 1. Open http://localhost:9470 in your browser",
|
|
56
|
+
" 2. Add your service credentials via the Web UI",
|
|
57
|
+
" 3. Use Claude Code with the straylight-ai MCP server",
|
|
58
|
+
"",
|
|
59
|
+
].join("\n"));
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":";;AAsBA,4BAiDC;AAvED,iDAAyC;AACzC,4CAKsB;AACtB,4CAA6C;AAC7C,wDAAiF;AACjF,wCAAyC;AAEzC,MAAM,UAAU,GAAG,qCAAqC,CAAC;AACzD,MAAM,iBAAiB,GAAG,MAAM,CAAC;AACjC,MAAM,MAAM,GAAG,uBAAuB,CAAC;AAEvC;;;;;;GAMG;AACI,KAAK,UAAU,QAAQ;IAC5B,MAAM,OAAO,GAAG,IAAA,yBAAa,GAAE,CAAC;IAChC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,qDAAqD;YACnD,+DAA+D;YAC/D,2DAA2D,CAC9D,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,4BAA4B,OAAO,EAAE,CAAC,CAAC;IAEnD,MAAM,MAAM,GAAG,MAAM,IAAA,8BAAkB,EAAC,OAAO,CAAC,CAAC;IAEjD,IAAI,MAAM,KAAK,WAAW,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;QAChE,IAAA,wBAAQ,EAAC,IAAA,2BAAe,EAAC,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IAC3D,CAAC;SAAM,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;QAC5D,IAAA,wBAAQ,EAAC,IAAA,6BAAiB,EAAC,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IAC7D,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;IAC7D,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;IACxD,MAAM,IAAA,yBAAa,EAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC;IACnD,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IAEvC,MAAM,UAAU,GAAG,MAAM,IAAA,6BAAW,GAAE,CAAC;IACvC,IAAI,UAAU,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;IACzD,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,IAAA,gDAA8B,GAAE,CAAC,CAAC;IAChD,CAAC;IAED,MAAM,IAAA,qBAAW,EAAC,MAAM,CAAC,CAAC;IAE1B,OAAO,CAAC,GAAG,CACT;QACE,EAAE;QACF,mDAAmD;QACnD,EAAE;QACF,aAAa;QACb,iDAAiD;QACjD,kDAAkD;QAClD,wDAAwD;QACxD,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"AAWA;;;GAGG;AACH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CA4B9C"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runStart = runStart;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
const docker_js_1 = require("../docker.js");
|
|
6
|
+
const health_js_1 = require("../health.js");
|
|
7
|
+
const HEALTH_URL = "http://localhost:9470/api/v1/health";
|
|
8
|
+
const HEALTH_TIMEOUT_MS = 30_000;
|
|
9
|
+
/**
|
|
10
|
+
* Start an existing stopped container and wait for health.
|
|
11
|
+
* Errors if the container does not exist (use `setup` instead).
|
|
12
|
+
*/
|
|
13
|
+
async function runStart() {
|
|
14
|
+
const runtime = (0, docker_js_1.detectRuntime)();
|
|
15
|
+
if (!runtime) {
|
|
16
|
+
throw new Error("Neither Docker nor Podman was found on your PATH.\n" +
|
|
17
|
+
"Install Docker Desktop: https://docs.docker.com/get-docker/");
|
|
18
|
+
}
|
|
19
|
+
const status = await (0, docker_js_1.getContainerStatus)(runtime);
|
|
20
|
+
if (status === "not_found") {
|
|
21
|
+
throw new Error("Straylight-AI container not found. Run `npx straylight-ai setup` first.");
|
|
22
|
+
}
|
|
23
|
+
if (status === "running") {
|
|
24
|
+
console.log("Straylight-AI is already running.");
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
console.log("Starting Straylight-AI...");
|
|
28
|
+
(0, child_process_1.execSync)((0, docker_js_1.buildStartCommand)(runtime), { stdio: "inherit" });
|
|
29
|
+
console.log("Waiting for Straylight-AI to be ready...");
|
|
30
|
+
await (0, health_js_1.waitForHealth)(HEALTH_URL, HEALTH_TIMEOUT_MS);
|
|
31
|
+
console.log("Straylight-AI is ready at http://localhost:9470");
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=start.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":";;AAeA,4BA4BC;AA3CD,iDAAyC;AACzC,4CAIsB;AACtB,4CAA6C;AAE7C,MAAM,UAAU,GAAG,qCAAqC,CAAC;AACzD,MAAM,iBAAiB,GAAG,MAAM,CAAC;AAEjC;;;GAGG;AACI,KAAK,UAAU,QAAQ;IAC5B,MAAM,OAAO,GAAG,IAAA,yBAAa,GAAE,CAAC;IAChC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,qDAAqD;YACnD,6DAA6D,CAChE,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,IAAA,8BAAkB,EAAC,OAAO,CAAC,CAAC;IAEjD,IAAI,MAAM,KAAK,WAAW,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CACb,yEAAyE,CAC1E,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;QACjD,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;IACzC,IAAA,wBAAQ,EAAC,IAAA,6BAAiB,EAAC,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IAE3D,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;IACxD,MAAM,IAAA,yBAAa,EAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC;IACnD,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;AACjE,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { HealthResponse } from "../health.js";
|
|
2
|
+
/** Result returned by runStatus */
|
|
3
|
+
export interface StatusResult {
|
|
4
|
+
containerStatus: "running" | "stopped" | "not_found";
|
|
5
|
+
health?: HealthResponse;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Check the container status and, if running, fetch and display health info.
|
|
9
|
+
*/
|
|
10
|
+
export declare function runStatus(): Promise<StatusResult>;
|
|
11
|
+
//# sourceMappingURL=status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,cAAc,EAAE,MAAM,cAAc,CAAC;AAI3D,mCAAmC;AACnC,MAAM,WAAW,YAAY;IAC3B,eAAe,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,CAAC;IACrD,MAAM,CAAC,EAAE,cAAc,CAAC;CACzB;AAED;;GAEG;AACH,wBAAsB,SAAS,IAAI,OAAO,CAAC,YAAY,CAAC,CAoCvD"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runStatus = runStatus;
|
|
4
|
+
const docker_js_1 = require("../docker.js");
|
|
5
|
+
const health_js_1 = require("../health.js");
|
|
6
|
+
const HEALTH_URL = "http://localhost:9470/api/v1/health";
|
|
7
|
+
/**
|
|
8
|
+
* Check the container status and, if running, fetch and display health info.
|
|
9
|
+
*/
|
|
10
|
+
async function runStatus() {
|
|
11
|
+
const runtime = (0, docker_js_1.detectRuntime)();
|
|
12
|
+
if (!runtime) {
|
|
13
|
+
throw new Error("Neither Docker nor Podman was found on your PATH.\n" +
|
|
14
|
+
"Install Docker Desktop: https://docs.docker.com/get-docker/");
|
|
15
|
+
}
|
|
16
|
+
const containerStatus = await (0, docker_js_1.getContainerStatus)(runtime);
|
|
17
|
+
const result = { containerStatus };
|
|
18
|
+
if (containerStatus === "running") {
|
|
19
|
+
try {
|
|
20
|
+
result.health = await (0, health_js_1.checkHealth)(HEALTH_URL);
|
|
21
|
+
console.log("Straylight-AI is running.");
|
|
22
|
+
console.log(` Status: ${result.health.status}`);
|
|
23
|
+
if (result.health.version) {
|
|
24
|
+
console.log(` Version: ${result.health.version}`);
|
|
25
|
+
}
|
|
26
|
+
console.log(" URL: http://localhost:9470");
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
console.log("Straylight-AI container is running but not yet healthy.");
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
else if (containerStatus === "stopped") {
|
|
33
|
+
console.log('Straylight-AI container is stopped. Run `npx straylight-ai start` to start it.');
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
console.log('Straylight-AI is not installed. Run `npx straylight-ai setup` to get started.');
|
|
37
|
+
}
|
|
38
|
+
return result;
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":";;AAcA,8BAoCC;AAlDD,4CAAiE;AACjE,4CAA2D;AAE3D,MAAM,UAAU,GAAG,qCAAqC,CAAC;AAQzD;;GAEG;AACI,KAAK,UAAU,SAAS;IAC7B,MAAM,OAAO,GAAG,IAAA,yBAAa,GAAE,CAAC;IAChC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,qDAAqD;YACnD,6DAA6D,CAChE,CAAC;IACJ,CAAC;IAED,MAAM,eAAe,GAAG,MAAM,IAAA,8BAAkB,EAAC,OAAO,CAAC,CAAC;IAE1D,MAAM,MAAM,GAAiB,EAAE,eAAe,EAAE,CAAC;IAEjD,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;QAClC,IAAI,CAAC;YACH,MAAM,CAAC,MAAM,GAAG,MAAM,IAAA,uBAAW,EAAC,UAAU,CAAC,CAAC;YAC9C,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;YACzC,OAAO,CAAC,GAAG,CAAC,aAAa,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;YACjD,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBAC1B,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;YACrD,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;QAC9C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;SAAM,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;QACzC,OAAO,CAAC,GAAG,CACT,gFAAgF,CACjF,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CACT,+EAA+E,CAChF,CAAC;IACJ,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stop.d.ts","sourceRoot":"","sources":["../../src/commands/stop.ts"],"names":[],"mappings":"AAOA;;;GAGG;AACH,wBAAsB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAmB7C"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runStop = runStop;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
const docker_js_1 = require("../docker.js");
|
|
6
|
+
/**
|
|
7
|
+
* Stop the running Straylight-AI container.
|
|
8
|
+
* No-op if the container is not currently running.
|
|
9
|
+
*/
|
|
10
|
+
async function runStop() {
|
|
11
|
+
const runtime = (0, docker_js_1.detectRuntime)();
|
|
12
|
+
if (!runtime) {
|
|
13
|
+
throw new Error("Neither Docker nor Podman was found on your PATH.\n" +
|
|
14
|
+
"Install Docker Desktop: https://docs.docker.com/get-docker/");
|
|
15
|
+
}
|
|
16
|
+
const running = await (0, docker_js_1.isContainerRunning)(runtime);
|
|
17
|
+
if (!running) {
|
|
18
|
+
console.log("Straylight-AI is not currently running.");
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
console.log("Stopping Straylight-AI...");
|
|
22
|
+
(0, child_process_1.execSync)((0, docker_js_1.buildStopCommand)(runtime), { stdio: "inherit" });
|
|
23
|
+
console.log("Straylight-AI stopped.");
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=stop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stop.js","sourceRoot":"","sources":["../../src/commands/stop.ts"],"names":[],"mappings":";;AAWA,0BAmBC;AA9BD,iDAAyC;AACzC,4CAIsB;AAEtB;;;GAGG;AACI,KAAK,UAAU,OAAO;IAC3B,MAAM,OAAO,GAAG,IAAA,yBAAa,GAAE,CAAC;IAChC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,qDAAqD;YACnD,6DAA6D,CAChE,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,IAAA,8BAAkB,EAAC,OAAO,CAAC,CAAC;IAElD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;QACvD,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;IACzC,IAAA,wBAAQ,EAAC,IAAA,4BAAgB,EAAC,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;IAC1D,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;AACxC,CAAC"}
|
package/dist/docker.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/** Name of the managed container */
|
|
2
|
+
export declare const CONTAINER_NAME = "straylight-ai";
|
|
3
|
+
/** Docker image to pull and run */
|
|
4
|
+
export declare const CONTAINER_IMAGE = "ghcr.io/aj-geddes/straylight-ai:latest";
|
|
5
|
+
/** Host port mapped to container port 9470 */
|
|
6
|
+
export declare const CONTAINER_PORT = 9470;
|
|
7
|
+
/** Host data directory mounted at /data inside the container */
|
|
8
|
+
export declare const DATA_DIR: string;
|
|
9
|
+
/** Container status values */
|
|
10
|
+
export type ContainerStatus = "running" | "stopped" | "not_found";
|
|
11
|
+
/** Supported container runtimes */
|
|
12
|
+
export type Runtime = "docker" | "podman";
|
|
13
|
+
/**
|
|
14
|
+
* Detect whether docker or podman is available on the host.
|
|
15
|
+
* Returns the first available runtime, or null if neither is found.
|
|
16
|
+
*/
|
|
17
|
+
export declare function detectRuntime(): Runtime | null;
|
|
18
|
+
/**
|
|
19
|
+
* Get the status of the straylight-ai container.
|
|
20
|
+
*/
|
|
21
|
+
export declare function getContainerStatus(runtime: string): Promise<ContainerStatus>;
|
|
22
|
+
/**
|
|
23
|
+
* Returns true when the container is currently running.
|
|
24
|
+
*/
|
|
25
|
+
export declare function isContainerRunning(runtime: string): Promise<boolean>;
|
|
26
|
+
/**
|
|
27
|
+
* Build the docker/podman run command string.
|
|
28
|
+
*/
|
|
29
|
+
export declare function buildRunCommand(runtime: string): string;
|
|
30
|
+
/**
|
|
31
|
+
* Build the docker/podman start command string.
|
|
32
|
+
*/
|
|
33
|
+
export declare function buildStartCommand(runtime: string): string;
|
|
34
|
+
/**
|
|
35
|
+
* Build the docker/podman stop command string.
|
|
36
|
+
*/
|
|
37
|
+
export declare function buildStopCommand(runtime: string): string;
|
|
38
|
+
/**
|
|
39
|
+
* Pull the container image.
|
|
40
|
+
*/
|
|
41
|
+
export declare function pullImage(runtime: string): void;
|
|
42
|
+
//# sourceMappingURL=docker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docker.d.ts","sourceRoot":"","sources":["../src/docker.ts"],"names":[],"mappings":"AAIA,oCAAoC;AACpC,eAAO,MAAM,cAAc,kBAAkB,CAAC;AAE9C,mCAAmC;AACnC,eAAO,MAAM,eAAe,2CAA2C,CAAC;AAExE,8CAA8C;AAC9C,eAAO,MAAM,cAAc,OAAO,CAAC;AAEnC,gEAAgE;AAChE,eAAO,MAAM,QAAQ,QAAoD,CAAC;AAE1E,8BAA8B;AAC9B,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,CAAC;AAElE,mCAAmC;AACnC,MAAM,MAAM,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAE1C;;;GAGG;AACH,wBAAgB,aAAa,IAAI,OAAO,GAAG,IAAI,CAU9C;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,eAAe,CAAC,CAe1B;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAE1E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAUvD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE/C"}
|
package/dist/docker.js
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.DATA_DIR = exports.CONTAINER_PORT = exports.CONTAINER_IMAGE = exports.CONTAINER_NAME = void 0;
|
|
37
|
+
exports.detectRuntime = detectRuntime;
|
|
38
|
+
exports.getContainerStatus = getContainerStatus;
|
|
39
|
+
exports.isContainerRunning = isContainerRunning;
|
|
40
|
+
exports.buildRunCommand = buildRunCommand;
|
|
41
|
+
exports.buildStartCommand = buildStartCommand;
|
|
42
|
+
exports.buildStopCommand = buildStopCommand;
|
|
43
|
+
exports.pullImage = pullImage;
|
|
44
|
+
const child_process_1 = require("child_process");
|
|
45
|
+
const os = __importStar(require("os"));
|
|
46
|
+
const path = __importStar(require("path"));
|
|
47
|
+
/** Name of the managed container */
|
|
48
|
+
exports.CONTAINER_NAME = "straylight-ai";
|
|
49
|
+
/** Docker image to pull and run */
|
|
50
|
+
exports.CONTAINER_IMAGE = "ghcr.io/aj-geddes/straylight-ai:latest";
|
|
51
|
+
/** Host port mapped to container port 9470 */
|
|
52
|
+
exports.CONTAINER_PORT = 9470;
|
|
53
|
+
/** Host data directory mounted at /data inside the container */
|
|
54
|
+
exports.DATA_DIR = path.join(os.homedir(), ".straylight-ai", "data");
|
|
55
|
+
/**
|
|
56
|
+
* Detect whether docker or podman is available on the host.
|
|
57
|
+
* Returns the first available runtime, or null if neither is found.
|
|
58
|
+
*/
|
|
59
|
+
function detectRuntime() {
|
|
60
|
+
for (const runtime of ["docker", "podman"]) {
|
|
61
|
+
try {
|
|
62
|
+
(0, child_process_1.execSync)(`${runtime} --version`, { stdio: "pipe" });
|
|
63
|
+
return runtime;
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// try the next one
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Get the status of the straylight-ai container.
|
|
73
|
+
*/
|
|
74
|
+
async function getContainerStatus(runtime) {
|
|
75
|
+
try {
|
|
76
|
+
const output = (0, child_process_1.execSync)(`${runtime} inspect --format "{{.State.Status}}" ${exports.CONTAINER_NAME}`, { stdio: "pipe" })
|
|
77
|
+
.toString()
|
|
78
|
+
.trim()
|
|
79
|
+
.replace(/^"|"$/g, ""); // strip surrounding quotes if present
|
|
80
|
+
if (output === "running")
|
|
81
|
+
return "running";
|
|
82
|
+
return "stopped";
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
return "not_found";
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Returns true when the container is currently running.
|
|
90
|
+
*/
|
|
91
|
+
async function isContainerRunning(runtime) {
|
|
92
|
+
return (await getContainerStatus(runtime)) === "running";
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Build the docker/podman run command string.
|
|
96
|
+
*/
|
|
97
|
+
function buildRunCommand(runtime) {
|
|
98
|
+
return [
|
|
99
|
+
`${runtime} run`,
|
|
100
|
+
"-d",
|
|
101
|
+
`--name ${exports.CONTAINER_NAME}`,
|
|
102
|
+
`-p ${exports.CONTAINER_PORT}:${exports.CONTAINER_PORT}`,
|
|
103
|
+
`-v ${exports.DATA_DIR}:/data`,
|
|
104
|
+
"--restart unless-stopped",
|
|
105
|
+
exports.CONTAINER_IMAGE,
|
|
106
|
+
].join(" ");
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Build the docker/podman start command string.
|
|
110
|
+
*/
|
|
111
|
+
function buildStartCommand(runtime) {
|
|
112
|
+
return `${runtime} start ${exports.CONTAINER_NAME}`;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Build the docker/podman stop command string.
|
|
116
|
+
*/
|
|
117
|
+
function buildStopCommand(runtime) {
|
|
118
|
+
return `${runtime} stop ${exports.CONTAINER_NAME}`;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Pull the container image.
|
|
122
|
+
*/
|
|
123
|
+
function pullImage(runtime) {
|
|
124
|
+
(0, child_process_1.execSync)(`${runtime} pull ${exports.CONTAINER_IMAGE}`, { stdio: "inherit" });
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=docker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docker.js","sourceRoot":"","sources":["../src/docker.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,sCAUC;AAKD,gDAiBC;AAKD,gDAEC;AAKD,0CAUC;AAKD,8CAEC;AAKD,4CAEC;AAKD,8BAEC;AArGD,iDAAyC;AACzC,uCAAyB;AACzB,2CAA6B;AAE7B,oCAAoC;AACvB,QAAA,cAAc,GAAG,eAAe,CAAC;AAE9C,mCAAmC;AACtB,QAAA,eAAe,GAAG,wCAAwC,CAAC;AAExE,8CAA8C;AACjC,QAAA,cAAc,GAAG,IAAI,CAAC;AAEnC,gEAAgE;AACnD,QAAA,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,gBAAgB,EAAE,MAAM,CAAC,CAAC;AAQ1E;;;GAGG;AACH,SAAgB,aAAa;IAC3B,KAAK,MAAM,OAAO,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAc,EAAE,CAAC;QACxD,IAAI,CAAC;YACH,IAAA,wBAAQ,EAAC,GAAG,OAAO,YAAY,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;YACpD,OAAO,OAAO,CAAC;QACjB,CAAC;QAAC,MAAM,CAAC;YACP,mBAAmB;QACrB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,kBAAkB,CACtC,OAAe;IAEf,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAA,wBAAQ,EACrB,GAAG,OAAO,yCAAyC,sBAAc,EAAE,EACnE,EAAE,KAAK,EAAE,MAAM,EAAE,CAClB;aACE,QAAQ,EAAE;aACV,IAAI,EAAE;aACN,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,sCAAsC;QAEhE,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO,SAAS,CAAC;QAC3C,OAAO,SAAS,CAAC;IACnB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,WAAW,CAAC;IACrB,CAAC;AACH,CAAC;AAED;;GAEG;AACI,KAAK,UAAU,kBAAkB,CAAC,OAAe;IACtD,OAAO,CAAC,MAAM,kBAAkB,CAAC,OAAO,CAAC,CAAC,KAAK,SAAS,CAAC;AAC3D,CAAC;AAED;;GAEG;AACH,SAAgB,eAAe,CAAC,OAAe;IAC7C,OAAO;QACL,GAAG,OAAO,MAAM;QAChB,IAAI;QACJ,UAAU,sBAAc,EAAE;QAC1B,MAAM,sBAAc,IAAI,sBAAc,EAAE;QACxC,MAAM,gBAAQ,QAAQ;QACtB,0BAA0B;QAC1B,uBAAe;KAChB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACd,CAAC;AAED;;GAEG;AACH,SAAgB,iBAAiB,CAAC,OAAe;IAC/C,OAAO,GAAG,OAAO,UAAU,sBAAc,EAAE,CAAC;AAC9C,CAAC;AAED;;GAEG;AACH,SAAgB,gBAAgB,CAAC,OAAe;IAC9C,OAAO,GAAG,OAAO,SAAS,sBAAc,EAAE,CAAC;AAC7C,CAAC;AAED;;GAEG;AACH,SAAgB,SAAS,CAAC,OAAe;IACvC,IAAA,wBAAQ,EAAC,GAAG,OAAO,SAAS,uBAAe,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;AACvE,CAAC"}
|
package/dist/health.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** Response shape from the health endpoint */
|
|
2
|
+
export interface HealthResponse {
|
|
3
|
+
status: string;
|
|
4
|
+
version?: string;
|
|
5
|
+
[key: string]: unknown;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Perform a single health check against the given URL.
|
|
9
|
+
* Throws if the endpoint is unreachable or returns a non-ok HTTP status.
|
|
10
|
+
*/
|
|
11
|
+
export declare function checkHealth(url: string): Promise<HealthResponse>;
|
|
12
|
+
/**
|
|
13
|
+
* Poll the health endpoint until it returns a successful response or the
|
|
14
|
+
* timeout elapses.
|
|
15
|
+
*
|
|
16
|
+
* @param url Full URL of the health endpoint.
|
|
17
|
+
* @param timeoutMs Maximum time to wait in milliseconds.
|
|
18
|
+
* @returns The first successful HealthResponse.
|
|
19
|
+
* @throws Error when the timeout is reached without a successful response.
|
|
20
|
+
*/
|
|
21
|
+
export declare function waitForHealth(url: string, timeoutMs: number): Promise<HealthResponse>;
|
|
22
|
+
//# sourceMappingURL=health.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../src/health.ts"],"names":[],"mappings":"AAAA,8CAA8C;AAC9C,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAKD;;;GAGG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAMtE;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,cAAc,CAAC,CAgBzB"}
|
package/dist/health.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.checkHealth = checkHealth;
|
|
4
|
+
exports.waitForHealth = waitForHealth;
|
|
5
|
+
/** Interval between health-check attempts in milliseconds */
|
|
6
|
+
const POLL_INTERVAL_MS = 1_000;
|
|
7
|
+
/**
|
|
8
|
+
* Perform a single health check against the given URL.
|
|
9
|
+
* Throws if the endpoint is unreachable or returns a non-ok HTTP status.
|
|
10
|
+
*/
|
|
11
|
+
async function checkHealth(url) {
|
|
12
|
+
const response = await fetch(url);
|
|
13
|
+
if (!response.ok) {
|
|
14
|
+
throw new Error(`Health check failed with HTTP ${response.status}`);
|
|
15
|
+
}
|
|
16
|
+
return (await response.json());
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Poll the health endpoint until it returns a successful response or the
|
|
20
|
+
* timeout elapses.
|
|
21
|
+
*
|
|
22
|
+
* @param url Full URL of the health endpoint.
|
|
23
|
+
* @param timeoutMs Maximum time to wait in milliseconds.
|
|
24
|
+
* @returns The first successful HealthResponse.
|
|
25
|
+
* @throws Error when the timeout is reached without a successful response.
|
|
26
|
+
*/
|
|
27
|
+
async function waitForHealth(url, timeoutMs) {
|
|
28
|
+
const deadline = Date.now() + timeoutMs;
|
|
29
|
+
while (Date.now() < deadline) {
|
|
30
|
+
try {
|
|
31
|
+
return await checkHealth(url);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
// Not ready yet — wait before retrying
|
|
35
|
+
await sleep(POLL_INTERVAL_MS);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
throw new Error(`Health check timed out after ${timeoutMs}ms. ` +
|
|
39
|
+
`Is the container running at ${url}?`);
|
|
40
|
+
}
|
|
41
|
+
function sleep(ms) {
|
|
42
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=health.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"health.js","sourceRoot":"","sources":["../src/health.ts"],"names":[],"mappings":";;AAcA,kCAMC;AAWD,sCAmBC;AA3CD,6DAA6D;AAC7D,MAAM,gBAAgB,GAAG,KAAK,CAAC;AAE/B;;;GAGG;AACI,KAAK,UAAU,WAAW,CAAC,GAAW;IAC3C,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,iCAAiC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAmB,CAAC;AACnD,CAAC;AAED;;;;;;;;GAQG;AACI,KAAK,UAAU,aAAa,CACjC,GAAW,EACX,SAAiB;IAEjB,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;IAExC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,OAAO,MAAM,WAAW,CAAC,GAAG,CAAC,CAAC;QAChC,CAAC;QAAC,MAAM,CAAC;YACP,uCAAuC;YACvC,MAAM,KAAK,CAAC,gBAAgB,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CACb,gCAAgC,SAAS,MAAM;QAC7C,+BAA+B,GAAG,GAAG,CACxC,CAAC;AACJ,CAAC;AAED,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check whether the Claude Code CLI is available on PATH.
|
|
3
|
+
*/
|
|
4
|
+
export declare function isClaudeAvailable(): boolean;
|
|
5
|
+
/**
|
|
6
|
+
* Register the Straylight-AI MCP server with Claude Code.
|
|
7
|
+
*
|
|
8
|
+
* Runs:
|
|
9
|
+
* claude mcp add straylight-ai --transport stdio -- npx straylight-ai mcp
|
|
10
|
+
*
|
|
11
|
+
* @returns true on success, false if claude is unavailable or the command fails.
|
|
12
|
+
*/
|
|
13
|
+
export declare function registerMCP(): Promise<boolean>;
|
|
14
|
+
/**
|
|
15
|
+
* Build the manual registration instructions string for users who do not have
|
|
16
|
+
* Claude Code installed.
|
|
17
|
+
*/
|
|
18
|
+
export declare function manualRegistrationInstructions(): string;
|
|
19
|
+
//# sourceMappingURL=mcp-register.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-register.d.ts","sourceRoot":"","sources":["../src/mcp-register.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,OAAO,CAO3C;AAED;;;;;;;GAOG;AACH,wBAAsB,WAAW,IAAI,OAAO,CAAC,OAAO,CAAC,CAsBpD;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,IAAI,MAAM,CAQvD"}
|