agenticros 0.3.1 → 0.3.4
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 +13 -5
- package/dist/__tests__/claude-config.test.d.ts +2 -0
- package/dist/__tests__/claude-config.test.d.ts.map +1 -0
- package/dist/__tests__/claude-config.test.js +77 -0
- package/dist/__tests__/claude-config.test.js.map +1 -0
- package/dist/__tests__/hermes-config.test.d.ts +2 -0
- package/dist/__tests__/hermes-config.test.d.ts.map +1 -0
- package/dist/__tests__/hermes-config.test.js +88 -0
- package/dist/__tests__/hermes-config.test.js.map +1 -0
- package/dist/__tests__/mcp-setup.test.d.ts +2 -0
- package/dist/__tests__/mcp-setup.test.d.ts.map +1 -0
- package/dist/__tests__/mcp-setup.test.js +23 -0
- package/dist/__tests__/mcp-setup.test.js.map +1 -0
- package/dist/commands/claude.d.ts +16 -0
- package/dist/commands/claude.d.ts.map +1 -0
- package/dist/commands/claude.js +30 -0
- package/dist/commands/claude.js.map +1 -0
- package/dist/commands/codex.d.ts +4 -4
- package/dist/commands/codex.d.ts.map +1 -1
- package/dist/commands/codex.js +21 -90
- package/dist/commands/codex.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +30 -22
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/hermes.d.ts +14 -0
- package/dist/commands/hermes.d.ts.map +1 -0
- package/dist/commands/hermes.js +21 -0
- package/dist/commands/hermes.js.map +1 -0
- package/dist/commands/init.d.ts +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +16 -18
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/mcp.d.ts +20 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/mcp.js +31 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/index.js +76 -0
- package/dist/index.js.map +1 -1
- package/dist/util/claude-config.d.ts +47 -0
- package/dist/util/claude-config.d.ts.map +1 -0
- package/dist/util/claude-config.js +227 -0
- package/dist/util/claude-config.js.map +1 -0
- package/dist/util/hermes-config.d.ts +51 -0
- package/dist/util/hermes-config.d.ts.map +1 -0
- package/dist/util/hermes-config.js +277 -0
- package/dist/util/hermes-config.js.map +1 -0
- package/dist/util/mcp-setup.d.ts +55 -0
- package/dist/util/mcp-setup.d.ts.map +1 -0
- package/dist/util/mcp-setup.js +235 -0
- package/dist/util/mcp-setup.js.map +1 -0
- package/package.json +2 -1
- package/runtime/BUNDLE.json +1 -1
- package/runtime/README.md +87 -10
- package/runtime/docs/cli.md +89 -2
- package/runtime/packages/agenticros-claude-code/README.md +35 -0
package/README.md
CHANGED
|
@@ -3,14 +3,14 @@
|
|
|
3
3
|
> agentic AI for ROS-powered robots
|
|
4
4
|
|
|
5
5
|
`agenticros` is the unified command-line tool for AgenticROS — bring up a real
|
|
6
|
-
robot or a simulated one, drive it from Claude Code, OpenAI Codex, or OpenClaw,
|
|
6
|
+
robot or a simulated one, drive it from Claude Code, OpenAI Codex, Hermes Agent, or OpenClaw,
|
|
7
7
|
and keep your workspace healthy from a single binary.
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
10
|
# Brand new machine: one command end-to-end
|
|
11
|
-
npx agenticros init # workspace + plugin +
|
|
11
|
+
npx agenticros init # workspace + plugin + MCP clients + API key + doctor
|
|
12
12
|
agenticros # interactive menu
|
|
13
|
-
agenticros
|
|
13
|
+
agenticros mcp setup # register AgenticROS MCP for Codex, Hermes, and Claude
|
|
14
14
|
agenticros up real # bring up the real-robot stack
|
|
15
15
|
agenticros up sim-amr # bring up a simulated 2-wheel AMR
|
|
16
16
|
agenticros up sim-arm # bring up a simulated 6-DOF arm
|
|
@@ -54,8 +54,14 @@ Three ways, listed easiest first:
|
|
|
54
54
|
| `agenticros up sim-arm` | Bring up the simulated 6-DOF arm (UR5e-shaped, per-joint position control). |
|
|
55
55
|
| `agenticros down` | Stop everything we started. |
|
|
56
56
|
| `agenticros doctor` | Coloured health-check table; `--json` for CI. |
|
|
57
|
-
| `agenticros
|
|
57
|
+
| `agenticros mcp setup` | Register AgenticROS MCP for Codex, Hermes, and Claude (primary). |
|
|
58
|
+
| `agenticros mcp doctor` | Validate all MCP client configs. |
|
|
59
|
+
| `agenticros codex setup` | Codex only — `~/.codex/config.toml` (or `--project`). |
|
|
58
60
|
| `agenticros codex doctor` | Validate Codex MCP config paths and namespace policy. |
|
|
61
|
+
| `agenticros hermes setup` | Hermes only — `~/.hermes/config.yaml`. |
|
|
62
|
+
| `agenticros hermes doctor` | Validate Hermes MCP config paths and namespace policy. |
|
|
63
|
+
| `agenticros claude setup` | Claude only — Desktop + project `.mcp.json`. |
|
|
64
|
+
| `agenticros claude doctor` | Validate Claude MCP config paths and namespace policy. |
|
|
59
65
|
| `agenticros status` | Snapshot of running components + last mode. |
|
|
60
66
|
| `agenticros logs [target]` | Tail `camera` / `mcp` / `sim` / `rosbridge` / `gateway`. |
|
|
61
67
|
| `agenticros config [show\|set\|edit\|reset]` | Read or edit `~/.agenticros/config.json`. |
|
|
@@ -77,7 +83,8 @@ walks through:
|
|
|
77
83
|
5. Robot config (namespace, transport mode, sample `~/.agenticros/config.json`)
|
|
78
84
|
6. OpenAI API key (paste once → `scripts/configure_agenticros.sh`)
|
|
79
85
|
7. Codex MCP config (optional — `~/.codex/config.toml` and project `.codex/config.toml`)
|
|
80
|
-
8.
|
|
86
|
+
8. Hermes MCP config (optional — `~/.hermes/config.yaml`)
|
|
87
|
+
9. Final `agenticros doctor` summary
|
|
81
88
|
|
|
82
89
|
Every step is **idempotent**: it checks doctor first and skips the work if
|
|
83
90
|
nothing is missing. Use `agenticros init --force` to redo everything.
|
|
@@ -87,6 +94,7 @@ nothing is missing. Use `agenticros init --force` to redo everything.
|
|
|
87
94
|
- `~/.agenticros/config.json` — AgenticROS runtime config (transport mode,
|
|
88
95
|
robot namespace, safety limits, teleop defaults). Edited via `agenticros config`.
|
|
89
96
|
- `~/.codex/config.toml` — OpenAI Codex CLI MCP servers (written by `agenticros codex setup`).
|
|
97
|
+
- `~/.hermes/config.yaml` — Hermes Agent MCP servers (written by `agenticros hermes setup`).
|
|
90
98
|
- `~/.agenticros/cli-state.json` — CLI's own state (last mode, last namespace,
|
|
91
99
|
for the menu's "(yesterday)" hint).
|
|
92
100
|
- `~/agenticros/` — the install dir when invoked via `npx`. Contains a copy of
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-config.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/claude-config.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { mkdtempSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { describe, it } from "node:test";
|
|
5
|
+
import assert from "node:assert/strict";
|
|
6
|
+
import { buildAgenticrosMcpServerEntry, readClaudeAgenticrosConfig, upsertAgenticrosMcpJson, validateClaudeAgenticrosConfig, } from "../util/claude-config.js";
|
|
7
|
+
describe("claude-config", () => {
|
|
8
|
+
it("buildAgenticrosMcpServerEntry uses sh -c wrapper and empty namespace", () => {
|
|
9
|
+
const entry = buildAgenticrosMcpServerEntry("/opt/agenticros/dist/index.js");
|
|
10
|
+
assert.equal(entry["type"], "stdio");
|
|
11
|
+
assert.equal(entry["command"], "sh");
|
|
12
|
+
assert.deepEqual(entry["args"], [
|
|
13
|
+
"-c",
|
|
14
|
+
"node /opt/agenticros/dist/index.js 2>>/tmp/agenticros-mcp.log",
|
|
15
|
+
]);
|
|
16
|
+
assert.deepEqual(entry["env"], { AGENTICROS_ROBOT_NAMESPACE: "" });
|
|
17
|
+
});
|
|
18
|
+
it("upsertAgenticrosMcpJson preserves other servers", () => {
|
|
19
|
+
const existing = JSON.stringify({
|
|
20
|
+
mcpServers: {
|
|
21
|
+
other: { type: "stdio", command: "echo" },
|
|
22
|
+
agenticros: { type: "stdio", command: "node", args: ["old.js"] },
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
const entry = buildAgenticrosMcpServerEntry("/abs/index.js");
|
|
26
|
+
const merged = upsertAgenticrosMcpJson(existing, entry);
|
|
27
|
+
const parsed = JSON.parse(merged);
|
|
28
|
+
assert.ok(parsed.mcpServers.other);
|
|
29
|
+
assert.match(JSON.stringify(parsed.mcpServers.agenticros), /\/abs\/index.js/);
|
|
30
|
+
});
|
|
31
|
+
it("readClaudeAgenticrosConfig parses sh -c args", () => {
|
|
32
|
+
const dir = mkdtempSync(join(tmpdir(), "agenticros-claude-"));
|
|
33
|
+
const path = join(dir, ".mcp.json");
|
|
34
|
+
writeFileSync(path, JSON.stringify({
|
|
35
|
+
mcpServers: {
|
|
36
|
+
agenticros: {
|
|
37
|
+
type: "stdio",
|
|
38
|
+
command: "sh",
|
|
39
|
+
args: ["-c", "node /tmp/index.js 2>>/tmp/agenticros-mcp.log"],
|
|
40
|
+
env: { AGENTICROS_ROBOT_NAMESPACE: "" },
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
}));
|
|
44
|
+
const cfg = readClaudeAgenticrosConfig(path, "project");
|
|
45
|
+
assert.equal(cfg.command, "sh");
|
|
46
|
+
assert.deepEqual(cfg.args, ["-c", "node /tmp/index.js 2>>/tmp/agenticros-mcp.log"]);
|
|
47
|
+
assert.equal(cfg.env?.["AGENTICROS_ROBOT_NAMESPACE"], "");
|
|
48
|
+
});
|
|
49
|
+
it("validateClaudeAgenticrosConfig flags relative paths and hardcoded namespace", () => {
|
|
50
|
+
const cfg = {
|
|
51
|
+
configPath: "/tmp/.mcp.json",
|
|
52
|
+
exists: true,
|
|
53
|
+
target: "project",
|
|
54
|
+
command: "sh",
|
|
55
|
+
args: ["-c", "node packages/agenticros-claude-code/dist/index.js"],
|
|
56
|
+
env: { AGENTICROS_ROBOT_NAMESPACE: "robotabc" },
|
|
57
|
+
};
|
|
58
|
+
const v = validateClaudeAgenticrosConfig(cfg, "/abs/index.js");
|
|
59
|
+
assert.equal(v.ok, false);
|
|
60
|
+
assert.ok(v.issues.some((i) => i.message.includes("relative")));
|
|
61
|
+
assert.ok(v.issues.some((i) => i.message.includes("hardcoded")));
|
|
62
|
+
});
|
|
63
|
+
it("validateClaudeAgenticrosConfig passes for correct absolute config", () => {
|
|
64
|
+
const cfg = {
|
|
65
|
+
configPath: "/tmp/.mcp.json",
|
|
66
|
+
exists: true,
|
|
67
|
+
target: "project",
|
|
68
|
+
command: "sh",
|
|
69
|
+
args: ["-c", "node /abs/index.js 2>>/tmp/agenticros-mcp.log"],
|
|
70
|
+
env: { AGENTICROS_ROBOT_NAMESPACE: "" },
|
|
71
|
+
};
|
|
72
|
+
const v = validateClaudeAgenticrosConfig(cfg, "/abs/index.js");
|
|
73
|
+
assert.equal(v.ok, true);
|
|
74
|
+
assert.equal(v.issues.length, 0);
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
//# sourceMappingURL=claude-config.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-config.test.js","sourceRoot":"","sources":["../../src/__tests__/claude-config.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hermes-config.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/hermes-config.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { mkdtempSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { describe, it } from "node:test";
|
|
5
|
+
import assert from "node:assert/strict";
|
|
6
|
+
import { buildAgenticrosMcpYamlBlock, readHermesAgenticrosConfig, upsertAgenticrosBlock, validateHermesAgenticrosConfig, } from "../util/hermes-config.js";
|
|
7
|
+
describe("hermes-config", () => {
|
|
8
|
+
it("buildAgenticrosMcpYamlBlock uses absolute path and empty namespace", () => {
|
|
9
|
+
const block = buildAgenticrosMcpYamlBlock("/opt/agenticros/dist/index.js");
|
|
10
|
+
assert.match(block, /args: \["\/opt\/agenticros\/dist\/index.js"\]/);
|
|
11
|
+
assert.match(block, /AGENTICROS_ROBOT_NAMESPACE: ""/);
|
|
12
|
+
assert.match(block, /connect_timeout: 60/);
|
|
13
|
+
assert.match(block, /timeout: 120/);
|
|
14
|
+
});
|
|
15
|
+
it("upsertAgenticrosBlock replaces existing agenticros section", () => {
|
|
16
|
+
const existing = `llm:
|
|
17
|
+
provider: openrouter
|
|
18
|
+
|
|
19
|
+
mcp_servers:
|
|
20
|
+
other:
|
|
21
|
+
command: "echo"
|
|
22
|
+
agenticros:
|
|
23
|
+
command: "node"
|
|
24
|
+
args: ["relative/path.js"]
|
|
25
|
+
env:
|
|
26
|
+
AGENTICROS_ROBOT_NAMESPACE: "robot123"
|
|
27
|
+
`;
|
|
28
|
+
const block = buildAgenticrosMcpYamlBlock("/abs/index.js");
|
|
29
|
+
const merged = upsertAgenticrosBlock(existing, block);
|
|
30
|
+
assert.match(merged, /llm:/);
|
|
31
|
+
assert.match(merged, /other:/);
|
|
32
|
+
assert.match(merged, /\/abs\/index.js/);
|
|
33
|
+
assert.doesNotMatch(merged, /relative\/path\.js/);
|
|
34
|
+
assert.match(merged, /AGENTICROS_ROBOT_NAMESPACE: ""/);
|
|
35
|
+
});
|
|
36
|
+
it("upsertAgenticrosBlock appends mcp_servers when missing", () => {
|
|
37
|
+
const existing = "llm:\n provider: ollama\n";
|
|
38
|
+
const block = buildAgenticrosMcpYamlBlock("/abs/index.js");
|
|
39
|
+
const merged = upsertAgenticrosBlock(existing, block);
|
|
40
|
+
assert.match(merged, /mcp_servers:/);
|
|
41
|
+
assert.match(merged, /\/abs\/index.js/);
|
|
42
|
+
});
|
|
43
|
+
it("readHermesAgenticrosConfig parses stdio args and env", () => {
|
|
44
|
+
const dir = mkdtempSync(join(tmpdir(), "agenticros-hermes-"));
|
|
45
|
+
const path = join(dir, "config.yaml");
|
|
46
|
+
writeFileSync(path, `mcp_servers:
|
|
47
|
+
agenticros:
|
|
48
|
+
command: "node"
|
|
49
|
+
args: ["/tmp/index.js"]
|
|
50
|
+
env:
|
|
51
|
+
AGENTICROS_ROBOT_NAMESPACE: ""
|
|
52
|
+
connect_timeout: 60
|
|
53
|
+
timeout: 120
|
|
54
|
+
`);
|
|
55
|
+
const cfg = readHermesAgenticrosConfig(path);
|
|
56
|
+
assert.equal(cfg.command, "node");
|
|
57
|
+
assert.deepEqual(cfg.args, ["/tmp/index.js"]);
|
|
58
|
+
assert.equal(cfg.env?.["AGENTICROS_ROBOT_NAMESPACE"], "");
|
|
59
|
+
assert.equal(cfg.connectTimeout, 60);
|
|
60
|
+
assert.equal(cfg.timeout, 120);
|
|
61
|
+
});
|
|
62
|
+
it("validateHermesAgenticrosConfig flags relative paths and hardcoded namespace", () => {
|
|
63
|
+
const cfg = {
|
|
64
|
+
configPath: "/tmp/config.yaml",
|
|
65
|
+
exists: true,
|
|
66
|
+
command: "node",
|
|
67
|
+
args: ["packages/agenticros-claude-code/dist/index.js"],
|
|
68
|
+
env: { AGENTICROS_ROBOT_NAMESPACE: "robotabc" },
|
|
69
|
+
};
|
|
70
|
+
const v = validateHermesAgenticrosConfig(cfg, "/abs/index.js");
|
|
71
|
+
assert.equal(v.ok, false);
|
|
72
|
+
assert.ok(v.issues.some((i) => i.message.includes("relative")));
|
|
73
|
+
assert.ok(v.issues.some((i) => i.message.includes("hardcoded")));
|
|
74
|
+
});
|
|
75
|
+
it("validateHermesAgenticrosConfig passes for correct absolute config", () => {
|
|
76
|
+
const cfg = {
|
|
77
|
+
configPath: "/tmp/config.yaml",
|
|
78
|
+
exists: true,
|
|
79
|
+
command: "node",
|
|
80
|
+
args: ["/abs/index.js"],
|
|
81
|
+
env: { AGENTICROS_ROBOT_NAMESPACE: "" },
|
|
82
|
+
};
|
|
83
|
+
const v = validateHermesAgenticrosConfig(cfg, "/abs/index.js");
|
|
84
|
+
assert.equal(v.ok, true);
|
|
85
|
+
assert.equal(v.issues.length, 0);
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
//# sourceMappingURL=hermes-config.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hermes-config.test.js","sourceRoot":"","sources":["../../src/__tests__/hermes-config.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-setup.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/mcp-setup.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { describe, it } from "node:test";
|
|
2
|
+
import assert from "node:assert/strict";
|
|
3
|
+
import { buildMcpDoctorChecks, resolveMcpHosts } from "../util/mcp-setup.js";
|
|
4
|
+
describe("mcp-setup", () => {
|
|
5
|
+
it("resolveMcpHosts defaults to all three hosts", () => {
|
|
6
|
+
assert.deepEqual(resolveMcpHosts({}), ["codex", "hermes", "claude"]);
|
|
7
|
+
});
|
|
8
|
+
it("resolveMcpHosts honors explicit host flags", () => {
|
|
9
|
+
assert.deepEqual(resolveMcpHosts({ codex: true, hermes: false, claude: false }), ["codex"]);
|
|
10
|
+
assert.deepEqual(resolveMcpHosts({ hermes: true }), ["hermes"]);
|
|
11
|
+
assert.deepEqual(resolveMcpHosts({ claude: true }), ["claude"]);
|
|
12
|
+
});
|
|
13
|
+
it("resolveMcpHosts uses project scope for legacy codex setup", () => {
|
|
14
|
+
assert.deepEqual(resolveMcpHosts({ codexScope: "project" }), ["codex"]);
|
|
15
|
+
});
|
|
16
|
+
it("buildMcpDoctorChecks filters by host", () => {
|
|
17
|
+
const all = buildMcpDoctorChecks("/abs/index.js", "/repo");
|
|
18
|
+
const codexOnly = buildMcpDoctorChecks("/abs/index.js", "/repo", ["codex"]);
|
|
19
|
+
assert.ok(all.length > codexOnly.length);
|
|
20
|
+
assert.ok(codexOnly.every((c) => c.id.startsWith("codex")));
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
//# sourceMappingURL=mcp-setup.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-setup.test.js","sourceRoot":"","sources":["../../src/__tests__/mcp-setup.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AAExC,OAAO,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE7E,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IACzB,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACrD,MAAM,CAAC,SAAS,CAAC,eAAe,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACpD,MAAM,CAAC,SAAS,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QAC5F,MAAM,CAAC,SAAS,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;QAChE,MAAM,CAAC,SAAS,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,GAAG,EAAE;QACnE,MAAM,CAAC,SAAS,CAAC,eAAe,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,GAAG,GAAG,oBAAoB,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC;QAC3D,MAAM,SAAS,GAAG,oBAAoB,CAAC,eAAe,EAAE,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QAC5E,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;QACzC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC9D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `agenticros claude` — thin wrapper around unified MCP setup (Claude hosts).
|
|
3
|
+
*/
|
|
4
|
+
import { claudeOnPath } from "../util/mcp-setup.js";
|
|
5
|
+
export interface ClaudeSetupOptions {
|
|
6
|
+
project?: boolean;
|
|
7
|
+
desktop?: boolean;
|
|
8
|
+
quiet?: boolean;
|
|
9
|
+
}
|
|
10
|
+
export interface ClaudeDoctorOptions {
|
|
11
|
+
json?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export { claudeOnPath };
|
|
14
|
+
export declare function claudeSetupCommand(opts?: ClaudeSetupOptions): Promise<void>;
|
|
15
|
+
export declare function claudeDoctorCommand(opts?: ClaudeDoctorOptions): Promise<number>;
|
|
16
|
+
//# sourceMappingURL=claude.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../src/commands/claude.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,YAAY,EAAqC,MAAM,sBAAsB,CAAC;AAGvF,MAAM,WAAW,kBAAkB;IACjC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,OAAO,EAAE,YAAY,EAAE,CAAC;AAExB,wBAAsB,kBAAkB,CAAC,IAAI,GAAE,kBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAerF;AAED,wBAAsB,mBAAmB,CAAC,IAAI,GAAE,mBAAwB,GAAG,OAAO,CAAC,MAAM,CAAC,CAMzF"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `agenticros claude` — thin wrapper around unified MCP setup (Claude hosts).
|
|
3
|
+
*/
|
|
4
|
+
import { header } from "../util/logger.js";
|
|
5
|
+
import { claudeOnPath, mcpDoctorCommand, mcpSetupCommand } from "../util/mcp-setup.js";
|
|
6
|
+
import { getCliPaths } from "../util/paths.js";
|
|
7
|
+
export { claudeOnPath };
|
|
8
|
+
export async function claudeSetupCommand(opts = {}) {
|
|
9
|
+
const paths = getCliPaths();
|
|
10
|
+
const desktopOnly = opts.desktop && !opts.project;
|
|
11
|
+
const projectOnly = opts.project && !opts.desktop;
|
|
12
|
+
await mcpSetupCommand({
|
|
13
|
+
codex: false,
|
|
14
|
+
hermes: false,
|
|
15
|
+
claude: true,
|
|
16
|
+
all: false,
|
|
17
|
+
project: projectOnly || (!desktopOnly && !!paths.repoRoot),
|
|
18
|
+
desktop: desktopOnly || !projectOnly,
|
|
19
|
+
repoRoot: paths.repoRoot,
|
|
20
|
+
quiet: opts.quiet,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
export async function claudeDoctorCommand(opts = {}) {
|
|
24
|
+
if (!opts.json) {
|
|
25
|
+
header("Claude MCP doctor");
|
|
26
|
+
}
|
|
27
|
+
const paths = getCliPaths();
|
|
28
|
+
return mcpDoctorCommand({ json: opts.json, hosts: ["claude"], repoRoot: paths.repoRoot });
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=claude.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../../src/commands/claude.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvF,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAY/C,OAAO,EAAE,YAAY,EAAE,CAAC;AAExB,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAA2B,EAAE;IACpE,MAAM,KAAK,GAAG,WAAW,EAAE,CAAC;IAC5B,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;IAClD,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC;IAElD,MAAM,eAAe,CAAC;QACpB,KAAK,EAAE,KAAK;QACZ,MAAM,EAAE,KAAK;QACb,MAAM,EAAE,IAAI;QACZ,GAAG,EAAE,KAAK;QACV,OAAO,EAAE,WAAW,IAAI,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC;QAC1D,OAAO,EAAE,WAAW,IAAI,CAAC,WAAW;QACpC,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,KAAK,EAAE,IAAI,CAAC,KAAK;KAClB,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,OAA4B,EAAE;IACtE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACf,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAC9B,CAAC;IACD,MAAM,KAAK,GAAG,WAAW,EAAE,CAAC;IAC5B,OAAO,gBAAgB,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;AAC5F,CAAC"}
|
package/dist/commands/codex.d.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `agenticros codex` —
|
|
2
|
+
* `agenticros codex` — thin wrapper around unified MCP setup (Codex host).
|
|
3
3
|
*/
|
|
4
4
|
import { type CodexConfigScope } from "../util/codex-config.js";
|
|
5
|
+
import { codexOnPath } from "../util/mcp-setup.js";
|
|
6
|
+
export type { CodexConfigScope };
|
|
5
7
|
export interface CodexSetupOptions {
|
|
6
8
|
scope?: CodexConfigScope;
|
|
7
|
-
/** Skip interactive confirmation when codex CLI is missing. */
|
|
8
9
|
yes?: boolean;
|
|
9
|
-
/** Suppress the section header (e.g. when called from `agenticros init`). */
|
|
10
10
|
quiet?: boolean;
|
|
11
11
|
}
|
|
12
12
|
export interface CodexDoctorOptions {
|
|
13
13
|
json?: boolean;
|
|
14
14
|
}
|
|
15
|
-
export
|
|
15
|
+
export { codexOnPath };
|
|
16
16
|
export declare function codexSetupCommand(opts?: CodexSetupOptions): Promise<void>;
|
|
17
17
|
export declare function codexDoctorCommand(opts?: CodexDoctorOptions): Promise<number>;
|
|
18
18
|
//# sourceMappingURL=codex.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../src/commands/codex.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"codex.d.ts","sourceRoot":"","sources":["../../src/commands/codex.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,OAAO,EAAE,WAAW,EAAqC,MAAM,sBAAsB,CAAC;AAEtF,YAAY,EAAE,gBAAgB,EAAE,CAAC;AAEjC,MAAM,WAAW,iBAAiB;IAChC,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,OAAO,EAAE,WAAW,EAAE,CAAC;AAEvB,wBAAsB,iBAAiB,CAAC,IAAI,GAAE,iBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBnF;AAED,wBAAsB,kBAAkB,CAAC,IAAI,GAAE,kBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC,CAKvF"}
|
package/dist/commands/codex.js
CHANGED
|
@@ -1,99 +1,30 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* `agenticros codex` —
|
|
2
|
+
* `agenticros codex` — thin wrapper around unified MCP setup (Codex host).
|
|
3
3
|
*/
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
import { getCliPaths } from "../util/paths.js";
|
|
8
|
-
import { colors, header, info, ok, warn, err } from "../util/logger.js";
|
|
9
|
-
export async function codexOnPath() {
|
|
10
|
-
try {
|
|
11
|
-
const { exitCode } = await execa("codex", ["--version"], { reject: false });
|
|
12
|
-
return exitCode === 0;
|
|
13
|
-
}
|
|
14
|
-
catch {
|
|
15
|
-
return false;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
4
|
+
import { header } from "../util/logger.js";
|
|
5
|
+
import { codexOnPath, mcpDoctorCommand, mcpSetupCommand } from "../util/mcp-setup.js";
|
|
6
|
+
export { codexOnPath };
|
|
18
7
|
export async function codexSetupCommand(opts = {}) {
|
|
19
|
-
if (!opts.quiet) {
|
|
20
|
-
header("Configure Codex MCP");
|
|
21
|
-
}
|
|
22
|
-
const mcpEntry = findMcpEntry();
|
|
23
|
-
if (!mcpEntry) {
|
|
24
|
-
err("AgenticROS MCP server is not built.");
|
|
25
|
-
info("Run `pnpm --filter @agenticros/claude-code build` or `agenticros init` first.");
|
|
26
|
-
process.exit(1);
|
|
27
|
-
}
|
|
28
8
|
const scope = opts.scope ?? "global";
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
9
|
+
if (scope === "project") {
|
|
10
|
+
await mcpSetupCommand({
|
|
11
|
+
codex: true,
|
|
12
|
+
codexScope: "project",
|
|
13
|
+
quiet: opts.quiet,
|
|
14
|
+
});
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
await mcpSetupCommand({
|
|
18
|
+
codex: true,
|
|
19
|
+
hermes: false,
|
|
20
|
+
claude: false,
|
|
21
|
+
quiet: opts.quiet,
|
|
22
|
+
});
|
|
44
23
|
}
|
|
45
24
|
export async function codexDoctorCommand(opts = {}) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
const candidates = [
|
|
49
|
-
{ label: "global", path: globalCodexConfigPath() },
|
|
50
|
-
];
|
|
51
|
-
if (paths.repoRoot) {
|
|
52
|
-
candidates.push({ label: "project", path: projectCodexConfigPath(paths.repoRoot) });
|
|
53
|
-
}
|
|
54
|
-
const results = candidates.map((c) => {
|
|
55
|
-
const cfg = readCodexAgenticrosConfig(c.path);
|
|
56
|
-
const validation = validateCodexAgenticrosConfig(cfg, mcpEntry);
|
|
57
|
-
return { ...c, cfg, validation };
|
|
58
|
-
});
|
|
59
|
-
if (opts.json) {
|
|
60
|
-
process.stdout.write(`${JSON.stringify({ results, mcpEntry }, null, 2)}\n`);
|
|
61
|
-
const anyRed = results.some((r) => r.validation.issues.some((i) => i.severity === "red"));
|
|
62
|
-
return anyRed ? 1 : 0;
|
|
25
|
+
if (!opts.json) {
|
|
26
|
+
header("Codex MCP doctor");
|
|
63
27
|
}
|
|
64
|
-
|
|
65
|
-
if (!mcpEntry) {
|
|
66
|
-
err("MCP server not built.");
|
|
67
|
-
return 1;
|
|
68
|
-
}
|
|
69
|
-
info(`Expected MCP entry: ${mcpEntry}\n`);
|
|
70
|
-
let exitCode = 0;
|
|
71
|
-
for (const r of results) {
|
|
72
|
-
process.stdout.write(`${colors.bold(r.label)} (${r.path})\n`);
|
|
73
|
-
if (!r.cfg.exists) {
|
|
74
|
-
process.stdout.write(` ${colors.yellow("○")} Config file not present\n`);
|
|
75
|
-
process.stdout.write(` ${colors.dim("→ Run `agenticros codex setup" + (r.label === "project" ? " --project" : "") + "`")}\n`);
|
|
76
|
-
if (r.label === "global")
|
|
77
|
-
exitCode = 1;
|
|
78
|
-
continue;
|
|
79
|
-
}
|
|
80
|
-
if (r.validation.ok) {
|
|
81
|
-
process.stdout.write(` ${colors.green("✓")} agenticros MCP configured correctly\n`);
|
|
82
|
-
continue;
|
|
83
|
-
}
|
|
84
|
-
for (const issue of r.validation.issues) {
|
|
85
|
-
const icon = issue.severity === "red" ? colors.red("✗") : colors.yellow("○");
|
|
86
|
-
process.stdout.write(` ${icon} ${issue.message}\n`);
|
|
87
|
-
if (issue.hint) {
|
|
88
|
-
process.stdout.write(` ${colors.dim("→ " + issue.hint)}\n`);
|
|
89
|
-
}
|
|
90
|
-
if (issue.severity === "red")
|
|
91
|
-
exitCode = 1;
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
return exitCode;
|
|
95
|
-
}
|
|
96
|
-
function dimHint(message) {
|
|
97
|
-
process.stdout.write(`${colors.dim(message)}\n`);
|
|
28
|
+
return mcpDoctorCommand({ json: opts.json, hosts: ["codex"] });
|
|
98
29
|
}
|
|
99
30
|
//# sourceMappingURL=codex.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/commands/codex.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/commands/codex.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AActF,OAAO,EAAE,WAAW,EAAE,CAAC;AAEvB,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,OAA0B,EAAE;IAClE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC;IAErC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,MAAM,eAAe,CAAC;YACpB,KAAK,EAAE,IAAI;YACX,UAAU,EAAE,SAAS;YACrB,KAAK,EAAE,IAAI,CAAC,KAAK;SAClB,CAAC,CAAC;QACH,OAAO;IACT,CAAC;IAED,MAAM,eAAe,CAAC;QACpB,KAAK,EAAE,IAAI;QACX,MAAM,EAAE,KAAK;QACb,MAAM,EAAE,KAAK;QACb,KAAK,EAAE,IAAI,CAAC,KAAK;KAClB,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAA2B,EAAE;IACpE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACf,MAAM,CAAC,kBAAkB,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,gBAAgB,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AACjE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAyBH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;AAElD,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,WAAW,EAAE,CAAC;IACtB,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;CACzD;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CA+BxE;AAED,sFAAsF;AACtF,wBAAsB,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC,CAGrD;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,YAAY,CAAC,CA0Z7D"}
|
package/dist/commands/doctor.js
CHANGED
|
@@ -16,8 +16,8 @@ import { colors, header, ok, warn, err, info } from "../util/logger.js";
|
|
|
16
16
|
import { activeConfigPath, profilesDir, readActiveMode } from "../util/profiles.js";
|
|
17
17
|
import { ensureToolsAlsoAllow, readAgenticrosContractTools, readOpenclawConfig, } from "../util/openclaw-config.js";
|
|
18
18
|
import { listSkills } from "../util/skills.js";
|
|
19
|
-
import { buildCodexDoctorChecks } from "../util/codex-config.js";
|
|
20
19
|
import { findMcpEntry } from "../util/mcp-discovery.js";
|
|
20
|
+
import { buildMcpDoctorChecks, claudeOnPath, codexOnPath, hermesOnPath, } from "../util/mcp-setup.js";
|
|
21
21
|
export async function doctorCommand(opts) {
|
|
22
22
|
const report = await runDoctorChecks();
|
|
23
23
|
if (opts.json) {
|
|
@@ -206,28 +206,36 @@ export async function runDoctorChecks() {
|
|
|
206
206
|
: "Fine for real-robot mode if the value matches your robot's namespace.",
|
|
207
207
|
});
|
|
208
208
|
}
|
|
209
|
-
// Codex
|
|
209
|
+
// MCP client configs (Codex, Hermes, Claude).
|
|
210
210
|
const mcpEntry = findMcpEntry();
|
|
211
|
-
checks.push(...
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
211
|
+
checks.push(...buildMcpDoctorChecks(mcpEntry, paths.repoRoot));
|
|
212
|
+
const hasCodex = await codexOnPath();
|
|
213
|
+
checks.push({
|
|
214
|
+
id: "codex-cli",
|
|
215
|
+
label: hasCodex ? "Codex CLI installed" : "Codex CLI not detected",
|
|
216
|
+
severity: hasCodex ? "green" : "yellow",
|
|
217
|
+
hint: hasCodex
|
|
218
|
+
? undefined
|
|
219
|
+
: "Install from https://developers.openai.com/codex/ then run `agenticros mcp setup --codex`.",
|
|
220
|
+
});
|
|
221
|
+
const hasHermes = await hermesOnPath();
|
|
222
|
+
checks.push({
|
|
223
|
+
id: "hermes-cli",
|
|
224
|
+
label: hasHermes ? "Hermes CLI installed" : "Hermes CLI not detected",
|
|
225
|
+
severity: hasHermes ? "green" : "yellow",
|
|
226
|
+
hint: hasHermes
|
|
227
|
+
? undefined
|
|
228
|
+
: "Install from https://github.com/NousResearch/hermes-agent then run `agenticros mcp setup --hermes`.",
|
|
229
|
+
});
|
|
230
|
+
const hasClaude = await claudeOnPath();
|
|
231
|
+
checks.push({
|
|
232
|
+
id: "claude-cli",
|
|
233
|
+
label: hasClaude ? "Claude Code CLI installed" : "Claude Code CLI not detected",
|
|
234
|
+
severity: hasClaude ? "green" : "yellow",
|
|
235
|
+
hint: hasClaude
|
|
236
|
+
? undefined
|
|
237
|
+
: "Install from https://claude.com/product/claude-code then run `agenticros mcp setup --claude`.",
|
|
238
|
+
});
|
|
231
239
|
// OpenAI key.
|
|
232
240
|
const home = process.env["HOME"] ?? "";
|
|
233
241
|
const authFile = join(home, ".openclaw", "agents", "main", "agent", "auth-profiles.json");
|