@withone/cli 2.9.1 → 2.9.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 +8 -4
- package/bin/cli.js +7 -1
- package/dist/chunk-FYTWXGPJ.js +79 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +5 -0
- package/dist/node-check.d.ts +36 -0
- package/dist/node-check.js +18 -0
- package/package.json +2 -2
- package/skills/one/SKILL.md +2 -0
package/README.md
CHANGED
|
@@ -50,10 +50,14 @@ one logout # Clear credentials (with scope picker and confirmation)
|
|
|
50
50
|
|
|
51
51
|
The browser consent page names the key and tags it with where this CLI is installed (scope, project path, machine, OS user, CLI version, chosen harnesses, and the per-install device id unless telemetry is off) so you can find and revoke it from Settings → API keys. The terminal prints exactly what will be sent before the browser opens.
|
|
52
52
|
|
|
53
|
-
Requires Node.js
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
53
|
+
Requires Node.js 22.23.4+, 24.22.1+ or 26.12.1+. Older Node versions trust the
|
|
54
|
+
compromised eMudhra intermediate CA certificates (October 2026), so a network
|
|
55
|
+
attacker could intercept the CLI's traffic and your API key. On them the CLI
|
|
56
|
+
refuses to run and prints the command that updates Node for how you installed
|
|
57
|
+
it. Node 18, 20, 23 and 25 are end-of-life and never got the fix.
|
|
58
|
+
|
|
59
|
+
If you can't update Node yet, `ONE_ALLOW_UNPATCHED_NODE=1` runs the CLI anyway,
|
|
60
|
+
with a security warning on every run. You remain exposed while it is set.
|
|
57
61
|
|
|
58
62
|
## Quick start
|
|
59
63
|
|
package/bin/cli.js
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { requirePatchedNode } from '../dist/node-check.js';
|
|
4
|
+
|
|
5
|
+
// eMudhra CA compromise: refuse to run before any connection opens on a Node
|
|
6
|
+
// that still trusts the leaked intermediates (see src/node-check.ts).
|
|
7
|
+
requirePatchedNode();
|
|
8
|
+
|
|
9
|
+
const { program } = await import('../dist/index.js');
|
|
4
10
|
|
|
5
11
|
program.parse();
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// src/node-check.ts
|
|
2
|
+
var FIXED_IN = {
|
|
3
|
+
22: [23, 4],
|
|
4
|
+
24: [22, 1],
|
|
5
|
+
26: [12, 1]
|
|
6
|
+
};
|
|
7
|
+
var FIRST_LINE_WITH_FIX = 27;
|
|
8
|
+
var RECOMMENDED_LINE = 24;
|
|
9
|
+
var REQUIRED_NODE = "22.23.4+, 24.22.1+ or 26.12.1+";
|
|
10
|
+
var REQUIRED_NODE_RANGE = "^22.23.4 || ^24.22.1 || >=26.12.1";
|
|
11
|
+
var ALLOW_UNPATCHED_ENV = "ONE_ALLOW_UNPATCHED_NODE";
|
|
12
|
+
function parseVersion(version) {
|
|
13
|
+
const [major, minor, patch] = version.split(".").map((part) => Number.parseInt(part, 10));
|
|
14
|
+
return [major, minor, patch ?? 0];
|
|
15
|
+
}
|
|
16
|
+
function nodeHasTlsFix(version = process.versions.node) {
|
|
17
|
+
const [major, minor, patch] = parseVersion(version);
|
|
18
|
+
if (!Number.isFinite(major)) return false;
|
|
19
|
+
if (major >= FIRST_LINE_WITH_FIX) return true;
|
|
20
|
+
const fixed = FIXED_IN[major];
|
|
21
|
+
if (!fixed) return false;
|
|
22
|
+
const [fixedMinor, fixedPatch] = fixed;
|
|
23
|
+
return minor > fixedMinor || minor === fixedMinor && patch >= fixedPatch;
|
|
24
|
+
}
|
|
25
|
+
function upgradeCommand(version = process.versions.node, execPath = process.execPath) {
|
|
26
|
+
const [major] = parseVersion(version);
|
|
27
|
+
const line = FIXED_IN[major] ? major : RECOMMENDED_LINE;
|
|
28
|
+
const path = execPath.replace(/\\/g, "/");
|
|
29
|
+
if (/\/\.nvm\/versions\/node\//.test(path)) return `nvm install ${line} && nvm alias default ${line}`;
|
|
30
|
+
if (/\/AppData\/(Roaming|Local)\/nvm\//i.test(path)) return `nvm install ${line} && nvm use ${line}`;
|
|
31
|
+
if (/\/\.?volta\//i.test(path)) return `volta install node@${line}`;
|
|
32
|
+
if (/fnm/i.test(path)) return `fnm install ${line} && fnm default ${line}`;
|
|
33
|
+
const brew = path.match(/\/Cellar\/(node(?:@\d+)?)\//);
|
|
34
|
+
if (brew) {
|
|
35
|
+
const formula = brew[1] === "node" || FIXED_IN[major] ? brew[1] : `node@${line}`;
|
|
36
|
+
return formula === brew[1] ? `brew upgrade ${formula}` : `brew install ${formula}`;
|
|
37
|
+
}
|
|
38
|
+
return `download Node.js ${line} from https://nodejs.org`;
|
|
39
|
+
}
|
|
40
|
+
function unpatchedNodeMessage(version = process.versions.node) {
|
|
41
|
+
return `Node.js v${version} trusts the compromised eMudhra certificates, so a network attacker could intercept One's traffic and your API key. The One CLI requires Node.js ${REQUIRED_NODE} (Node 18, 20, 23 and 25 never got the fix).`;
|
|
42
|
+
}
|
|
43
|
+
function requirePatchedNode() {
|
|
44
|
+
if (nodeHasTlsFix()) return;
|
|
45
|
+
const message = unpatchedNodeMessage();
|
|
46
|
+
const upgrade = upgradeCommand();
|
|
47
|
+
const agent = process.argv.includes("--agent") || process.env.ONE_AGENT === "1";
|
|
48
|
+
if (process.env[ALLOW_UNPATCHED_ENV] === "1") {
|
|
49
|
+
if (!agent) process.stderr.write(`Warning: ${message} Running anyway because ${ALLOW_UNPATCHED_ENV}=1.
|
|
50
|
+
`);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (agent) {
|
|
54
|
+
const error = {
|
|
55
|
+
error: `${message} Ask the user to update Node.js: ${upgrade}`,
|
|
56
|
+
code: "NODE_UPGRADE_REQUIRED",
|
|
57
|
+
currentNode: process.versions.node,
|
|
58
|
+
requiredNode: REQUIRED_NODE_RANGE,
|
|
59
|
+
upgrade
|
|
60
|
+
};
|
|
61
|
+
process.stdout.write(`${JSON.stringify(error)}
|
|
62
|
+
`);
|
|
63
|
+
} else {
|
|
64
|
+
process.stderr.write(`Error: ${message}
|
|
65
|
+
To update: ${upgrade}
|
|
66
|
+
`);
|
|
67
|
+
}
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export {
|
|
72
|
+
REQUIRED_NODE,
|
|
73
|
+
REQUIRED_NODE_RANGE,
|
|
74
|
+
ALLOW_UNPATCHED_ENV,
|
|
75
|
+
nodeHasTlsFix,
|
|
76
|
+
upgradeCommand,
|
|
77
|
+
unpatchedNodeMessage,
|
|
78
|
+
requirePatchedNode
|
|
79
|
+
};
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
nodeHasTlsFix
|
|
3
|
+
} from "./chunk-FYTWXGPJ.js";
|
|
1
4
|
import {
|
|
2
5
|
ApiError,
|
|
3
6
|
FLOW_SCHEMA,
|
|
@@ -10917,6 +10920,7 @@ Request specific sections:
|
|
|
10917
10920
|
- **Always use \`--agent\` flag** for structured JSON output
|
|
10918
10921
|
- Platform names are **lowercase**; multi-word names use dashes (e.g., \`hubspot\`, \`google-calendar\`)
|
|
10919
10922
|
- Always use the **exact action ID** from a find answer \u2014 don't guess
|
|
10923
|
+
- Requires Node.js 22.23.4+, 24.22.1+ or 26.12.1+. Older Node trusts the compromised eMudhra CA certificates, so every command exits 1 there with \`"code": "NODE_UPGRADE_REQUIRED"\` and an \`upgrade\` field holding the command for the user's setup. Don't retry: show the user that command and ask them to update Node.js
|
|
10920
10924
|
- Always read **knowledge** before executing any action
|
|
10921
10925
|
- Connection keys come from \`one connection list\` \u2014 don't hardcode them
|
|
10922
10926
|
- \`connection list\` also reports an \`access\` field per connection (\`full\` / \`methods\` / \`actions\`, plus a \`level\`: full, read-write, read-only, custom, none) \u2014 what One enforces for this key, narrowed by \`one config\`. Read it before planning so you don't propose an action that will be refused. \`accessSource: "local"\` means One did not report it, so it is unverified
|
|
@@ -13441,5 +13445,6 @@ program.command("list").alias("ls").description("Shortcut for: connection list")
|
|
|
13441
13445
|
await connectionListCommand(options);
|
|
13442
13446
|
});
|
|
13443
13447
|
export {
|
|
13448
|
+
nodeHasTlsFix,
|
|
13444
13449
|
program
|
|
13445
13450
|
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Refuses to run on a Node.js that still trusts the compromised eMudhra
|
|
3
|
+
* intermediate CAs (October 2026, RUSTSEC-2026-0381).
|
|
4
|
+
*
|
|
5
|
+
* Eight eMudhra/emSign intermediates were created with 8-bit private keys, so
|
|
6
|
+
* anyone can compute them and sign a certificate for any domain, including
|
|
7
|
+
* api.withone.ai. Node.js blocks them inside the TLS handshake from 22.23.4,
|
|
8
|
+
* 24.22.1 and 26.12.1 (nodejs/node#66871). On any older Node, a network
|
|
9
|
+
* attacker can intercept the CLI's traffic and the user's API key, and nothing
|
|
10
|
+
* in userland can block the intermediates the way Node's fix does.
|
|
11
|
+
*
|
|
12
|
+
* Built as its own entry so bin/cli.js can run it before loading the rest of
|
|
13
|
+
* the CLI, and before any connection opens.
|
|
14
|
+
*/
|
|
15
|
+
declare const REQUIRED_NODE = "22.23.4+, 24.22.1+ or 26.12.1+";
|
|
16
|
+
declare const REQUIRED_NODE_RANGE = "^22.23.4 || ^24.22.1 || >=26.12.1";
|
|
17
|
+
/** Set to 1 to run on an unpatched Node anyway, with a warning on every run. */
|
|
18
|
+
declare const ALLOW_UNPATCHED_ENV = "ONE_ALLOW_UNPATCHED_NODE";
|
|
19
|
+
/** True when this Node version rejects chains through the compromised eMudhra intermediates. */
|
|
20
|
+
declare function nodeHasTlsFix(version?: string): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* The command that updates Node for however it was installed, judged from the
|
|
23
|
+
* path of the running binary. A line that got the fix stays on its line; any
|
|
24
|
+
* other moves to the recommended one.
|
|
25
|
+
*/
|
|
26
|
+
declare function upgradeCommand(version?: string, execPath?: string): string;
|
|
27
|
+
declare function unpatchedNodeMessage(version?: string): string;
|
|
28
|
+
/**
|
|
29
|
+
* Exits with an error on an unpatched Node; returns on a patched one. In agent
|
|
30
|
+
* mode the error is JSON on stdout with a code agents can act on. With
|
|
31
|
+
* ONE_ALLOW_UNPATCHED_NODE=1 it warns and returns instead (silently in agent
|
|
32
|
+
* mode, where stderr would corrupt the JSON for harnesses that merge streams).
|
|
33
|
+
*/
|
|
34
|
+
declare function requirePatchedNode(): void;
|
|
35
|
+
|
|
36
|
+
export { ALLOW_UNPATCHED_ENV, REQUIRED_NODE, REQUIRED_NODE_RANGE, nodeHasTlsFix, requirePatchedNode, unpatchedNodeMessage, upgradeCommand };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ALLOW_UNPATCHED_ENV,
|
|
3
|
+
REQUIRED_NODE,
|
|
4
|
+
REQUIRED_NODE_RANGE,
|
|
5
|
+
nodeHasTlsFix,
|
|
6
|
+
requirePatchedNode,
|
|
7
|
+
unpatchedNodeMessage,
|
|
8
|
+
upgradeCommand
|
|
9
|
+
} from "./chunk-FYTWXGPJ.js";
|
|
10
|
+
export {
|
|
11
|
+
ALLOW_UNPATCHED_ENV,
|
|
12
|
+
REQUIRED_NODE,
|
|
13
|
+
REQUIRED_NODE_RANGE,
|
|
14
|
+
nodeHasTlsFix,
|
|
15
|
+
requirePatchedNode,
|
|
16
|
+
unpatchedNodeMessage,
|
|
17
|
+
upgradeCommand
|
|
18
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@withone/cli",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.2",
|
|
4
4
|
"description": "CLI for managing One",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -52,6 +52,6 @@
|
|
|
52
52
|
"url": "https://github.com/withoneai/cli"
|
|
53
53
|
},
|
|
54
54
|
"engines": {
|
|
55
|
-
"node": ">=
|
|
55
|
+
"node": "^22.23.4 || ^24.22.1 || >=26.12.1"
|
|
56
56
|
}
|
|
57
57
|
}
|
package/skills/one/SKILL.md
CHANGED
|
@@ -171,6 +171,8 @@ All segments are validated before any execution. Failed actions don't block othe
|
|
|
171
171
|
|
|
172
172
|
All errors return JSON: `{"error": "message"}`. Parse output as JSON and check for the `error` key.
|
|
173
173
|
|
|
174
|
+
The CLI requires Node.js 22.23.4+, 24.22.1+ or 26.12.1+ (older Node trusts the compromised eMudhra CA certificates). On an older Node every command exits 1 with `"code": "NODE_UPGRADE_REQUIRED"` and an `upgrade` field holding the command for the user's setup. Don't retry: show the user that command and ask them to update Node.js.
|
|
175
|
+
|
|
174
176
|
## Important Rules
|
|
175
177
|
|
|
176
178
|
- Always use `--agent` flag for structured JSON output
|