@atbash/cli 0.6.0-dev.1 → 0.6.1-dev.2
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 +57 -8
- package/dist/bin/atbash.js +6 -3
- package/dist/bin/atbash.js.map +1 -1
- package/dist/commands/config-cmd.js +15 -15
- package/dist/commands/config-cmd.js.map +1 -1
- package/dist/commands/connect.d.ts +84 -24
- package/dist/commands/connect.js +289 -73
- package/dist/commands/connect.js.map +1 -1
- package/dist/commands/held.js +2 -2
- package/dist/commands/held.js.map +1 -1
- package/dist/commands/history.js +1 -1
- package/dist/commands/history.js.map +1 -1
- package/dist/commands/judge.js +2 -2
- package/dist/commands/judge.js.map +1 -1
- package/dist/commands/mcp-cmd.d.ts +13 -0
- package/dist/commands/mcp-cmd.js +216 -0
- package/dist/commands/mcp-cmd.js.map +1 -0
- package/dist/commands/policy.js +1 -1
- package/dist/commands/policy.js.map +1 -1
- package/dist/commands/setup.d.ts +390 -8
- package/dist/commands/setup.js +1873 -164
- package/dist/commands/setup.js.map +1 -1
- package/dist/commands/stats.js +1 -1
- package/dist/commands/stats.js.map +1 -1
- package/dist/commands/status.js +1 -1
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/tier.js +1 -1
- package/dist/commands/tier.js.map +1 -1
- package/dist/commands/tools.js +3 -3
- package/dist/commands/tools.js.map +1 -1
- package/dist/commands/whoami.js +1 -1
- package/dist/commands/whoami.js.map +1 -1
- package/dist/shared/atbash-targets.d.ts +49 -0
- package/dist/shared/atbash-targets.js +63 -0
- package/dist/shared/atbash-targets.js.map +1 -0
- package/dist/shared/openclaw-runtime.d.ts +221 -0
- package/dist/shared/openclaw-runtime.js +476 -0
- package/dist/shared/openclaw-runtime.js.map +1 -0
- package/dist/shared/win-exec.d.ts +63 -0
- package/dist/shared/win-exec.js +147 -0
- package/dist/shared/win-exec.js.map +1 -0
- package/package.json +3 -2
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.isWindowsShim = isWindowsShim;
|
|
7
|
+
exports.quoteArg = quoteArg;
|
|
8
|
+
exports.escapeForCmd = escapeForCmd;
|
|
9
|
+
exports.cmdLineFor = cmdLineFor;
|
|
10
|
+
exports.spawnPortable = spawnPortable;
|
|
11
|
+
exports.pickExecutable = pickExecutable;
|
|
12
|
+
/**
|
|
13
|
+
* Launching an npm-installed CLI on Windows, without opening a shell seam.
|
|
14
|
+
*
|
|
15
|
+
* `openclaw`, `hermes`, `npm` and every other Node CLI arrive on Windows as a
|
|
16
|
+
* `.cmd` shim, and a `.cmd` is not an executable — CreateProcess cannot run one.
|
|
17
|
+
* Node used to paper over that; since 18.20.2 / 20.12.2 (the CVE-2024-27980 fix)
|
|
18
|
+
* it refuses outright, and `spawnSync("openclaw.cmd", …)` fails with EINVAL
|
|
19
|
+
* unless the call goes through a shell. That is why every `openclaw` probe
|
|
20
|
+
* answered "could not run" on Windows while working everywhere else: detection
|
|
21
|
+
* did not misread the machine, it never reached the binary at all.
|
|
22
|
+
*
|
|
23
|
+
* ⚠️ THE OBVIOUS REPAIR, `shell: true`, IS THE WRONG ONE HERE. It concatenates
|
|
24
|
+
* the command and its arguments into ONE string for `cmd.exe` to re-parse, so a
|
|
25
|
+
* `&`, `|` or `%VAR%` anywhere in an argument — or in the install path, which is
|
|
26
|
+
* read off `where` and was never written by us — stops being data and becomes
|
|
27
|
+
* another command. This tool governs whether an agent's actions are allowed to
|
|
28
|
+
* happen; it does not get to introduce shell injection into its own probe path.
|
|
29
|
+
*
|
|
30
|
+
* So a shim is routed through `cmd.exe /d /s /c` explicitly, with the command
|
|
31
|
+
* line built here: each token is quoted for the child's own CRT parser and then
|
|
32
|
+
* caret-escaped for the `cmd.exe` pass that happens first. `shell: true` skips
|
|
33
|
+
* that second step, which is exactly the part that matters.
|
|
34
|
+
*
|
|
35
|
+
* Everything off Windows, and every real `.exe`, is spawned directly as before.
|
|
36
|
+
*/
|
|
37
|
+
const child_process_1 = require("child_process");
|
|
38
|
+
const path_1 = __importDefault(require("path"));
|
|
39
|
+
/** Batch shims — the two extensions `cmd.exe` must interpret for us. */
|
|
40
|
+
const SHIM = /\.(cmd|bat)$/i;
|
|
41
|
+
/**
|
|
42
|
+
* What `cmd.exe` acts on before the child ever sees the line.
|
|
43
|
+
*
|
|
44
|
+
* `%` is in here because `%FOO%` is expanded during that pass, which would
|
|
45
|
+
* otherwise substitute an environment variable into an argument — or blank it.
|
|
46
|
+
*/
|
|
47
|
+
const CMD_META = /[()%!^"<>&|]/g;
|
|
48
|
+
/** Does this command need `cmd.exe` to run at all? */
|
|
49
|
+
function isWindowsShim(command) {
|
|
50
|
+
return process.platform === "win32" && SHIM.test(command);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Quote one token the way the child's C runtime will parse it back.
|
|
54
|
+
*
|
|
55
|
+
* The backslash rule is the unobvious half: a backslash is literal EXCEPT in the
|
|
56
|
+
* run immediately before a quote, where each one must be doubled. `C:\dir\` as
|
|
57
|
+
* the last token would otherwise end `"C:\dir\"` — an escaped quote, which
|
|
58
|
+
* swallows the rest of the line.
|
|
59
|
+
*/
|
|
60
|
+
function quoteArg(arg) {
|
|
61
|
+
if (arg === "")
|
|
62
|
+
return '""';
|
|
63
|
+
if (!/[\s"\\]/.test(arg))
|
|
64
|
+
return arg;
|
|
65
|
+
const escaped = arg
|
|
66
|
+
.replace(/(\\*)"/g, '$1$1\\"') // double the run before a real quote, then escape it
|
|
67
|
+
.replace(/(\\*)$/, "$1$1"); // and the run before the quote we are about to add
|
|
68
|
+
return `"${escaped}"`;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Caret-escape a token for the `cmd.exe` parse.
|
|
72
|
+
*
|
|
73
|
+
* The quotes added by {@link quoteArg} are escaped too, deliberately. An escaped
|
|
74
|
+
* quote is literal text to `cmd.exe`, so it does not open a quoted section
|
|
75
|
+
* there, and arrives at the child as the plain `"` its CRT is expecting.
|
|
76
|
+
*/
|
|
77
|
+
function escapeForCmd(token) {
|
|
78
|
+
return token.replace(CMD_META, "^$&");
|
|
79
|
+
}
|
|
80
|
+
/** Build the full `cmd.exe` command line for a shim and its arguments. */
|
|
81
|
+
function cmdLineFor(command, args) {
|
|
82
|
+
return [command, ...args].map((a) => escapeForCmd(quoteArg(a))).join(" ");
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* `spawnSync`, but a Windows `.cmd`/`.bat` shim actually runs.
|
|
86
|
+
*
|
|
87
|
+
* Identical to `spawnSync` in every other case — same arguments, same return —
|
|
88
|
+
* so it is a drop-in at the call sites that probe an external CLI.
|
|
89
|
+
*/
|
|
90
|
+
function spawnPortable(command, args, options = {}) {
|
|
91
|
+
if (process.platform !== "win32") {
|
|
92
|
+
return (0, child_process_1.spawnSync)(command, args, options);
|
|
93
|
+
}
|
|
94
|
+
// A bare name like `openclaw` or `hermes` hides the problem rather than
|
|
95
|
+
// avoiding it: the PATH search resolves it to the same `.cmd`, and the launch
|
|
96
|
+
// fails just as hard, only without an extension to recognize it by. Resolve
|
|
97
|
+
// first, then decide.
|
|
98
|
+
const resolved = resolveOnWindows(command);
|
|
99
|
+
if (!isWindowsShim(resolved)) {
|
|
100
|
+
return (0, child_process_1.spawnSync)(resolved, args, options);
|
|
101
|
+
}
|
|
102
|
+
// `/d` skips AutoRun commands from the registry — someone else's startup script
|
|
103
|
+
// has no business running inside a read-only probe. `/s` fixes the quote rule to
|
|
104
|
+
// "strip the first and last", which is what makes the wrapping pair below safe.
|
|
105
|
+
const comspec = process.env.ComSpec || process.env.COMSPEC || "cmd.exe";
|
|
106
|
+
return (0, child_process_1.spawnSync)(comspec, ["/d", "/s", "/c", `"${cmdLineFor(resolved, args)}"`], {
|
|
107
|
+
...options,
|
|
108
|
+
// Node must pass our line through untouched — it is already quoted correctly,
|
|
109
|
+
// and a second round of Node's own quoting would break the escaping above.
|
|
110
|
+
windowsVerbatimArguments: true,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Turn a bare command name into the file Windows will actually launch.
|
|
115
|
+
*
|
|
116
|
+
* Anything already carrying a path is left alone — the caller has resolved it,
|
|
117
|
+
* and re-resolving could pick a different install off PATH than the one they
|
|
118
|
+
* meant. A name with no path goes through `where`, which is the same lookup the
|
|
119
|
+
* shell would do, so the answer matches what the operator sees.
|
|
120
|
+
*/
|
|
121
|
+
function resolveOnWindows(command) {
|
|
122
|
+
if (path_1.default.isAbsolute(command) || command.includes("\\") || command.includes("/"))
|
|
123
|
+
return command;
|
|
124
|
+
const where = (0, child_process_1.spawnSync)("where", [command], { encoding: "utf8" });
|
|
125
|
+
if (where.status !== 0)
|
|
126
|
+
return command;
|
|
127
|
+
return pickExecutable((where.stdout ?? "").split(/\r?\n/)) ?? command;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Pick the runnable match out of `where` output.
|
|
131
|
+
*
|
|
132
|
+
* `where openclaw` lists BOTH the extensionless POSIX-style script npm writes for
|
|
133
|
+
* Git Bash and the `openclaw.cmd` Windows actually uses, in that order. Taking
|
|
134
|
+
* the first line — which is what this did — hands back the one file on the list
|
|
135
|
+
* that Windows cannot execute.
|
|
136
|
+
*/
|
|
137
|
+
function pickExecutable(lines) {
|
|
138
|
+
const found = lines.map((l) => l.trim()).filter(Boolean);
|
|
139
|
+
if (found.length === 0)
|
|
140
|
+
return undefined;
|
|
141
|
+
const runnable = (process.env.PATHEXT || ".COM;.EXE;.BAT;.CMD")
|
|
142
|
+
.split(";")
|
|
143
|
+
.map((e) => e.trim().toLowerCase())
|
|
144
|
+
.filter(Boolean);
|
|
145
|
+
return found.find((f) => runnable.some((ext) => f.toLowerCase().endsWith(ext))) ?? found[0];
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=win-exec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"win-exec.js","sourceRoot":"","sources":["../../src/shared/win-exec.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atbash/cli",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.1-dev.2",
|
|
4
4
|
"description": "Atbash CLI — control boundary before the last irreversible step in an agent workflow",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"homepage": "https://atbash.ai",
|
|
@@ -26,13 +26,14 @@
|
|
|
26
26
|
"scripts": {
|
|
27
27
|
"clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
28
28
|
"build": "npm run clean && tsc",
|
|
29
|
+
"typecheck": "tsc --noEmit",
|
|
29
30
|
"test": "node scripts/run-tests.mjs",
|
|
30
31
|
"dev": "ts-node src/bin/atbash.ts",
|
|
31
32
|
"release": "npm version patch --no-git-tag-version && npm run build && npx npm@10 publish --access public",
|
|
32
33
|
"release:dev": "npm version prerelease --preid dev --no-git-tag-version && npm run build && npx npm@10 publish --tag dev --access public"
|
|
33
34
|
},
|
|
34
35
|
"dependencies": {
|
|
35
|
-
"@atbash/sdk": "0.
|
|
36
|
+
"@atbash/sdk": "0.13.0-dev.0",
|
|
36
37
|
"@iarna/toml": "2.2.5",
|
|
37
38
|
"chalk": "^4.1.2",
|
|
38
39
|
"commander": "^12.0.0",
|