@clawops/cli 2.0.1 → 2.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/README.md +862 -807
- package/dist/{apply-KYFPWI5U.js → apply-HJ5GAKHW.js} +7 -7
- package/dist/{automation-RMAIBNVC.js → automation-MKCJ46I6.js} +3 -3
- package/dist/{bootstrap-HNGKY6WW.js → bootstrap-NN647RCY.js} +2 -2
- package/dist/{chunk-HSPHXG6W.js → chunk-3Z5TDXCJ.js} +2 -2
- package/dist/{chunk-CX5SL5HP.js → chunk-64PONSA5.js} +10 -1
- package/dist/{chunk-STLRHLLV.js → chunk-A2DS5SB7.js} +12 -9
- package/dist/{chunk-KC3GC3PE.js → chunk-AYUX4FOF.js} +127 -13
- package/dist/{chunk-LEVIW2PV.js → chunk-BELTQGHT.js} +16 -2
- package/dist/{preflight-MWWM5JT3.js → chunk-BTW7NHOH.js} +3 -2
- package/dist/{chunk-A2I76FTA.js → chunk-ELU3XQEA.js} +1 -1
- package/dist/{chunk-IVWP4QUJ.js → chunk-GFUK6KDR.js} +10 -10
- package/dist/{chunk-W3OLNNJW.js → chunk-PSOSBJVO.js} +1 -1
- package/dist/{chunk-5XT5IAJK.js → chunk-QDNFADJI.js} +12 -5
- package/dist/{chunk-LBE6COC4.js → chunk-R3DTA35B.js} +22 -3
- package/dist/{preflight-EF52S3WW.js → chunk-TC2VYPLH.js} +3 -2
- package/dist/chunk-X56CQ6GB.js +157 -0
- package/dist/{chunk-BSLIYB5Q.js → chunk-XFN3YDZE.js} +1 -1
- package/dist/{cli-WLD3EBEM.js → cli-NH7VUNOU.js} +1 -1
- package/dist/cli.js +156 -82
- package/dist/{context-7EVC6W45.js → context-7VI3R6EK.js} +4 -4
- package/dist/flows-RI7FGHAM.js +120 -0
- package/dist/{generate-I6YQ5V2T.js → generate-YEM73KVB.js} +6 -6
- package/dist/{harden-72JMRT4E.js → harden-3KKCR7BL.js} +541 -3
- package/dist/{mcp-wire-3SWBM7D6.js → mcp-wire-TE2ZL6HD.js} +10 -10
- package/dist/{package-5BCMEBTE.js → package-JWDMWPV3.js} +47 -10
- package/dist/preflight-7W23GP4R.js +19 -0
- package/dist/preflight-IE2YWBAC.js +13 -0
- package/dist/private-only-DIA26I2E.js +74 -0
- package/dist/{server-GBA7BJGK.js → server-ZJPXPRZT.js} +10 -10
- package/dist/{stack-config-R4SPSUQZ.js → stack-config-LUTS2XAD.js} +2 -2
- package/dist/{state-PRBIIN7I.js → state-AOAYLYY5.js} +2 -2
- package/dist/{store-SDUR52Z5.js → store-OVB3DAJR.js} +1 -1
- package/dist/tailscale-cutover-6YP2QKFM.js +113 -0
- package/dist/{validate-YVI3BJ55.js → validate-JXKN5WD6.js} +1 -1
- package/package.json +39 -8
- package/spec/deploy-plan.schema.json +16 -1
- package/spec/mcp-tools.yaml +67 -9
package/dist/cli.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
MCP_APPS,
|
|
4
|
+
buildMcpEntry,
|
|
5
|
+
writeAppConfigs
|
|
6
|
+
} from "./chunk-OIGTOLB3.js";
|
|
2
7
|
import {
|
|
3
8
|
monitor_default,
|
|
4
9
|
runDiagnostics
|
|
5
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-GFUK6KDR.js";
|
|
6
11
|
import {
|
|
7
12
|
GATEWAY_LOGS_PROBE,
|
|
8
13
|
chooseLogSource,
|
|
9
14
|
containerLogsCommand,
|
|
10
15
|
gatewayLogsCommand
|
|
11
16
|
} from "./chunk-NUL5F6YV.js";
|
|
12
|
-
import {
|
|
13
|
-
MCP_APPS,
|
|
14
|
-
buildMcpEntry,
|
|
15
|
-
writeAppConfigs
|
|
16
|
-
} from "./chunk-OIGTOLB3.js";
|
|
17
17
|
import "./chunk-3OLUJPCB.js";
|
|
18
18
|
import {
|
|
19
19
|
execPrivileged,
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
interpretProbe,
|
|
28
28
|
probeCommand
|
|
29
29
|
} from "./chunk-LT4XMO5D.js";
|
|
30
|
-
import "./chunk-
|
|
30
|
+
import "./chunk-BELTQGHT.js";
|
|
31
31
|
import {
|
|
32
32
|
CONFIG_FILENAME,
|
|
33
33
|
CONTAINER_UID,
|
|
@@ -62,7 +62,7 @@ import {
|
|
|
62
62
|
getConfigDir,
|
|
63
63
|
requireConfig,
|
|
64
64
|
setConfig
|
|
65
|
-
} from "./chunk-
|
|
65
|
+
} from "./chunk-64PONSA5.js";
|
|
66
66
|
import {
|
|
67
67
|
ClawopsError,
|
|
68
68
|
UsageError
|
|
@@ -148,7 +148,7 @@ async function resolveScopeAccount(provider, signal) {
|
|
|
148
148
|
const { callerAccount } = await import("./preflight-TFD4N5ZU.js");
|
|
149
149
|
return await callerAccount(signal);
|
|
150
150
|
}
|
|
151
|
-
const { resolveProjectId } = await import("./preflight-
|
|
151
|
+
const { resolveProjectId } = await import("./preflight-IE2YWBAC.js");
|
|
152
152
|
return resolveProjectId();
|
|
153
153
|
} catch {
|
|
154
154
|
return void 0;
|
|
@@ -339,7 +339,7 @@ var up_default = defineCommand2({
|
|
|
339
339
|
"publish-gateway": { type: "string", description: 'loopback (default) or all. "all" serves plaintext HTTP \u2014 put TLS in front of it' }
|
|
340
340
|
},
|
|
341
341
|
async run({ args }) {
|
|
342
|
-
const { buildContext } = await import("./context-
|
|
342
|
+
const { buildContext } = await import("./context-7VI3R6EK.js");
|
|
343
343
|
const { guardOpenclawVersion, defaultOpenclawVersion } = await import("./version-guard-XVYW5WFJ.js");
|
|
344
344
|
const ctx = buildContext(args);
|
|
345
345
|
const requestedVersion = typeof args["openclaw-version"] === "string" ? args["openclaw-version"] : await defaultOpenclawVersion();
|
|
@@ -352,7 +352,7 @@ var up_default = defineCommand2({
|
|
|
352
352
|
);
|
|
353
353
|
}
|
|
354
354
|
const { localOpts } = stackConfig;
|
|
355
|
-
const { localBootstrap } = await import("./bootstrap-
|
|
355
|
+
const { localBootstrap } = await import("./bootstrap-NN647RCY.js");
|
|
356
356
|
const gatewayPort = parseGatewayPort(args["gateway-port"]);
|
|
357
357
|
const abortController2 = new AbortController();
|
|
358
358
|
process3.on("SIGINT", () => abortController2.abort());
|
|
@@ -392,8 +392,8 @@ var up_default = defineCommand2({
|
|
|
392
392
|
}
|
|
393
393
|
return;
|
|
394
394
|
}
|
|
395
|
-
const { generatePlan } = await import("./generate-
|
|
396
|
-
const { applyPlan } = await import("./apply-
|
|
395
|
+
const { generatePlan } = await import("./generate-YEM73KVB.js");
|
|
396
|
+
const { applyPlan } = await import("./apply-HJ5GAKHW.js");
|
|
397
397
|
const { resolveNetworkFlags } = await import("./network-args-PYJRJBYO.js");
|
|
398
398
|
const { detectEgressIp } = await import("./firewall-5VKZ4WBH.js");
|
|
399
399
|
const isDryRun = Boolean(args["dry-run"]);
|
|
@@ -523,7 +523,7 @@ var down_default = defineCommand3({
|
|
|
523
523
|
"dry-run": { type: "boolean", description: "Show what would be destroyed without destroying" }
|
|
524
524
|
},
|
|
525
525
|
async run({ args }) {
|
|
526
|
-
const { buildContext } = await import("./context-
|
|
526
|
+
const { buildContext } = await import("./context-7VI3R6EK.js");
|
|
527
527
|
const ctx = buildContext(args);
|
|
528
528
|
if (args["dry-run"]) {
|
|
529
529
|
info(`Dry run \u2014 would destroy stack "${ctx.stackName}"`);
|
|
@@ -587,7 +587,7 @@ var status_default = defineCommand4({
|
|
|
587
587
|
json: { type: "boolean", description: "Emit JSON" }
|
|
588
588
|
},
|
|
589
589
|
async run({ args }) {
|
|
590
|
-
const { buildContext } = await import("./context-
|
|
590
|
+
const { buildContext } = await import("./context-7VI3R6EK.js");
|
|
591
591
|
const ctx = buildContext(args);
|
|
592
592
|
if (ctx.adapter.name === "local") {
|
|
593
593
|
const state = ctx.localState;
|
|
@@ -645,6 +645,30 @@ import { defineCommand as defineCommand5 } from "citty";
|
|
|
645
645
|
import process7 from "process";
|
|
646
646
|
import { writeFileSync as writeFileSync2 } from "fs";
|
|
647
647
|
import { isAbsolute } from "path";
|
|
648
|
+
function disruptionWarnings(diff) {
|
|
649
|
+
const out = [];
|
|
650
|
+
const isInstance = (type) => /:(Instance|instance)/.test(type);
|
|
651
|
+
const replaced = diff.replace ?? [];
|
|
652
|
+
if (replaced.length > 0) {
|
|
653
|
+
const instance = replaced.some((r) => isInstance(r.type));
|
|
654
|
+
out.push(
|
|
655
|
+
`This plan REPLACES ${replaced.length} existing resource${replaced.length === 1 ? "" : "s"}: ` + replaced.map((r) => r.name ?? r.type).join(", ") + "." + (instance ? " Replacing the instance destroys its boot disk, and with it the OpenClaw config, database, sessions and transcripts on the host. Take a backup first: `clawops backup create`." : "")
|
|
656
|
+
);
|
|
657
|
+
}
|
|
658
|
+
if (diff.update.length > 0) {
|
|
659
|
+
const instance = diff.update.some((u) => isInstance(u.resource.type));
|
|
660
|
+
out.push(
|
|
661
|
+
`This plan modifies ${diff.update.length} existing resource${diff.update.length === 1 ? "" : "s"}.` + (instance ? " Some instance changes require the machine to be stopped and started, so the gateway goes down for the duration and in-flight work is lost. State on disk is kept." : "")
|
|
662
|
+
);
|
|
663
|
+
}
|
|
664
|
+
if (diff.delete.length > 0) {
|
|
665
|
+
out.push(`This plan DELETES ${diff.delete.length} existing resource${diff.delete.length === 1 ? "" : "s"}.`);
|
|
666
|
+
}
|
|
667
|
+
return out;
|
|
668
|
+
}
|
|
669
|
+
function warnAboutDisruption(diff) {
|
|
670
|
+
for (const line2 of disruptionWarnings(diff)) warn(line2);
|
|
671
|
+
}
|
|
648
672
|
var plan_default = defineCommand5({
|
|
649
673
|
meta: {
|
|
650
674
|
name: "plan",
|
|
@@ -659,11 +683,12 @@ var plan_default = defineCommand5({
|
|
|
659
683
|
"ssh-cidr": { type: "string", description: "CIDR(s) allowed to reach SSH, comma-separated, or 'auto' for this machine's IP. Omitted = none, and nothing will be able to connect" },
|
|
660
684
|
"gateway-cidr": { type: "string", description: "CIDR(s) allowed to reach the gateway port, comma-separated, or 'auto'. Requires --publish-gateway all" },
|
|
661
685
|
"publish-gateway": { type: "string", description: 'loopback (default) or all. "all" serves plaintext HTTP \u2014 put TLS in front of it' },
|
|
662
|
-
out: { type: "string", description: "Write plan JSON to this absolute path (default: stdout)" }
|
|
686
|
+
out: { type: "string", description: "Write plan JSON to this absolute path (default: stdout)" },
|
|
687
|
+
"private-only": { type: "boolean", description: "Close public SSH and gateway access; reach the stack over its tailnet. Needs `clawops harden --tailscale` first, and checks the tailnet answers before planning" }
|
|
663
688
|
},
|
|
664
689
|
async run({ args }) {
|
|
665
|
-
const { buildContext } = await import("./context-
|
|
666
|
-
const { generatePlan } = await import("./generate-
|
|
690
|
+
const { buildContext } = await import("./context-7VI3R6EK.js");
|
|
691
|
+
const { generatePlan } = await import("./generate-YEM73KVB.js");
|
|
667
692
|
const { resolveNetworkFlags } = await import("./network-args-PYJRJBYO.js");
|
|
668
693
|
const { detectEgressIp } = await import("./firewall-5VKZ4WBH.js");
|
|
669
694
|
const ctx = buildContext(args);
|
|
@@ -677,14 +702,21 @@ var plan_default = defineCommand5({
|
|
|
677
702
|
if (outPath && !isAbsolute(outPath)) {
|
|
678
703
|
throw new UsageError("--out path must be absolute (R7). Use an absolute path like /tmp/plan.json.");
|
|
679
704
|
}
|
|
680
|
-
const
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
);
|
|
705
|
+
const flags = {
|
|
706
|
+
sshCidr: strArg2(args["ssh-cidr"]),
|
|
707
|
+
gatewayCidr: strArg2(args["gateway-cidr"]),
|
|
708
|
+
publishGateway: strArg2(args["publish-gateway"])
|
|
709
|
+
};
|
|
710
|
+
const resolved = await resolveNetworkFlags(flags, {
|
|
711
|
+
detectEgressIp: () => detectEgressIp("https://ifconfig.me/ip")
|
|
712
|
+
});
|
|
713
|
+
let network = resolved;
|
|
714
|
+
if (args["private-only"]) {
|
|
715
|
+
const { privateOnlyNetwork, assertTailnetReachable } = await import("./private-only-DIA26I2E.js");
|
|
716
|
+
const { probeSsh } = await import("./tailscale-cutover-6YP2QKFM.js");
|
|
717
|
+
network = privateOnlyNetwork(flags, resolved, ctx.config.stacks[ctx.stackName]?.tailscale, ctx.stackName);
|
|
718
|
+
await assertTailnetReachable(ctx, (conn) => probeSsh(conn));
|
|
719
|
+
}
|
|
688
720
|
const abortController = new AbortController();
|
|
689
721
|
process7.on("SIGINT", () => abortController.abort());
|
|
690
722
|
process7.on("SIGTERM", () => abortController.abort());
|
|
@@ -715,7 +747,8 @@ var plan_default = defineCommand5({
|
|
|
715
747
|
process7.stdout.write(planJson + "\n");
|
|
716
748
|
}
|
|
717
749
|
const { spec, metadata } = plan;
|
|
718
|
-
const
|
|
750
|
+
const tailnetIp = spec.network.tailscale?.privateOnly ? spec.network.tailscale.ip : void 0;
|
|
751
|
+
const sshCidrs = spec.network.allowedSshCidrs.join(", ") || (tailnetIp ? `(none) \u2014 tailnet only, at ${tailnetIp}` : "(none)");
|
|
719
752
|
const gatewayCidrs = spec.network.allowedGatewayCidrs.join(", ") || "(none)";
|
|
720
753
|
const publish = spec.network.publishGateway ?? "loopback";
|
|
721
754
|
process7.stderr.write(
|
|
@@ -729,20 +762,22 @@ Plan: ${metadata.name} (${spec.provider}${spec.region ? ` / ${spec.region}` : "
|
|
|
729
762
|
`
|
|
730
763
|
);
|
|
731
764
|
if (plan.diff) {
|
|
732
|
-
const { create, update, delete: del, totalChanges } = plan.diff;
|
|
765
|
+
const { create, update, delete: del, replace = [], totalChanges } = plan.diff;
|
|
733
766
|
process7.stderr.write(
|
|
734
767
|
`
|
|
735
|
-
Changes: ${create.length} to create, ${update.length} to update, ${del.length} to delete (${totalChanges} total)
|
|
768
|
+
Changes: ${create.length} to create, ${update.length} to update, ${replace.length} to replace, ${del.length} to delete (${totalChanges} total)
|
|
736
769
|
`
|
|
737
770
|
);
|
|
738
771
|
const rows = [
|
|
739
772
|
...create.map((r) => ["+", r.type, r.name ?? ""]),
|
|
740
773
|
...update.map((r) => ["~", r.resource.type, r.resource.name ?? ""]),
|
|
774
|
+
...replace.map((r) => ["+-", r.type, r.name ?? ""]),
|
|
741
775
|
...del.map((r) => ["-", r.type, r.name ?? ""])
|
|
742
776
|
];
|
|
743
777
|
if (rows.length > 0) {
|
|
744
778
|
process7.stderr.write(renderTable(["Op", "Resource Type", "Name"], rows) + "\n");
|
|
745
779
|
}
|
|
780
|
+
warnAboutDisruption(plan.diff);
|
|
746
781
|
} else {
|
|
747
782
|
process7.stderr.write("\n(diff unavailable \u2014 preview could not run against this stack)\n");
|
|
748
783
|
}
|
|
@@ -768,8 +803,8 @@ var apply_default = defineCommand6({
|
|
|
768
803
|
"dry-run": { type: "boolean", description: "Validate plan and show diff without applying" }
|
|
769
804
|
},
|
|
770
805
|
async run({ args }) {
|
|
771
|
-
const { validatePlan } = await import("./validate-
|
|
772
|
-
const { applyPlan } = await import("./apply-
|
|
806
|
+
const { validatePlan } = await import("./validate-JXKN5WD6.js");
|
|
807
|
+
const { applyPlan } = await import("./apply-HJ5GAKHW.js");
|
|
773
808
|
const planPath = args._?.[0];
|
|
774
809
|
if (!planPath) {
|
|
775
810
|
throw new UsageError("Usage: clawops apply <plan.json>");
|
|
@@ -895,7 +930,7 @@ var destroy_default = defineCommand7({
|
|
|
895
930
|
"dry-run": { type: "boolean", description: "Show what would be destroyed without destroying" }
|
|
896
931
|
},
|
|
897
932
|
async run({ args }) {
|
|
898
|
-
const { buildContext } = await import("./context-
|
|
933
|
+
const { buildContext } = await import("./context-7VI3R6EK.js");
|
|
899
934
|
const ctx = buildContext(args);
|
|
900
935
|
if (ctx.adapter.name === "local") {
|
|
901
936
|
throw new UsageError(
|
|
@@ -933,7 +968,7 @@ Pass --yes to proceed with destruction.
|
|
|
933
968
|
const abortController = new AbortController();
|
|
934
969
|
process9.on("SIGINT", () => abortController.abort());
|
|
935
970
|
process9.on("SIGTERM", () => abortController.abort());
|
|
936
|
-
const
|
|
971
|
+
const doomedHosts = await hostsOf(stack, ctx);
|
|
937
972
|
const spin = spinner(`Destroying stack "${ctx.stackName}"\u2026`);
|
|
938
973
|
try {
|
|
939
974
|
await stack.destroy({
|
|
@@ -947,31 +982,29 @@ Pass --yes to proceed with destruction.
|
|
|
947
982
|
spin.fail("Destroy failed");
|
|
948
983
|
throw err;
|
|
949
984
|
}
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
const removed = forgetHost(
|
|
953
|
-
|
|
954
|
-
doomedHost.host,
|
|
955
|
-
doomedHost.port
|
|
956
|
-
);
|
|
957
|
-
if (removed) info(`Forgot the host key for ${doomedHost.host} \u2014 its instance is gone.`);
|
|
985
|
+
const { forgetHost } = await import("./known-hosts-file-I3Q3NBYQ.js");
|
|
986
|
+
for (const doomed of doomedHosts) {
|
|
987
|
+
const removed = forgetHost(expandHome(ctx.config.ssh.knownHostsPath), doomed.host, doomed.port);
|
|
988
|
+
if (removed) info(`Forgot the host key for ${doomed.host} \u2014 its instance is gone.`);
|
|
958
989
|
}
|
|
959
990
|
}
|
|
960
991
|
});
|
|
961
|
-
async function
|
|
992
|
+
async function hostsOf(stack, ctx) {
|
|
993
|
+
const hosts = [];
|
|
962
994
|
try {
|
|
963
995
|
const outputMap = await stack.outputs();
|
|
964
996
|
const raw = Object.fromEntries(Object.entries(outputMap).map(([k, v]) => [k, v.value]));
|
|
965
997
|
const { extractBaseOutputs } = await import("./outputs-DJHBY7EE.js");
|
|
966
|
-
const
|
|
967
|
-
|
|
968
|
-
privateKeyPath: ctx.config.ssh.keyPath,
|
|
969
|
-
knownHostsPath: ctx.config.ssh.knownHostsPath
|
|
970
|
-
});
|
|
971
|
-
return conn.host ? { host: conn.host, port: conn.port } : void 0;
|
|
998
|
+
const base = extractBaseOutputs(raw);
|
|
999
|
+
if (base.sshHost) hosts.push({ host: base.sshHost, port: base.sshPort });
|
|
972
1000
|
} catch {
|
|
973
|
-
return void 0;
|
|
974
1001
|
}
|
|
1002
|
+
const tailnet = ctx.config.stacks?.[ctx.stackName]?.tailscale;
|
|
1003
|
+
if (tailnet?.ip) {
|
|
1004
|
+
const port = hosts[0]?.port ?? 22;
|
|
1005
|
+
if (!hosts.some((h) => h.host === tailnet.ip)) hosts.push({ host: tailnet.ip, port });
|
|
1006
|
+
}
|
|
1007
|
+
return hosts;
|
|
975
1008
|
}
|
|
976
1009
|
function expandHome(p) {
|
|
977
1010
|
return p.replace(/^~/, process9.env["HOME"] ?? "~");
|
|
@@ -990,7 +1023,7 @@ var ssh_default = defineCommand8({
|
|
|
990
1023
|
command: { type: "string", description: "Remote command to run (instead of interactive shell)" }
|
|
991
1024
|
},
|
|
992
1025
|
async run({ args }) {
|
|
993
|
-
const { buildContext } = await import("./context-
|
|
1026
|
+
const { buildContext } = await import("./context-7VI3R6EK.js");
|
|
994
1027
|
const { acquireSession, drainPool } = await import("./pool-PIIKJ4L2.js");
|
|
995
1028
|
const ctx = buildContext(args);
|
|
996
1029
|
let conn;
|
|
@@ -1077,7 +1110,7 @@ var tunnel_default = defineCommand9({
|
|
|
1077
1110
|
"no-open": { type: "boolean", description: "Do not open browser after tunnel is ready" }
|
|
1078
1111
|
},
|
|
1079
1112
|
async run({ args }) {
|
|
1080
|
-
const { buildContext } = await import("./context-
|
|
1113
|
+
const { buildContext } = await import("./context-7VI3R6EK.js");
|
|
1081
1114
|
const { extractBaseOutputs } = await import("./outputs-DJHBY7EE.js");
|
|
1082
1115
|
const { acquireSession } = await import("./pool-PIIKJ4L2.js");
|
|
1083
1116
|
const ctx = buildContext(args);
|
|
@@ -1146,7 +1179,7 @@ var logs_default = defineCommand10({
|
|
|
1146
1179
|
json: { type: "boolean", description: "Emit the gateway's structured JSON log lines" }
|
|
1147
1180
|
},
|
|
1148
1181
|
async run({ args }) {
|
|
1149
|
-
const { buildContext } = await import("./context-
|
|
1182
|
+
const { buildContext } = await import("./context-7VI3R6EK.js");
|
|
1150
1183
|
const { extractBaseOutputs } = await import("./outputs-DJHBY7EE.js");
|
|
1151
1184
|
const { acquireSession, drainPool } = await import("./pool-PIIKJ4L2.js");
|
|
1152
1185
|
const ctx = buildContext(args);
|
|
@@ -1252,7 +1285,7 @@ var config_default = defineCommand11({
|
|
|
1252
1285
|
"dry-run": { type: "boolean", description: "Show what would change without writing" }
|
|
1253
1286
|
},
|
|
1254
1287
|
async run({ args }) {
|
|
1255
|
-
const { buildContext } = await import("./context-
|
|
1288
|
+
const { buildContext } = await import("./context-7VI3R6EK.js");
|
|
1256
1289
|
const { extractBaseOutputs } = await import("./outputs-DJHBY7EE.js");
|
|
1257
1290
|
const { acquireSession, drainPool } = await import("./pool-PIIKJ4L2.js");
|
|
1258
1291
|
const [action, key, value] = args._ ?? [];
|
|
@@ -1387,7 +1420,7 @@ var agents_default = defineCommand12({
|
|
|
1387
1420
|
cursor: { type: "string", description: "Continue from a previous `logs` result cursor" }
|
|
1388
1421
|
},
|
|
1389
1422
|
async run({ args }) {
|
|
1390
|
-
const { buildContext } = await import("./context-
|
|
1423
|
+
const { buildContext } = await import("./context-7VI3R6EK.js");
|
|
1391
1424
|
const { extractBaseOutputs } = await import("./outputs-DJHBY7EE.js");
|
|
1392
1425
|
const { acquireSession, drainPool } = await import("./pool-PIIKJ4L2.js");
|
|
1393
1426
|
const [action, name] = args._ ?? [];
|
|
@@ -1619,7 +1652,7 @@ var migrate_default = defineCommand13({
|
|
|
1619
1652
|
yes: { type: "boolean", description: "Skip the confirmation prompt" }
|
|
1620
1653
|
},
|
|
1621
1654
|
async run({ args }) {
|
|
1622
|
-
const { buildContext } = await import("./context-
|
|
1655
|
+
const { buildContext } = await import("./context-7VI3R6EK.js");
|
|
1623
1656
|
const { extractBaseOutputs } = await import("./outputs-DJHBY7EE.js");
|
|
1624
1657
|
const { acquireSession, drainPool } = await import("./pool-PIIKJ4L2.js");
|
|
1625
1658
|
const { guardOpenclawVersion, defaultOpenclawVersion } = await import("./version-guard-XVYW5WFJ.js");
|
|
@@ -1758,7 +1791,7 @@ var gateway_default = defineCommand14({
|
|
|
1758
1791
|
json: { type: "boolean", description: "Emit JSON (for status)" }
|
|
1759
1792
|
},
|
|
1760
1793
|
async run({ args }) {
|
|
1761
|
-
const { buildContext } = await import("./context-
|
|
1794
|
+
const { buildContext } = await import("./context-7VI3R6EK.js");
|
|
1762
1795
|
const { extractBaseOutputs } = await import("./outputs-DJHBY7EE.js");
|
|
1763
1796
|
const { acquireSession, drainPool } = await import("./pool-PIIKJ4L2.js");
|
|
1764
1797
|
const [action, versionArg] = args._ ?? [];
|
|
@@ -1990,7 +2023,7 @@ var backup_default = defineCommand15({
|
|
|
1990
2023
|
yes: { type: "boolean", description: "[restore] Skip confirmation prompt" }
|
|
1991
2024
|
},
|
|
1992
2025
|
async run({ args }) {
|
|
1993
|
-
const { buildContext } = await import("./context-
|
|
2026
|
+
const { buildContext } = await import("./context-7VI3R6EK.js");
|
|
1994
2027
|
const { acquireSession, drainPool } = await import("./pool-PIIKJ4L2.js");
|
|
1995
2028
|
const action = args.action;
|
|
1996
2029
|
if (action !== "create" && action !== "restore") {
|
|
@@ -2201,7 +2234,7 @@ var stacks_default = defineCommand16({
|
|
|
2201
2234
|
let isDeployed = false;
|
|
2202
2235
|
if (!args.force) {
|
|
2203
2236
|
try {
|
|
2204
|
-
const { buildContext } = await import("./context-
|
|
2237
|
+
const { buildContext } = await import("./context-7VI3R6EK.js");
|
|
2205
2238
|
const ctx = buildContext({ stack: name });
|
|
2206
2239
|
if (ctx.adapter.name === "local") {
|
|
2207
2240
|
isDeployed = !!ctx.localState;
|
|
@@ -2342,7 +2375,7 @@ var serveCmd = defineCommand18({
|
|
|
2342
2375
|
inspector: { type: "boolean", description: "Enable MCP inspector" }
|
|
2343
2376
|
},
|
|
2344
2377
|
async run({ args }) {
|
|
2345
|
-
const { serveMcp } = await import("./server-
|
|
2378
|
+
const { serveMcp } = await import("./server-ZJPXPRZT.js");
|
|
2346
2379
|
await serveMcp({
|
|
2347
2380
|
port: args.http ? Number(args.http) : void 0,
|
|
2348
2381
|
bind: args.bind,
|
|
@@ -2420,11 +2453,11 @@ var wireCmd = defineCommand18({
|
|
|
2420
2453
|
rewire: { type: "boolean", description: "Replace an existing clawops entry" }
|
|
2421
2454
|
},
|
|
2422
2455
|
async run({ args }) {
|
|
2423
|
-
const { buildContext } = await import("./context-
|
|
2456
|
+
const { buildContext } = await import("./context-7VI3R6EK.js");
|
|
2424
2457
|
const { acquireSession, drainPool } = await import("./pool-PIIKJ4L2.js");
|
|
2425
2458
|
const { extractBaseOutputs } = await import("./outputs-DJHBY7EE.js");
|
|
2426
|
-
const { wireGatewayMcp } = await import("./mcp-wire-
|
|
2427
|
-
const { MCP_HTTP_PORT } = await import("./server-
|
|
2459
|
+
const { wireGatewayMcp } = await import("./mcp-wire-TE2ZL6HD.js");
|
|
2460
|
+
const { MCP_HTTP_PORT } = await import("./server-ZJPXPRZT.js");
|
|
2428
2461
|
const ac = new AbortController();
|
|
2429
2462
|
process20.on("SIGINT", () => {
|
|
2430
2463
|
ac.abort();
|
|
@@ -3007,7 +3040,7 @@ var setup_default = defineCommand19({
|
|
|
3007
3040
|
inquirer
|
|
3008
3041
|
});
|
|
3009
3042
|
} else {
|
|
3010
|
-
const { getConfigDir: getConfigDir2 } = await import("./store-
|
|
3043
|
+
const { getConfigDir: getConfigDir2 } = await import("./store-OVB3DAJR.js");
|
|
3011
3044
|
const knownHostsPath = path2.join(getConfigDir2(), "known_hosts");
|
|
3012
3045
|
process21.stdout.write("\n");
|
|
3013
3046
|
info("To deploy later, run these two commands:");
|
|
@@ -3024,7 +3057,7 @@ var setup_default = defineCommand19({
|
|
|
3024
3057
|
default: false
|
|
3025
3058
|
}]);
|
|
3026
3059
|
if (applyNow) {
|
|
3027
|
-
const { applyPlan } = await import("./apply-
|
|
3060
|
+
const { applyPlan } = await import("./apply-HJ5GAKHW.js");
|
|
3028
3061
|
const plan = JSON.parse(readFileSync3(outputPath, "utf-8"));
|
|
3029
3062
|
try {
|
|
3030
3063
|
await applyPlan(plan, {
|
|
@@ -3052,8 +3085,8 @@ To deploy later: clawops apply ${outputPath}`);
|
|
|
3052
3085
|
}
|
|
3053
3086
|
});
|
|
3054
3087
|
async function runLocalDeploy(opts) {
|
|
3055
|
-
const { setConfig: setConfig2, getConfig: getConfig2, getConfigDir: getConfigDir2 } = await import("./store-
|
|
3056
|
-
const { localBootstrap } = await import("./bootstrap-
|
|
3088
|
+
const { setConfig: setConfig2, getConfig: getConfig2, getConfigDir: getConfigDir2 } = await import("./store-OVB3DAJR.js");
|
|
3089
|
+
const { localBootstrap } = await import("./bootstrap-NN647RCY.js");
|
|
3057
3090
|
const { connect } = await import("./ssh-VAI5DU5M.js");
|
|
3058
3091
|
const { readRemoteConfig, atomicWriteConfig, restartGateway, deepMerge } = await import("./remote-config-3HZLUWEA.js");
|
|
3059
3092
|
const { resolveSecrets } = await import("./secrets-SVZWNAPK.js");
|
|
@@ -3527,8 +3560,8 @@ async function maybeWireGatewayMcp(opts) {
|
|
|
3527
3560
|
const { wireGateway } = await inquirerPromptWire(opts.inquirer);
|
|
3528
3561
|
if (!wireGateway) return;
|
|
3529
3562
|
const { connect } = await import("./ssh-VAI5DU5M.js");
|
|
3530
|
-
const { getConfigDir: getConfigDir2 } = await import("./store-
|
|
3531
|
-
const { wireGatewayMcp } = await import("./mcp-wire-
|
|
3563
|
+
const { getConfigDir: getConfigDir2 } = await import("./store-OVB3DAJR.js");
|
|
3564
|
+
const { wireGatewayMcp } = await import("./mcp-wire-TE2ZL6HD.js");
|
|
3532
3565
|
const knownHostsPath = path2.join(getConfigDir2(), "known_hosts");
|
|
3533
3566
|
const spin = spinner("Wiring gateway MCP client...");
|
|
3534
3567
|
const session = await connect({
|
|
@@ -3647,8 +3680,8 @@ function instanceChoices(provider) {
|
|
|
3647
3680
|
return table[provider] ?? [];
|
|
3648
3681
|
}
|
|
3649
3682
|
async function maybeHarden(opts) {
|
|
3650
|
-
const { MODULE_CATALOG, resolveModules, runHardening, formatHardenSummary } = await import("./harden-
|
|
3651
|
-
const { getConfig: getConfig2 } = await import("./store-
|
|
3683
|
+
const { MODULE_CATALOG, resolveModules, runHardening, formatHardenSummary } = await import("./harden-3KKCR7BL.js");
|
|
3684
|
+
const { getConfig: getConfig2 } = await import("./store-OVB3DAJR.js");
|
|
3652
3685
|
const config = getConfig2();
|
|
3653
3686
|
if (!config) return;
|
|
3654
3687
|
const availableModules = resolveModules(MODULE_CATALOG, void 0, opts.provider);
|
|
@@ -3671,7 +3704,7 @@ async function maybeHarden(opts) {
|
|
|
3671
3704
|
const modules = availableModules.filter((m) => selectedIds.includes(m.id));
|
|
3672
3705
|
process21.stdout.write("\nApplying hardening modules...\n\n");
|
|
3673
3706
|
try {
|
|
3674
|
-
const { buildContext } = await import("./context-
|
|
3707
|
+
const { buildContext } = await import("./context-7VI3R6EK.js");
|
|
3675
3708
|
const { extractBaseOutputs } = await import("./outputs-DJHBY7EE.js");
|
|
3676
3709
|
const ctx = buildContext({ stack: opts.stackName });
|
|
3677
3710
|
const stackObj = await ctx.getStack();
|
|
@@ -3946,7 +3979,7 @@ var rotateCmd = defineCommand20({
|
|
|
3946
3979
|
spawnSync3("chmod", ["700", secretsDir()], { stdio: "ignore" });
|
|
3947
3980
|
writeFileSync4(secretPath(name), value.trim(), { encoding: "utf-8", mode: 384 });
|
|
3948
3981
|
success(`Secret "${name}" updated.`);
|
|
3949
|
-
const { getConfig: getConfig2 } = await import("./store-
|
|
3982
|
+
const { getConfig: getConfig2 } = await import("./store-OVB3DAJR.js");
|
|
3950
3983
|
const cfg = getConfig2();
|
|
3951
3984
|
const targetStack = args.stack ?? cfg?.defaults?.stack;
|
|
3952
3985
|
if (!targetStack) {
|
|
@@ -3963,11 +3996,11 @@ var rotateCmd = defineCommand20({
|
|
|
3963
3996
|
}
|
|
3964
3997
|
info(`Re-applying config overlay to stack "${targetStack}"\u2026`);
|
|
3965
3998
|
try {
|
|
3966
|
-
const { buildContext } = await import("./context-
|
|
3999
|
+
const { buildContext } = await import("./context-7VI3R6EK.js");
|
|
3967
4000
|
const { readRemoteConfig, atomicWriteConfig, restartGateway, deepMerge } = await import("./remote-config-3HZLUWEA.js");
|
|
3968
4001
|
const { resolveSecrets } = await import("./secrets-SVZWNAPK.js");
|
|
3969
4002
|
const { acquireSession, drainPool } = await import("./pool-PIIKJ4L2.js");
|
|
3970
|
-
const { localStateToConnectionInfo } = await import("./state-
|
|
4003
|
+
const { localStateToConnectionInfo } = await import("./state-AOAYLYY5.js");
|
|
3971
4004
|
const ctx = buildContext({ stack: targetStack });
|
|
3972
4005
|
let conn;
|
|
3973
4006
|
if (ctx.adapter.name === "local") {
|
|
@@ -4150,7 +4183,7 @@ import { accessSync, constants } from "fs";
|
|
|
4150
4183
|
import { execSync as execSync2 } from "child_process";
|
|
4151
4184
|
var ISSUES_URL = `${REPO_URL}/issues/new`;
|
|
4152
4185
|
var BODY_CAP = 2e3;
|
|
4153
|
-
var VERSION = true ? "2.0
|
|
4186
|
+
var VERSION = true ? "2.1.0" : "dev";
|
|
4154
4187
|
async function collectContext() {
|
|
4155
4188
|
const nodeVersion = process23.version;
|
|
4156
4189
|
const os3 = `${process23.platform} ${process23.arch}`;
|
|
@@ -4158,7 +4191,7 @@ async function collectContext() {
|
|
|
4158
4191
|
let stackCount = 0;
|
|
4159
4192
|
let sshKey = "unknown";
|
|
4160
4193
|
try {
|
|
4161
|
-
const { getConfig: getConfig2 } = await import("./store-
|
|
4194
|
+
const { getConfig: getConfig2 } = await import("./store-OVB3DAJR.js");
|
|
4162
4195
|
const config = getConfig2();
|
|
4163
4196
|
if (config) {
|
|
4164
4197
|
const stacks = Object.values(config.stacks);
|
|
@@ -4264,12 +4297,14 @@ var harden_default = defineCommand23({
|
|
|
4264
4297
|
list: { type: "boolean", description: "List available modules and exit" },
|
|
4265
4298
|
"dry-run": { type: "boolean", description: "Check current state without applying changes" },
|
|
4266
4299
|
yes: { type: "boolean", description: "Skip confirmation prompt" },
|
|
4267
|
-
json: { type: "boolean", description: "Emit structured JSON output" }
|
|
4300
|
+
json: { type: "boolean", description: "Emit structured JSON output" },
|
|
4301
|
+
tailscale: { type: "boolean", description: "Join the tailnet, verify this machine can reach the host there, then use that address" },
|
|
4302
|
+
"tailscale-revert": { type: "boolean", description: "Take the host off its tailnet and go back to its public address. A private-only stack must be reopened with a plan first" }
|
|
4268
4303
|
},
|
|
4269
4304
|
async run({ args }) {
|
|
4270
|
-
const { MODULE_CATALOG, resolveModules, runHardening, formatHardenSummary } = await import("./harden-
|
|
4271
|
-
const { buildContext } = await import("./context-
|
|
4272
|
-
const { getConfig: getConfig2 } = await import("./store-
|
|
4305
|
+
const { MODULE_CATALOG, resolveModules, runHardening, formatHardenSummary } = await import("./harden-3KKCR7BL.js");
|
|
4306
|
+
const { buildContext } = await import("./context-7VI3R6EK.js");
|
|
4307
|
+
const { getConfig: getConfig2 } = await import("./store-OVB3DAJR.js");
|
|
4273
4308
|
if (args.list) {
|
|
4274
4309
|
process24.stdout.write("\nAvailable hardening modules:\n\n");
|
|
4275
4310
|
for (const mod of MODULE_CATALOG) {
|
|
@@ -4290,7 +4325,36 @@ var harden_default = defineCommand23({
|
|
|
4290
4325
|
}
|
|
4291
4326
|
const ctx = buildContext({ stack: args.stack });
|
|
4292
4327
|
const provider = ctx.adapter.name;
|
|
4293
|
-
|
|
4328
|
+
if (args["tailscale-revert"]) {
|
|
4329
|
+
const { revertTailnet } = await import("./flows-RI7FGHAM.js");
|
|
4330
|
+
const override = config.stacks[ctx.stackName]?.tailscale;
|
|
4331
|
+
if (override && args.yes !== true) {
|
|
4332
|
+
const { createInterface: createInterface3 } = await import("readline/promises");
|
|
4333
|
+
const rl = createInterface3({ input: process24.stdin, output: process24.stdout });
|
|
4334
|
+
const answer = await rl.question(
|
|
4335
|
+
`Take "${ctx.stackName}" off the tailnet (${override.ip}) and use its public address again? [y/N] `
|
|
4336
|
+
);
|
|
4337
|
+
rl.close();
|
|
4338
|
+
if (!answer.toLowerCase().startsWith("y")) {
|
|
4339
|
+
info("Aborted.");
|
|
4340
|
+
return;
|
|
4341
|
+
}
|
|
4342
|
+
}
|
|
4343
|
+
const outcome = await revertTailnet(ctx, config);
|
|
4344
|
+
if (!outcome.ok) {
|
|
4345
|
+
failure(outcome.reason);
|
|
4346
|
+
process24.exit(1);
|
|
4347
|
+
}
|
|
4348
|
+
if ("noop" in outcome) info(outcome.message);
|
|
4349
|
+
else success(outcome.message);
|
|
4350
|
+
return;
|
|
4351
|
+
}
|
|
4352
|
+
const { makeTailscaleModule } = await import("./harden-3KKCR7BL.js");
|
|
4353
|
+
const forStack = makeTailscaleModule(ctx.stackName);
|
|
4354
|
+
const resolved = resolveModules(MODULE_CATALOG, args.options, provider).map(
|
|
4355
|
+
(m) => m.id === "tailscale" ? forStack : m
|
|
4356
|
+
);
|
|
4357
|
+
const modules = args.tailscale && !resolved.some((m) => m.id === "tailscale") ? [...resolved, forStack] : resolved;
|
|
4294
4358
|
if (modules.length === 0) {
|
|
4295
4359
|
warn("No modules selected for this provider. Use --options to specify modules or --list to see all.");
|
|
4296
4360
|
return;
|
|
@@ -4368,6 +4432,16 @@ var harden_default = defineCommand23({
|
|
|
4368
4432
|
if (!args["dry-run"]) {
|
|
4369
4433
|
success("Hardening complete.");
|
|
4370
4434
|
}
|
|
4435
|
+
if (args.tailscale && !args["dry-run"]) {
|
|
4436
|
+
const { cutOverToTailnet } = await import("./flows-RI7FGHAM.js");
|
|
4437
|
+
process24.stdout.write("\nVerifying the tailnet address before using it...\n");
|
|
4438
|
+
const outcome = await cutOverToTailnet(ctx, conn, config);
|
|
4439
|
+
if (!outcome.ok) {
|
|
4440
|
+
failure(outcome.reason);
|
|
4441
|
+
process24.exit(1);
|
|
4442
|
+
}
|
|
4443
|
+
success(outcome.message);
|
|
4444
|
+
}
|
|
4371
4445
|
}
|
|
4372
4446
|
});
|
|
4373
4447
|
|
|
@@ -4390,7 +4464,7 @@ function handleError(err) {
|
|
|
4390
4464
|
}
|
|
4391
4465
|
|
|
4392
4466
|
// src/cli/index.ts
|
|
4393
|
-
var CLI_VERSION = true ? "2.0
|
|
4467
|
+
var CLI_VERSION = true ? "2.1.0" : "dev";
|
|
4394
4468
|
var main = defineCommand24({
|
|
4395
4469
|
meta: {
|
|
4396
4470
|
name: "clawops",
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
import {
|
|
3
3
|
buildContext,
|
|
4
4
|
loadAdapterModule
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-QDNFADJI.js";
|
|
6
|
+
import "./chunk-BELTQGHT.js";
|
|
7
7
|
import "./chunk-GIEVAGEK.js";
|
|
8
8
|
import "./chunk-VOEJYRIK.js";
|
|
9
9
|
import "./chunk-EI7CQQ7D.js";
|
|
10
10
|
import "./chunk-FEK7VJAY.js";
|
|
11
11
|
import "./chunk-RHOWYIWT.js";
|
|
12
12
|
import "./chunk-N4WZLWJ4.js";
|
|
13
|
-
import "./chunk-
|
|
14
|
-
import "./chunk-
|
|
13
|
+
import "./chunk-ELU3XQEA.js";
|
|
14
|
+
import "./chunk-64PONSA5.js";
|
|
15
15
|
import "./chunk-KGXPLI7W.js";
|
|
16
16
|
import "./chunk-VUFMZEIM.js";
|
|
17
17
|
export {
|