@clawops/cli 1.2.1 → 1.3.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/README.md +1 -1
- package/dist/{apply-KBF7OPWL.js → apply-DLNE2JYZ.js} +4 -3
- package/dist/{bootstrap-UYCOEJQX.js → bootstrap-G4UZ2FKH.js} +3 -3
- package/dist/chunk-6ZFIFDBJ.js +41 -0
- package/dist/{chunk-BRPU7AQC.js → chunk-A2I76FTA.js} +13 -1
- package/dist/{chunk-LU63NZD3.js → chunk-JCUZU5BH.js} +5 -1
- package/dist/{chunk-ACYJBSLJ.js → chunk-JDN6PLH2.js} +1 -1
- package/dist/{chunk-QJ6ERXHN.js → chunk-LVIIYY27.js} +1 -1
- package/dist/{chunk-SSB6SGPQ.js → chunk-ZDPBBYYV.js} +2 -2
- package/dist/cli.js +328 -51
- package/dist/{context-VUAYRAJY.js → context-M2RMDHX6.js} +2 -2
- package/dist/{generate-PZPLG3ZM.js → generate-U7PJ5LRG.js} +3 -3
- package/dist/overlay-store-ADZPD7EU.js +11 -0
- package/dist/{package-SE3M4NJA.js → package-AFUTH62F.js} +1 -1
- package/dist/{server-4DNHLGEG.js → server-I62UES5V.js} +11 -10
- package/dist/state-PRBIIN7I.js +17 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# clawops
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
MCP-native infrastructure ops for OpenClaw — with read-only mode, destructive-action confirmation, and audit logs built in.
|
|
4
4
|
|
|
5
5
|
**clawops** is a CLI and [MCP](https://modelcontextprotocol.io/) server for deploying and operating
|
|
6
6
|
self-hosted [OpenClaw](https://github.com/openclaw/openclaw) instances. Provision on AWS, GCP,
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
applyPlan
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-JCUZU5BH.js";
|
|
5
5
|
import "./chunk-YTH4L2GN.js";
|
|
6
|
+
import "./chunk-6ZFIFDBJ.js";
|
|
6
7
|
import "./chunk-BOPSG2LI.js";
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-BRPU7AQC.js";
|
|
8
|
+
import "./chunk-JDN6PLH2.js";
|
|
9
9
|
import "./chunk-UDNZUSKA.js";
|
|
10
|
+
import "./chunk-A2I76FTA.js";
|
|
10
11
|
import "./chunk-CX5SL5HP.js";
|
|
11
12
|
import "./chunk-KGXPLI7W.js";
|
|
12
13
|
export {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
writeLocalState
|
|
4
|
-
} from "./chunk-BRPU7AQC.js";
|
|
5
2
|
import {
|
|
6
3
|
acquireSession
|
|
7
4
|
} from "./chunk-ZVOEQCNW.js";
|
|
8
5
|
import "./chunk-4U3LTLWZ.js";
|
|
6
|
+
import {
|
|
7
|
+
writeLocalState
|
|
8
|
+
} from "./chunk-A2I76FTA.js";
|
|
9
9
|
import "./chunk-CX5SL5HP.js";
|
|
10
10
|
import {
|
|
11
11
|
ProviderError
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/plan/overlay-store.ts
|
|
4
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync } from "fs";
|
|
5
|
+
import path from "path";
|
|
6
|
+
import os from "os";
|
|
7
|
+
function overlayPath(stackName) {
|
|
8
|
+
return path.join(os.homedir(), ".clawops", "overlays", `${stackName}.json`);
|
|
9
|
+
}
|
|
10
|
+
function saveOverlay(stackName, overlay, secrets) {
|
|
11
|
+
const dir = path.join(os.homedir(), ".clawops", "overlays");
|
|
12
|
+
mkdirSync(dir, { recursive: true });
|
|
13
|
+
const data = { stackName, savedAt: (/* @__PURE__ */ new Date()).toISOString(), overlay, secrets };
|
|
14
|
+
writeFileSync(overlayPath(stackName), JSON.stringify(data, null, 2) + "\n", "utf-8");
|
|
15
|
+
}
|
|
16
|
+
function loadOverlay(stackName) {
|
|
17
|
+
const p = overlayPath(stackName);
|
|
18
|
+
if (!existsSync(p)) return null;
|
|
19
|
+
try {
|
|
20
|
+
return JSON.parse(readFileSync(p, "utf-8"));
|
|
21
|
+
} catch {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function listOverlays() {
|
|
26
|
+
const dir = path.join(os.homedir(), ".clawops", "overlays");
|
|
27
|
+
if (!existsSync(dir)) return [];
|
|
28
|
+
return readdirSync(dir).filter((f) => f.endsWith(".json")).flatMap((f) => {
|
|
29
|
+
try {
|
|
30
|
+
return [JSON.parse(readFileSync(path.join(dir, f), "utf-8"))];
|
|
31
|
+
} catch {
|
|
32
|
+
return [];
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export {
|
|
38
|
+
saveOverlay,
|
|
39
|
+
loadOverlay,
|
|
40
|
+
listOverlays
|
|
41
|
+
};
|
|
@@ -30,8 +30,20 @@ function writeLocalState(stackName, state) {
|
|
|
30
30
|
writeFileSync(tmp, JSON.stringify(state, null, 2) + "\n", "utf-8");
|
|
31
31
|
renameSync(tmp, dest);
|
|
32
32
|
}
|
|
33
|
+
function localStateToConnectionInfo(state) {
|
|
34
|
+
return {
|
|
35
|
+
host: state.sshHost,
|
|
36
|
+
port: state.sshPort,
|
|
37
|
+
user: state.sshUser,
|
|
38
|
+
privateKeyPath: state.privateKeyPath,
|
|
39
|
+
knownHostsPath: state.knownHostsPath
|
|
40
|
+
};
|
|
41
|
+
}
|
|
33
42
|
|
|
34
43
|
export {
|
|
44
|
+
stateDir,
|
|
45
|
+
statePath,
|
|
35
46
|
readLocalState,
|
|
36
|
-
writeLocalState
|
|
47
|
+
writeLocalState,
|
|
48
|
+
localStateToConnectionInfo
|
|
37
49
|
};
|
|
@@ -2,12 +2,15 @@
|
|
|
2
2
|
import {
|
|
3
3
|
validatePlan
|
|
4
4
|
} from "./chunk-YTH4L2GN.js";
|
|
5
|
+
import {
|
|
6
|
+
saveOverlay
|
|
7
|
+
} from "./chunk-6ZFIFDBJ.js";
|
|
5
8
|
import {
|
|
6
9
|
resolveSecrets
|
|
7
10
|
} from "./chunk-BOPSG2LI.js";
|
|
8
11
|
import {
|
|
9
12
|
buildContext
|
|
10
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-JDN6PLH2.js";
|
|
11
14
|
import {
|
|
12
15
|
atomicWriteConfig,
|
|
13
16
|
deepMerge,
|
|
@@ -106,6 +109,7 @@ async function applyConfigOverlay(plan, outputs, ctx, signal) {
|
|
|
106
109
|
});
|
|
107
110
|
await atomicWriteConfig(session, merged, signal);
|
|
108
111
|
await restartGateway(session, signal);
|
|
112
|
+
saveOverlay(plan.spec.stackName, configOverlay, plan.spec.secrets ?? []);
|
|
109
113
|
} finally {
|
|
110
114
|
session.close();
|
|
111
115
|
}
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
} from "./chunk-YTH4L2GN.js";
|
|
5
5
|
import {
|
|
6
6
|
buildContext
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-JDN6PLH2.js";
|
|
8
8
|
import {
|
|
9
9
|
getConfig
|
|
10
10
|
} from "./chunk-CX5SL5HP.js";
|
|
@@ -45,7 +45,7 @@ async function generatePlan(intent, _opts) {
|
|
|
45
45
|
"plan/apply is not supported for the local provider. Use `clawops up` directly."
|
|
46
46
|
);
|
|
47
47
|
}
|
|
48
|
-
const { version } = await import("./package-
|
|
48
|
+
const { version } = await import("./package-AFUTH62F.js");
|
|
49
49
|
const config = getConfig();
|
|
50
50
|
const instanceType = intent.instanceType ?? "small";
|
|
51
51
|
const openclawVersion = intent.openclawVersion ?? "latest";
|
package/dist/cli.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
validateOpenclawConfig
|
|
4
|
-
} from "./chunk-QJ6ERXHN.js";
|
|
5
2
|
import {
|
|
6
3
|
MCP_APPS,
|
|
7
4
|
buildMcpEntry,
|
|
8
5
|
writeAppConfigs
|
|
9
6
|
} from "./chunk-OIGTOLB3.js";
|
|
10
|
-
import
|
|
11
|
-
|
|
7
|
+
import {
|
|
8
|
+
validateOpenclawConfig
|
|
9
|
+
} from "./chunk-LVIIYY27.js";
|
|
10
|
+
import "./chunk-JDN6PLH2.js";
|
|
12
11
|
import "./chunk-ZVOEQCNW.js";
|
|
13
12
|
import "./chunk-4U3LTLWZ.js";
|
|
14
13
|
import "./chunk-UDNZUSKA.js";
|
|
14
|
+
import "./chunk-A2I76FTA.js";
|
|
15
15
|
import {
|
|
16
16
|
getConfig,
|
|
17
17
|
getConfigDir,
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
} from "./chunk-KGXPLI7W.js";
|
|
25
25
|
|
|
26
26
|
// src/cli/index.ts
|
|
27
|
-
import { defineCommand as
|
|
27
|
+
import { defineCommand as defineCommand21, runMain } from "citty";
|
|
28
28
|
|
|
29
29
|
// src/cli/commands/init.ts
|
|
30
30
|
import { defineCommand } from "citty";
|
|
@@ -217,7 +217,7 @@ var up_default = defineCommand2({
|
|
|
217
217
|
config: { type: "string", description: "Path to openclaw config overlay JSON (local provider only)" }
|
|
218
218
|
},
|
|
219
219
|
async run({ args }) {
|
|
220
|
-
const { buildContext } = await import("./context-
|
|
220
|
+
const { buildContext } = await import("./context-M2RMDHX6.js");
|
|
221
221
|
const ctx = buildContext(args);
|
|
222
222
|
const openclawVersion = typeof args["openclaw-version"] === "string" ? args["openclaw-version"] : "stable";
|
|
223
223
|
if (ctx.adapter.name === "local") {
|
|
@@ -228,7 +228,7 @@ var up_default = defineCommand2({
|
|
|
228
228
|
);
|
|
229
229
|
}
|
|
230
230
|
const { localOpts } = stackConfig;
|
|
231
|
-
const { localBootstrap } = await import("./bootstrap-
|
|
231
|
+
const { localBootstrap } = await import("./bootstrap-G4UZ2FKH.js");
|
|
232
232
|
const abortController = new AbortController();
|
|
233
233
|
process3.on("SIGINT", () => abortController.abort());
|
|
234
234
|
process3.on("SIGTERM", () => abortController.abort());
|
|
@@ -363,7 +363,7 @@ var down_default = defineCommand3({
|
|
|
363
363
|
"dry-run": { type: "boolean", description: "Show what would be destroyed without destroying" }
|
|
364
364
|
},
|
|
365
365
|
async run({ args }) {
|
|
366
|
-
const { buildContext } = await import("./context-
|
|
366
|
+
const { buildContext } = await import("./context-M2RMDHX6.js");
|
|
367
367
|
const ctx = buildContext(args);
|
|
368
368
|
if (args["dry-run"]) {
|
|
369
369
|
info(`Dry run \u2014 would destroy stack "${ctx.stackName}"`);
|
|
@@ -427,7 +427,7 @@ var status_default = defineCommand4({
|
|
|
427
427
|
json: { type: "boolean", description: "Emit JSON" }
|
|
428
428
|
},
|
|
429
429
|
async run({ args }) {
|
|
430
|
-
const { buildContext } = await import("./context-
|
|
430
|
+
const { buildContext } = await import("./context-M2RMDHX6.js");
|
|
431
431
|
const ctx = buildContext(args);
|
|
432
432
|
if (ctx.adapter.name === "local") {
|
|
433
433
|
const state = ctx.localState;
|
|
@@ -499,8 +499,8 @@ var plan_default = defineCommand5({
|
|
|
499
499
|
out: { type: "string", description: "Write plan JSON to this absolute path (default: stdout)" }
|
|
500
500
|
},
|
|
501
501
|
async run({ args }) {
|
|
502
|
-
const { buildContext } = await import("./context-
|
|
503
|
-
const { generatePlan } = await import("./generate-
|
|
502
|
+
const { buildContext } = await import("./context-M2RMDHX6.js");
|
|
503
|
+
const { generatePlan } = await import("./generate-U7PJ5LRG.js");
|
|
504
504
|
const ctx = buildContext(args);
|
|
505
505
|
if (ctx.adapter.name === "local") {
|
|
506
506
|
throw new UsageError(
|
|
@@ -590,7 +590,7 @@ var apply_default = defineCommand6({
|
|
|
590
590
|
},
|
|
591
591
|
async run({ args }) {
|
|
592
592
|
const { validatePlan } = await import("./validate-T5M5EHSJ.js");
|
|
593
|
-
const { applyPlan } = await import("./apply-
|
|
593
|
+
const { applyPlan } = await import("./apply-DLNE2JYZ.js");
|
|
594
594
|
const planPath = args._?.[0];
|
|
595
595
|
if (!planPath) {
|
|
596
596
|
throw new UsageError("Usage: clawops apply <plan.json>");
|
|
@@ -706,7 +706,7 @@ var destroy_default = defineCommand7({
|
|
|
706
706
|
"dry-run": { type: "boolean", description: "Show what would be destroyed without destroying" }
|
|
707
707
|
},
|
|
708
708
|
async run({ args }) {
|
|
709
|
-
const { buildContext } = await import("./context-
|
|
709
|
+
const { buildContext } = await import("./context-M2RMDHX6.js");
|
|
710
710
|
const ctx = buildContext(args);
|
|
711
711
|
if (ctx.adapter.name === "local") {
|
|
712
712
|
throw new UsageError(
|
|
@@ -773,7 +773,7 @@ var ssh_default = defineCommand8({
|
|
|
773
773
|
command: { type: "string", description: "Remote command to run (instead of interactive shell)" }
|
|
774
774
|
},
|
|
775
775
|
async run({ args }) {
|
|
776
|
-
const { buildContext } = await import("./context-
|
|
776
|
+
const { buildContext } = await import("./context-M2RMDHX6.js");
|
|
777
777
|
const { acquireSession, drainPool } = await import("./pool-FBFHATDG.js");
|
|
778
778
|
const ctx = buildContext(args);
|
|
779
779
|
let conn;
|
|
@@ -860,7 +860,7 @@ var tunnel_default = defineCommand9({
|
|
|
860
860
|
"no-open": { type: "boolean", description: "Do not open browser after tunnel is ready" }
|
|
861
861
|
},
|
|
862
862
|
async run({ args }) {
|
|
863
|
-
const { buildContext } = await import("./context-
|
|
863
|
+
const { buildContext } = await import("./context-M2RMDHX6.js");
|
|
864
864
|
const { extractBaseOutputs } = await import("./outputs-DJHBY7EE.js");
|
|
865
865
|
const { acquireSession } = await import("./pool-FBFHATDG.js");
|
|
866
866
|
const ctx = buildContext(args);
|
|
@@ -928,7 +928,7 @@ var logs_default = defineCommand10({
|
|
|
928
928
|
since: { type: "string", description: "Show logs since duration (e.g. 5m, 1h)" }
|
|
929
929
|
},
|
|
930
930
|
async run({ args }) {
|
|
931
|
-
const { buildContext } = await import("./context-
|
|
931
|
+
const { buildContext } = await import("./context-M2RMDHX6.js");
|
|
932
932
|
const { extractBaseOutputs } = await import("./outputs-DJHBY7EE.js");
|
|
933
933
|
const { acquireSession, drainPool } = await import("./pool-FBFHATDG.js");
|
|
934
934
|
const ctx = buildContext(args);
|
|
@@ -1045,7 +1045,7 @@ var config_default = defineCommand11({
|
|
|
1045
1045
|
"dry-run": { type: "boolean", description: "Show what would change without writing" }
|
|
1046
1046
|
},
|
|
1047
1047
|
async run({ args }) {
|
|
1048
|
-
const { buildContext } = await import("./context-
|
|
1048
|
+
const { buildContext } = await import("./context-M2RMDHX6.js");
|
|
1049
1049
|
const { extractBaseOutputs } = await import("./outputs-DJHBY7EE.js");
|
|
1050
1050
|
const { acquireSession, drainPool } = await import("./pool-FBFHATDG.js");
|
|
1051
1051
|
const [action, key, value] = args._ ?? [];
|
|
@@ -1171,7 +1171,7 @@ var agents_default = defineCommand12({
|
|
|
1171
1171
|
json: { type: "boolean", description: "Emit JSON (for list)" }
|
|
1172
1172
|
},
|
|
1173
1173
|
async run({ args }) {
|
|
1174
|
-
const { buildContext } = await import("./context-
|
|
1174
|
+
const { buildContext } = await import("./context-M2RMDHX6.js");
|
|
1175
1175
|
const { extractBaseOutputs } = await import("./outputs-DJHBY7EE.js");
|
|
1176
1176
|
const { acquireSession, drainPool } = await import("./pool-FBFHATDG.js");
|
|
1177
1177
|
const [action, name] = args._ ?? [];
|
|
@@ -1275,7 +1275,7 @@ var gateway_default = defineCommand13({
|
|
|
1275
1275
|
json: { type: "boolean", description: "Emit JSON (for status)" }
|
|
1276
1276
|
},
|
|
1277
1277
|
async run({ args }) {
|
|
1278
|
-
const { buildContext } = await import("./context-
|
|
1278
|
+
const { buildContext } = await import("./context-M2RMDHX6.js");
|
|
1279
1279
|
const { extractBaseOutputs } = await import("./outputs-DJHBY7EE.js");
|
|
1280
1280
|
const { acquireSession, drainPool } = await import("./pool-FBFHATDG.js");
|
|
1281
1281
|
const [action, versionArg] = args._ ?? [];
|
|
@@ -1388,7 +1388,7 @@ var backup_default = defineCommand14({
|
|
|
1388
1388
|
yes: { type: "boolean", description: "[restore] Skip confirmation prompt" }
|
|
1389
1389
|
},
|
|
1390
1390
|
async run({ args }) {
|
|
1391
|
-
const { buildContext } = await import("./context-
|
|
1391
|
+
const { buildContext } = await import("./context-M2RMDHX6.js");
|
|
1392
1392
|
const { acquireSession, drainPool } = await import("./pool-FBFHATDG.js");
|
|
1393
1393
|
const action = args.action;
|
|
1394
1394
|
if (action !== "create" && action !== "restore") {
|
|
@@ -1694,7 +1694,7 @@ var doctor_default = defineCommand16({
|
|
|
1694
1694
|
info("Remote health skipped \u2014 no config");
|
|
1695
1695
|
} else {
|
|
1696
1696
|
try {
|
|
1697
|
-
const { buildContext } = await import("./context-
|
|
1697
|
+
const { buildContext } = await import("./context-M2RMDHX6.js");
|
|
1698
1698
|
const { extractBaseOutputs } = await import("./outputs-DJHBY7EE.js");
|
|
1699
1699
|
const { acquireSession, drainPool } = await import("./pool-FBFHATDG.js");
|
|
1700
1700
|
const ctx = buildContext({ stack: args.stack });
|
|
@@ -1802,7 +1802,7 @@ var serveCmd = defineCommand17({
|
|
|
1802
1802
|
inspector: { type: "boolean", description: "Enable MCP inspector" }
|
|
1803
1803
|
},
|
|
1804
1804
|
async run({ args }) {
|
|
1805
|
-
const { serveMcp } = await import("./server-
|
|
1805
|
+
const { serveMcp } = await import("./server-I62UES5V.js");
|
|
1806
1806
|
await serveMcp({
|
|
1807
1807
|
port: args.http ? Number(args.http) : void 0,
|
|
1808
1808
|
bind: args.bind,
|
|
@@ -1876,12 +1876,6 @@ var mcp_default = defineCommand17({
|
|
|
1876
1876
|
subCommands: {
|
|
1877
1877
|
serve: serveCmd,
|
|
1878
1878
|
install: installCmd
|
|
1879
|
-
},
|
|
1880
|
-
run() {
|
|
1881
|
-
process19.stdout.write("Usage: clawops mcp <serve | install>\n\n");
|
|
1882
|
-
process19.stdout.write(" serve Start the MCP server (stdio or HTTP)\n");
|
|
1883
|
-
process19.stdout.write(" install Wire clawops into AI editors interactively\n\n");
|
|
1884
|
-
process19.stdout.write("Run `clawops mcp <command> --help` for flags.\n");
|
|
1885
1879
|
}
|
|
1886
1880
|
});
|
|
1887
1881
|
|
|
@@ -2148,10 +2142,10 @@ var setup_default = defineCommand18({
|
|
|
2148
2142
|
}
|
|
2149
2143
|
}
|
|
2150
2144
|
const gatewayToken = randomBytes(24).toString("hex");
|
|
2151
|
-
const
|
|
2152
|
-
mkdirSync3(
|
|
2153
|
-
spawnSync("chmod", ["700",
|
|
2154
|
-
const tokenPath = path3.join(
|
|
2145
|
+
const secretsDir2 = path3.join(os.homedir(), ".clawops", "secrets");
|
|
2146
|
+
mkdirSync3(secretsDir2, { recursive: true });
|
|
2147
|
+
spawnSync("chmod", ["700", secretsDir2], { stdio: "ignore" });
|
|
2148
|
+
const tokenPath = path3.join(secretsDir2, `GATEWAY_TOKEN_${stackAnswers.stackName}`);
|
|
2155
2149
|
writeFileSync3(tokenPath, gatewayToken, { encoding: "utf-8", mode: 384 });
|
|
2156
2150
|
const openclawConfigOverlay = {
|
|
2157
2151
|
models: builtModelConfig,
|
|
@@ -2309,7 +2303,7 @@ var setup_default = defineCommand18({
|
|
|
2309
2303
|
default: false
|
|
2310
2304
|
}]);
|
|
2311
2305
|
if (applyNow) {
|
|
2312
|
-
const { applyPlan } = await import("./apply-
|
|
2306
|
+
const { applyPlan } = await import("./apply-DLNE2JYZ.js");
|
|
2313
2307
|
const plan = JSON.parse(readFileSync3(outputPath, "utf-8"));
|
|
2314
2308
|
try {
|
|
2315
2309
|
await applyPlan(plan, {
|
|
@@ -2331,7 +2325,7 @@ To deploy later: clawops apply ${outputPath}`);
|
|
|
2331
2325
|
});
|
|
2332
2326
|
async function runLocalDeploy(opts) {
|
|
2333
2327
|
const { setConfig: setConfig2, getConfig: getConfig2, getConfigDir: getConfigDir2 } = await import("./store-SDUR52Z5.js");
|
|
2334
|
-
const { localBootstrap } = await import("./bootstrap-
|
|
2328
|
+
const { localBootstrap } = await import("./bootstrap-G4UZ2FKH.js");
|
|
2335
2329
|
const { connect } = await import("./ssh-IQXNME3D.js");
|
|
2336
2330
|
const { readRemoteConfig, atomicWriteConfig, restartGateway, deepMerge } = await import("./remote-config-JQ77SRC2.js");
|
|
2337
2331
|
const { resolveSecrets } = await import("./secrets-SVZWNAPK.js");
|
|
@@ -2404,6 +2398,8 @@ async function runLocalDeploy(opts) {
|
|
|
2404
2398
|
const merged = deepMerge(remote, resolved);
|
|
2405
2399
|
await atomicWriteConfig(session, merged, opts.signal);
|
|
2406
2400
|
await restartGateway(session, opts.signal);
|
|
2401
|
+
const { saveOverlay } = await import("./overlay-store-ADZPD7EU.js");
|
|
2402
|
+
saveOverlay(opts.stackName, opts.overlay, opts.secrets);
|
|
2407
2403
|
} finally {
|
|
2408
2404
|
session.close();
|
|
2409
2405
|
}
|
|
@@ -2497,7 +2493,7 @@ function cliInstallUrl(provider) {
|
|
|
2497
2493
|
return "https://learn.microsoft.com/en-us/cli/azure/install-azure-cli";
|
|
2498
2494
|
}
|
|
2499
2495
|
async function promptSecret(name, label, envDefault, inquirer) {
|
|
2500
|
-
const
|
|
2496
|
+
const secretsDir2 = path3.join(os.homedir(), ".clawops", "secrets");
|
|
2501
2497
|
const { secretSource } = await inquirer.prompt([{
|
|
2502
2498
|
type: "list",
|
|
2503
2499
|
name: "secretSource",
|
|
@@ -2515,12 +2511,12 @@ async function promptSecret(name, label, envDefault, inquirer) {
|
|
|
2515
2511
|
message: `Paste your ${label}: (input is hidden)`,
|
|
2516
2512
|
validate: (v) => v.trim() !== "" || "Value cannot be empty"
|
|
2517
2513
|
}]);
|
|
2518
|
-
mkdirSync3(
|
|
2519
|
-
spawnSync("chmod", ["700",
|
|
2520
|
-
const
|
|
2521
|
-
writeFileSync3(
|
|
2522
|
-
success(`Secret saved to ${
|
|
2523
|
-
return { name, source: "file", ref:
|
|
2514
|
+
mkdirSync3(secretsDir2, { recursive: true });
|
|
2515
|
+
spawnSync("chmod", ["700", secretsDir2], { stdio: "ignore" });
|
|
2516
|
+
const secretPath2 = path3.join(secretsDir2, name);
|
|
2517
|
+
writeFileSync3(secretPath2, secretValue.trim(), { encoding: "utf-8", mode: 384 });
|
|
2518
|
+
success(`Secret saved to ${secretPath2} (chmod 600)`);
|
|
2519
|
+
return { name, source: "file", ref: secretPath2 };
|
|
2524
2520
|
}
|
|
2525
2521
|
if (secretSource === "env") {
|
|
2526
2522
|
const { envVar } = await inquirer.prompt([{
|
|
@@ -2845,8 +2841,287 @@ function instanceChoices(provider) {
|
|
|
2845
2841
|
return table[provider] ?? [];
|
|
2846
2842
|
}
|
|
2847
2843
|
|
|
2848
|
-
// src/cli/commands/
|
|
2844
|
+
// src/cli/commands/secret.ts
|
|
2849
2845
|
import { defineCommand as defineCommand19 } from "citty";
|
|
2846
|
+
import { existsSync as existsSync3, readdirSync, readFileSync as readFileSync4, writeFileSync as writeFileSync4, unlinkSync, mkdirSync as mkdirSync4, statSync } from "fs";
|
|
2847
|
+
import { spawnSync as spawnSync2 } from "child_process";
|
|
2848
|
+
import path4 from "path";
|
|
2849
|
+
import os2 from "os";
|
|
2850
|
+
import process21 from "process";
|
|
2851
|
+
var SECRETS_DIR = path4.join(os2.homedir(), ".clawops", "secrets");
|
|
2852
|
+
function secretsDir() {
|
|
2853
|
+
return SECRETS_DIR;
|
|
2854
|
+
}
|
|
2855
|
+
function secretPath(name) {
|
|
2856
|
+
return path4.join(secretsDir(), name);
|
|
2857
|
+
}
|
|
2858
|
+
function listSecretNames() {
|
|
2859
|
+
if (!existsSync3(secretsDir())) return [];
|
|
2860
|
+
return readdirSync(secretsDir()).filter((f) => !f.startsWith("."));
|
|
2861
|
+
}
|
|
2862
|
+
var listCmd = defineCommand19({
|
|
2863
|
+
meta: { name: "list", description: "List all stored secrets and their status" },
|
|
2864
|
+
args: {
|
|
2865
|
+
json: { type: "boolean", description: "Emit JSON" }
|
|
2866
|
+
},
|
|
2867
|
+
run({ args }) {
|
|
2868
|
+
const names = listSecretNames();
|
|
2869
|
+
if (names.length === 0) {
|
|
2870
|
+
info("No secrets stored in ~/.clawops/secrets/");
|
|
2871
|
+
info("Run `clawops secret set <name>` to add one.");
|
|
2872
|
+
return;
|
|
2873
|
+
}
|
|
2874
|
+
const rows = names.map((name) => {
|
|
2875
|
+
const p = secretPath(name);
|
|
2876
|
+
try {
|
|
2877
|
+
const stat = statSync(p);
|
|
2878
|
+
const content = readFileSync4(p, "utf-8").trim();
|
|
2879
|
+
const status = content.length > 0 ? "ok" : "empty";
|
|
2880
|
+
const modified = stat.mtime.toISOString().slice(0, 10);
|
|
2881
|
+
return { name, status, source: "file", path: p, modified, resolvable: content.length > 0 };
|
|
2882
|
+
} catch {
|
|
2883
|
+
return { name, status: "unreadable", source: "file", path: p, modified: "\u2014", resolvable: false };
|
|
2884
|
+
}
|
|
2885
|
+
});
|
|
2886
|
+
if (args.json) {
|
|
2887
|
+
process21.stdout.write(JSON.stringify(rows, null, 2) + "\n");
|
|
2888
|
+
return;
|
|
2889
|
+
}
|
|
2890
|
+
const tableRows = rows.map((r) => [
|
|
2891
|
+
r.name,
|
|
2892
|
+
r.resolvable ? chalk.green("ok") : chalk.red(r.status),
|
|
2893
|
+
r.modified,
|
|
2894
|
+
r.path
|
|
2895
|
+
]);
|
|
2896
|
+
process21.stdout.write("\n" + renderTable(["Name", "Status", "Modified", "Path"], tableRows) + "\n\n");
|
|
2897
|
+
}
|
|
2898
|
+
});
|
|
2899
|
+
var setCmd = defineCommand19({
|
|
2900
|
+
meta: { name: "set", description: "Create or update a secret" },
|
|
2901
|
+
args: {
|
|
2902
|
+
value: { type: "string", description: "Secret value (skips interactive prompt)" }
|
|
2903
|
+
},
|
|
2904
|
+
async run({ args }) {
|
|
2905
|
+
const [name] = args._ ?? [];
|
|
2906
|
+
if (!name) {
|
|
2907
|
+
failure("Usage: clawops secret set <name>");
|
|
2908
|
+
process21.exit(2);
|
|
2909
|
+
}
|
|
2910
|
+
const inquirer = (await import("inquirer")).default;
|
|
2911
|
+
let value;
|
|
2912
|
+
if (args.value) {
|
|
2913
|
+
value = args.value;
|
|
2914
|
+
} else {
|
|
2915
|
+
const { secretValue } = await inquirer.prompt([{
|
|
2916
|
+
type: "password",
|
|
2917
|
+
name: "secretValue",
|
|
2918
|
+
message: `Value for secret "${name}": (input is hidden)`,
|
|
2919
|
+
validate: (v) => typeof v === "string" && v.trim() !== "" || "Value cannot be empty"
|
|
2920
|
+
}]);
|
|
2921
|
+
value = secretValue;
|
|
2922
|
+
}
|
|
2923
|
+
mkdirSync4(secretsDir(), { recursive: true });
|
|
2924
|
+
spawnSync2("chmod", ["700", secretsDir()], { stdio: "ignore" });
|
|
2925
|
+
writeFileSync4(secretPath(name), value.trim(), { encoding: "utf-8", mode: 384 });
|
|
2926
|
+
success(`Secret "${name}" saved to ${secretPath(name)} (chmod 600)`);
|
|
2927
|
+
info("Run `clawops secret rotate <name>` to propagate it to a running stack.");
|
|
2928
|
+
}
|
|
2929
|
+
});
|
|
2930
|
+
var deleteCmd = defineCommand19({
|
|
2931
|
+
meta: { name: "delete", description: "Remove a stored secret" },
|
|
2932
|
+
args: {
|
|
2933
|
+
yes: { type: "boolean", description: "Skip confirmation prompt" }
|
|
2934
|
+
},
|
|
2935
|
+
async run({ args }) {
|
|
2936
|
+
const [name] = args._ ?? [];
|
|
2937
|
+
if (!name) {
|
|
2938
|
+
failure("Usage: clawops secret delete <name>");
|
|
2939
|
+
process21.exit(2);
|
|
2940
|
+
}
|
|
2941
|
+
const p = secretPath(name);
|
|
2942
|
+
if (!existsSync3(p)) {
|
|
2943
|
+
failure(`Secret "${name}" not found at ${p}`);
|
|
2944
|
+
process21.exit(1);
|
|
2945
|
+
}
|
|
2946
|
+
const { listOverlays } = await import("./overlay-store-ADZPD7EU.js");
|
|
2947
|
+
const referencingStacks = listOverlays().filter((o) => o.secrets.some((s) => s.name === name)).map((o) => o.stackName);
|
|
2948
|
+
if (referencingStacks.length > 0) {
|
|
2949
|
+
warn(`Secret "${name}" is referenced by stack(s): ${referencingStacks.join(", ")}`);
|
|
2950
|
+
warn("Deleting it will leave those stacks with an unresolvable $secret: ref.");
|
|
2951
|
+
}
|
|
2952
|
+
if (!args.yes) {
|
|
2953
|
+
const inquirer = (await import("inquirer")).default;
|
|
2954
|
+
const { confirmed } = await inquirer.prompt([{
|
|
2955
|
+
type: "confirm",
|
|
2956
|
+
name: "confirmed",
|
|
2957
|
+
message: `Delete secret "${name}"?`,
|
|
2958
|
+
default: false
|
|
2959
|
+
}]);
|
|
2960
|
+
if (!confirmed) {
|
|
2961
|
+
info("Aborted.");
|
|
2962
|
+
return;
|
|
2963
|
+
}
|
|
2964
|
+
}
|
|
2965
|
+
unlinkSync(p);
|
|
2966
|
+
success(`Secret "${name}" deleted.`);
|
|
2967
|
+
}
|
|
2968
|
+
});
|
|
2969
|
+
var rotateCmd = defineCommand19({
|
|
2970
|
+
meta: { name: "rotate", description: "Update a secret and re-apply config to a running stack" },
|
|
2971
|
+
args: {
|
|
2972
|
+
stack: { type: "string", description: "Stack name to re-apply (defaults to config default)" },
|
|
2973
|
+
value: { type: "string", description: "New secret value (skips interactive prompt)" }
|
|
2974
|
+
},
|
|
2975
|
+
async run({ args }) {
|
|
2976
|
+
const [name] = args._ ?? [];
|
|
2977
|
+
if (!name) {
|
|
2978
|
+
failure("Usage: clawops secret rotate <name> [--stack <name>]");
|
|
2979
|
+
process21.exit(2);
|
|
2980
|
+
}
|
|
2981
|
+
const inquirer = (await import("inquirer")).default;
|
|
2982
|
+
let value;
|
|
2983
|
+
if (args.value) {
|
|
2984
|
+
value = args.value;
|
|
2985
|
+
} else {
|
|
2986
|
+
const { secretValue } = await inquirer.prompt([{
|
|
2987
|
+
type: "password",
|
|
2988
|
+
name: "secretValue",
|
|
2989
|
+
message: `New value for secret "${name}": (input is hidden)`,
|
|
2990
|
+
validate: (v) => typeof v === "string" && v.trim() !== "" || "Value cannot be empty"
|
|
2991
|
+
}]);
|
|
2992
|
+
value = secretValue;
|
|
2993
|
+
}
|
|
2994
|
+
mkdirSync4(secretsDir(), { recursive: true });
|
|
2995
|
+
spawnSync2("chmod", ["700", secretsDir()], { stdio: "ignore" });
|
|
2996
|
+
writeFileSync4(secretPath(name), value.trim(), { encoding: "utf-8", mode: 384 });
|
|
2997
|
+
success(`Secret "${name}" updated.`);
|
|
2998
|
+
const { getConfig: getConfig2 } = await import("./store-SDUR52Z5.js");
|
|
2999
|
+
const cfg = getConfig2();
|
|
3000
|
+
const targetStack = args.stack ?? cfg?.defaults?.stack;
|
|
3001
|
+
if (!targetStack) {
|
|
3002
|
+
warn("No stack specified and no default stack in config \u2014 skipping re-apply.");
|
|
3003
|
+
info("Run `clawops secret rotate <name> --stack <name>` to re-apply to a specific stack.");
|
|
3004
|
+
return;
|
|
3005
|
+
}
|
|
3006
|
+
const { loadOverlay } = await import("./overlay-store-ADZPD7EU.js");
|
|
3007
|
+
const stored = loadOverlay(targetStack);
|
|
3008
|
+
if (!stored) {
|
|
3009
|
+
warn(`No stored overlay for stack "${targetStack}" \u2014 cannot re-apply automatically.`);
|
|
3010
|
+
info("Re-run `clawops setup` or `clawops apply` to propagate the new secret.");
|
|
3011
|
+
return;
|
|
3012
|
+
}
|
|
3013
|
+
info(`Re-applying config overlay to stack "${targetStack}"\u2026`);
|
|
3014
|
+
try {
|
|
3015
|
+
const { buildContext } = await import("./context-M2RMDHX6.js");
|
|
3016
|
+
const { readRemoteConfig, atomicWriteConfig, restartGateway, deepMerge } = await import("./remote-config-JQ77SRC2.js");
|
|
3017
|
+
const { resolveSecrets } = await import("./secrets-SVZWNAPK.js");
|
|
3018
|
+
const { acquireSession, drainPool } = await import("./pool-FBFHATDG.js");
|
|
3019
|
+
const { localStateToConnectionInfo } = await import("./state-PRBIIN7I.js");
|
|
3020
|
+
const ctx = buildContext({ stack: targetStack });
|
|
3021
|
+
let conn;
|
|
3022
|
+
if (ctx.adapter.name === "local") {
|
|
3023
|
+
if (!ctx.localState) throw new Error(`Stack "${targetStack}" has not been bootstrapped yet.`);
|
|
3024
|
+
conn = localStateToConnectionInfo(ctx.localState);
|
|
3025
|
+
} else {
|
|
3026
|
+
const stack = await ctx.getStack();
|
|
3027
|
+
const outputMap = await stack.outputs();
|
|
3028
|
+
const outputs = Object.fromEntries(
|
|
3029
|
+
Object.entries(outputMap).map(([k, v]) => [k, v.value])
|
|
3030
|
+
);
|
|
3031
|
+
const { extractBaseOutputs } = await import("./outputs-DJHBY7EE.js");
|
|
3032
|
+
const base = extractBaseOutputs(outputs);
|
|
3033
|
+
conn = ctx.adapter.getConnectionInfo({ ...base, privateKeyPath: ctx.config.ssh.keyPath, knownHostsPath: ctx.config.ssh.knownHostsPath });
|
|
3034
|
+
}
|
|
3035
|
+
const { session, release } = await acquireSession(conn);
|
|
3036
|
+
try {
|
|
3037
|
+
const remote = await readRemoteConfig(session);
|
|
3038
|
+
const resolved = resolveSecrets(stored.overlay, stored.secrets);
|
|
3039
|
+
const merged = deepMerge(remote, resolved);
|
|
3040
|
+
await atomicWriteConfig(session, merged);
|
|
3041
|
+
await restartGateway(session);
|
|
3042
|
+
} finally {
|
|
3043
|
+
release();
|
|
3044
|
+
drainPool();
|
|
3045
|
+
}
|
|
3046
|
+
success(`Config overlay re-applied and gateway restarted on "${targetStack}".`);
|
|
3047
|
+
} catch (err) {
|
|
3048
|
+
failure(`Re-apply failed: ${err.message}`);
|
|
3049
|
+
info("The secret file has been updated. Re-run `clawops setup` or `clawops apply` to propagate.");
|
|
3050
|
+
}
|
|
3051
|
+
}
|
|
3052
|
+
});
|
|
3053
|
+
var auditCmd = defineCommand19({
|
|
3054
|
+
meta: { name: "audit", description: "Report missing secrets and unresolvable $secret: refs" },
|
|
3055
|
+
args: {
|
|
3056
|
+
json: { type: "boolean", description: "Emit JSON" }
|
|
3057
|
+
},
|
|
3058
|
+
async run({ args }) {
|
|
3059
|
+
const { listOverlays } = await import("./overlay-store-ADZPD7EU.js");
|
|
3060
|
+
const overlays = listOverlays();
|
|
3061
|
+
const issues = [];
|
|
3062
|
+
for (const name of listSecretNames()) {
|
|
3063
|
+
const p = secretPath(name);
|
|
3064
|
+
try {
|
|
3065
|
+
const content = readFileSync4(p, "utf-8").trim();
|
|
3066
|
+
if (content.length === 0) {
|
|
3067
|
+
issues.push({ kind: "empty-secret", secret: name, detail: `File exists but is empty: ${p}` });
|
|
3068
|
+
}
|
|
3069
|
+
} catch {
|
|
3070
|
+
issues.push({ kind: "unreadable-secret", secret: name, detail: `Cannot read: ${p}` });
|
|
3071
|
+
}
|
|
3072
|
+
}
|
|
3073
|
+
for (const overlay of overlays) {
|
|
3074
|
+
for (const s of overlay.secrets) {
|
|
3075
|
+
if (s.source === "file") {
|
|
3076
|
+
const ref = s.ref ?? secretPath(s.name);
|
|
3077
|
+
if (!existsSync3(ref)) {
|
|
3078
|
+
issues.push({ kind: "missing-file", stack: overlay.stackName, secret: s.name, detail: `File not found: ${ref}` });
|
|
3079
|
+
}
|
|
3080
|
+
} else if (s.source === "env") {
|
|
3081
|
+
const envVar = s.ref ?? s.name;
|
|
3082
|
+
if (!process21.env[envVar]) {
|
|
3083
|
+
issues.push({ kind: "missing-env", stack: overlay.stackName, secret: s.name, detail: `Env var not set: ${envVar}` });
|
|
3084
|
+
}
|
|
3085
|
+
} else {
|
|
3086
|
+
issues.push({ kind: "cloud-sm-unresolved", stack: overlay.stackName, secret: s.name, detail: `Source "${s.source}" is not auto-resolved \u2014 set manually` });
|
|
3087
|
+
}
|
|
3088
|
+
}
|
|
3089
|
+
}
|
|
3090
|
+
if (args.json) {
|
|
3091
|
+
process21.stdout.write(JSON.stringify({ issues, ok: issues.length === 0 }, null, 2) + "\n");
|
|
3092
|
+
return;
|
|
3093
|
+
}
|
|
3094
|
+
if (issues.length === 0) {
|
|
3095
|
+
success("All secrets are resolvable. No issues found.");
|
|
3096
|
+
return;
|
|
3097
|
+
}
|
|
3098
|
+
failure(`${issues.length} issue${issues.length === 1 ? "" : "s"} found:
|
|
3099
|
+
`);
|
|
3100
|
+
for (const issue of issues) {
|
|
3101
|
+
const prefix = issue.stack ? `[${issue.stack}] ` : "";
|
|
3102
|
+
warn(`${prefix}${issue.secret}: ${issue.detail}`);
|
|
3103
|
+
}
|
|
3104
|
+
process21.stdout.write("\n");
|
|
3105
|
+
info("Run `clawops secret set <name>` to update a missing or empty secret.");
|
|
3106
|
+
}
|
|
3107
|
+
});
|
|
3108
|
+
var secret_default = defineCommand19({
|
|
3109
|
+
meta: {
|
|
3110
|
+
name: "secret",
|
|
3111
|
+
description: "Manage clawops secrets (list | set | delete | rotate | audit)"
|
|
3112
|
+
},
|
|
3113
|
+
args: {},
|
|
3114
|
+
subCommands: {
|
|
3115
|
+
list: listCmd,
|
|
3116
|
+
set: setCmd,
|
|
3117
|
+
delete: deleteCmd,
|
|
3118
|
+
rotate: rotateCmd,
|
|
3119
|
+
audit: auditCmd
|
|
3120
|
+
}
|
|
3121
|
+
});
|
|
3122
|
+
|
|
3123
|
+
// src/cli/commands/help.ts
|
|
3124
|
+
import { defineCommand as defineCommand20 } from "citty";
|
|
2850
3125
|
var COMMANDS = [
|
|
2851
3126
|
["setup", "Interactive first-run wizard \u2014 configure, deploy, and wire AI apps"],
|
|
2852
3127
|
["init", "Write config and generate SSH key pair (non-interactive)"],
|
|
@@ -2866,6 +3141,7 @@ var COMMANDS = [
|
|
|
2866
3141
|
["stacks", "List named stacks and their state"],
|
|
2867
3142
|
["doctor", "Check Node version, config, SSH key, provider credentials, and Pulumi home"],
|
|
2868
3143
|
["mcp", "MCP server operations (mcp serve | mcp install)"],
|
|
3144
|
+
["secret", "Manage secrets (secret list | set | delete | rotate | audit)"],
|
|
2869
3145
|
["help", "Show this help message"]
|
|
2870
3146
|
];
|
|
2871
3147
|
var GLOBAL_FLAGS = [
|
|
@@ -2876,7 +3152,7 @@ var GLOBAL_FLAGS = [
|
|
|
2876
3152
|
["--dry-run", "Preview without applying (mutating commands)"],
|
|
2877
3153
|
["--yes", "Skip interactive confirmations (CI mode)"]
|
|
2878
3154
|
];
|
|
2879
|
-
var help_default =
|
|
3155
|
+
var help_default = defineCommand20({
|
|
2880
3156
|
meta: {
|
|
2881
3157
|
name: "help",
|
|
2882
3158
|
description: "Show available commands and global flags"
|
|
@@ -2916,25 +3192,25 @@ ${dim("Run `clawops <command> --help` for command-specific flags.")}
|
|
|
2916
3192
|
});
|
|
2917
3193
|
|
|
2918
3194
|
// src/cli/error-handler.ts
|
|
2919
|
-
import
|
|
3195
|
+
import process22 from "process";
|
|
2920
3196
|
function handleError(err) {
|
|
2921
3197
|
if (err instanceof ClawopsError) {
|
|
2922
3198
|
failure(err.message);
|
|
2923
|
-
|
|
3199
|
+
process22.exit(err.exitCode);
|
|
2924
3200
|
}
|
|
2925
3201
|
if (err instanceof Error) {
|
|
2926
3202
|
failure(`Unexpected error: ${err.message}`);
|
|
2927
|
-
if (
|
|
2928
|
-
|
|
3203
|
+
if (process22.env["DEBUG"]) {
|
|
3204
|
+
process22.stderr.write(err.stack ?? "\n");
|
|
2929
3205
|
}
|
|
2930
|
-
|
|
3206
|
+
process22.exit(1);
|
|
2931
3207
|
}
|
|
2932
3208
|
failure(`Unknown error: ${String(err)}`);
|
|
2933
|
-
|
|
3209
|
+
process22.exit(1);
|
|
2934
3210
|
}
|
|
2935
3211
|
|
|
2936
3212
|
// src/cli/index.ts
|
|
2937
|
-
var main =
|
|
3213
|
+
var main = defineCommand21({
|
|
2938
3214
|
meta: {
|
|
2939
3215
|
name: "clawops",
|
|
2940
3216
|
description: "Deploy and manage self-hosted OpenClaw instances across clouds",
|
|
@@ -2968,6 +3244,7 @@ var main = defineCommand20({
|
|
|
2968
3244
|
doctor: doctor_default,
|
|
2969
3245
|
mcp: mcp_default,
|
|
2970
3246
|
setup: setup_default,
|
|
3247
|
+
secret: secret_default,
|
|
2971
3248
|
help: help_default
|
|
2972
3249
|
}
|
|
2973
3250
|
});
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
generatePlan,
|
|
4
4
|
planId
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-ZDPBBYYV.js";
|
|
6
6
|
import "./chunk-YTH4L2GN.js";
|
|
7
|
-
import "./chunk-
|
|
8
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-JDN6PLH2.js";
|
|
8
|
+
import "./chunk-A2I76FTA.js";
|
|
9
9
|
import "./chunk-CX5SL5HP.js";
|
|
10
10
|
import "./chunk-KGXPLI7W.js";
|
|
11
11
|
export {
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
extractBaseOutputs
|
|
4
|
+
} from "./chunk-3QJBNAHW.js";
|
|
2
5
|
import {
|
|
3
6
|
generatePlan
|
|
4
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-ZDPBBYYV.js";
|
|
5
8
|
import {
|
|
6
9
|
applyPlan
|
|
7
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-JCUZU5BH.js";
|
|
8
11
|
import {
|
|
9
12
|
validatePlan
|
|
10
13
|
} from "./chunk-YTH4L2GN.js";
|
|
14
|
+
import "./chunk-6ZFIFDBJ.js";
|
|
11
15
|
import "./chunk-BOPSG2LI.js";
|
|
12
|
-
import {
|
|
13
|
-
extractBaseOutputs
|
|
14
|
-
} from "./chunk-3QJBNAHW.js";
|
|
15
16
|
import {
|
|
16
17
|
errText,
|
|
17
18
|
handleConfigGet,
|
|
@@ -20,17 +21,17 @@ import {
|
|
|
20
21
|
handleConfigValidate,
|
|
21
22
|
okText,
|
|
22
23
|
resolveConn
|
|
23
|
-
} from "./chunk-
|
|
24
|
+
} from "./chunk-LVIIYY27.js";
|
|
24
25
|
import {
|
|
25
26
|
buildContext
|
|
26
|
-
} from "./chunk-
|
|
27
|
-
import "./chunk-BRPU7AQC.js";
|
|
27
|
+
} from "./chunk-JDN6PLH2.js";
|
|
28
28
|
import {
|
|
29
29
|
acquireSession,
|
|
30
30
|
drainPool
|
|
31
31
|
} from "./chunk-ZVOEQCNW.js";
|
|
32
32
|
import "./chunk-4U3LTLWZ.js";
|
|
33
33
|
import "./chunk-UDNZUSKA.js";
|
|
34
|
+
import "./chunk-A2I76FTA.js";
|
|
34
35
|
import {
|
|
35
36
|
getConfig,
|
|
36
37
|
getConfigDir
|
|
@@ -613,7 +614,7 @@ async function handleUp(input, server) {
|
|
|
613
614
|
);
|
|
614
615
|
}
|
|
615
616
|
const { localOpts } = stackConfig;
|
|
616
|
-
const { localBootstrap } = await import("./bootstrap-
|
|
617
|
+
const { localBootstrap } = await import("./bootstrap-G4UZ2FKH.js");
|
|
617
618
|
const ac = new AbortController();
|
|
618
619
|
const state = await localBootstrap({
|
|
619
620
|
host: localOpts.host,
|
|
@@ -1231,7 +1232,7 @@ If none of the above resolves the issue:
|
|
|
1231
1232
|
|
|
1232
1233
|
// src/mcp/server.ts
|
|
1233
1234
|
async function serveMcp(opts) {
|
|
1234
|
-
const { version } = await import("./package-
|
|
1235
|
+
const { version } = await import("./package-AFUTH62F.js");
|
|
1235
1236
|
const server = new McpServer({ name: "clawops", version });
|
|
1236
1237
|
registerTools(server, opts);
|
|
1237
1238
|
registerResources(server);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
localStateToConnectionInfo,
|
|
4
|
+
readLocalState,
|
|
5
|
+
stateDir,
|
|
6
|
+
statePath,
|
|
7
|
+
writeLocalState
|
|
8
|
+
} from "./chunk-A2I76FTA.js";
|
|
9
|
+
import "./chunk-CX5SL5HP.js";
|
|
10
|
+
import "./chunk-KGXPLI7W.js";
|
|
11
|
+
export {
|
|
12
|
+
localStateToConnectionInfo,
|
|
13
|
+
readLocalState,
|
|
14
|
+
stateDir,
|
|
15
|
+
statePath,
|
|
16
|
+
writeLocalState
|
|
17
|
+
};
|