multiclaw 0.6.1 → 0.6.3

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/dist/index.js CHANGED
@@ -9,6 +9,7 @@ import { Command } from "commander";
9
9
  // src/commands/doctor.ts
10
10
  import {
11
11
  detectProviders,
12
+ hasExplicitTools,
12
13
  presentProviders,
13
14
  resolveCommand,
14
15
  resolveProvider,
@@ -113,13 +114,13 @@ function buildDoctorReport(detected, config) {
113
114
  const defaultsProvider = config.defaults?.provider;
114
115
  const defaultsProviderOk = !defaultsProvider || present.includes(defaultsProvider);
115
116
  const agents2 = [...config.agents];
116
- if (config.leader) agents2.push(config.leader);
117
+ if (config.leader && config.useLeader !== false) agents2.push(config.leader);
117
118
  const agentsWithMissingProvider = agents2.map((a) => ({ id: a.id, intended: resolveProvider(a, config) })).filter((a) => !present.includes(a.intended)).map((a) => a.id);
118
119
  const agentsWithUnsupportedTools = agents2.map((a) => {
119
120
  const command = resolveCommand(a, config);
120
121
  const spec = specForCommand(command) ?? specForProvider(resolveProvider(a, config));
121
- return { id: a.id, spec, tools: a.tools };
122
- }).filter((a) => a.spec && !a.spec.tools && a.tools !== void 0).map((a) => a.id);
122
+ return { id: a.id, spec, explicitTools: hasExplicitTools(a) };
123
+ }).filter((a) => a.spec && !a.spec.tools && a.explicitTools).map((a) => a.id);
123
124
  configReport = {
124
125
  name: config.name,
125
126
  defaultsProvider,
@@ -140,42 +141,35 @@ var RED = "\x1B[31m";
140
141
  var YELLOW = "\x1B[33m";
141
142
  var DIM = "\x1B[2m";
142
143
  var RESET = "\x1B[0m";
143
- var ANSI_RE = new RegExp(`${String.fromCharCode(27)}\\[[0-9;]*m`, "g");
144
144
  function color(enabled, code, text) {
145
145
  return enabled ? `${code}${text}${RESET}` : text;
146
146
  }
147
147
  function formatDoctorReport(report, useColor = true) {
148
148
  const lines = [];
149
149
  const c = (code, text) => color(useColor, code, text);
150
- const cell = (text, width, code) => {
151
- const plain = text.replace(ANSI_RE, "");
152
- const clipped = plain.length > width - 1 ? `${plain.slice(0, Math.max(0, width - 2))}\u2026` : plain;
153
- const rendered = code ? color(useColor, code, clipped) : clipped;
154
- return rendered + " ".repeat(Math.max(0, width - clipped.length));
155
- };
150
+ const statusLabel = (status) => status === "present" ? c(GREEN, "\u2713 available") : c(RED, "\u2717 missing");
151
+ const detail = (label, value, code) => ` ${c(DIM, `${label}:`)} ${code ? c(code, value) : value}`;
156
152
  lines.push("");
157
153
  lines.push(c(DIM, "multiclaw doctor \u2014 environment check"));
158
154
  lines.push("");
159
- lines.push(
160
- `${cell("provider", 12)}${cell("status", 10)}${cell("version", 14)}${cell("source", 9)}models auth`
161
- );
155
+ lines.push(c(DIM, "Providers"));
162
156
  for (const p of report.providers) {
163
- const mark = p.status === "present" ? "\u2713 present" : "\u2717 missing";
164
- const markCode = p.status === "present" ? GREEN : RED;
165
- const version = p.version ?? (p.status === "present" ? "" : "\u2014");
166
- const source = p.source ?? "\u2014";
167
- const sourceCode = p.source === "bundled" ? YELLOW : void 0;
168
- const models = p.modelSelection === "none" ? "n/a" : String(p.modelCount);
169
- const auth = p.authHint ? c(DIM, p.authHint) : "";
170
- lines.push(
171
- `${cell(p.label, 12)}${cell(mark, 10, markCode)}${cell(version, 14)}${cell(source, 9, sourceCode)}${cell(models, 7)}${auth}`
172
- );
173
- if (p.status === "present" && p.source === "bundled" && p.resolvedPath) {
174
- lines.push(c(DIM, ` bundled bridge: ${p.resolvedPath}`));
157
+ const title = `${statusLabel(p.status)} ${p.label}`;
158
+ lines.push(title);
159
+ if (p.version) lines.push(detail("version", p.version));
160
+ if (p.source) {
161
+ lines.push(detail("source", p.source, p.source === "bundled" ? YELLOW : void 0));
175
162
  }
163
+ const models = p.modelSelection === "none" ? "not supported" : String(p.modelCount);
164
+ lines.push(detail("models", models));
165
+ if (p.authHint) lines.push(detail("auth", p.authHint));
176
166
  if (p.status === "missing" && p.installHint) {
177
- lines.push(c(YELLOW, ` install: ${p.installHint}`));
167
+ lines.push(detail("install", p.installHint, YELLOW));
178
168
  }
169
+ if (p.status === "present" && p.source === "bundled" && p.resolvedPath) {
170
+ lines.push(detail("bridge", p.resolvedPath));
171
+ }
172
+ lines.push("");
179
173
  }
180
174
  if (report.config) {
181
175
  lines.push("");
@@ -485,14 +479,17 @@ import {
485
479
  // src/lib.ts
486
480
  import {
487
481
  detectProviders as detectProviders3,
482
+ hasExplicitTools as hasExplicitTools2,
488
483
  presentProviders as presentProviders2,
489
484
  resolveCommand as resolveCommand2,
490
- runtimeRegistry
485
+ runtimeRegistry,
486
+ validateToolsPolicy
491
487
  } from "@multiclawcli/core";
492
488
  import { agents, defineConfig } from "@multiclawcli/core";
493
489
  async function assertRuntimesAvailable(config) {
494
490
  const checked = /* @__PURE__ */ new Set();
495
- for (const agent of config.agents) {
491
+ const agents2 = config.leader && config.useLeader !== false && hasExplicitTools2(config.leader) ? [config.leader, ...config.agents] : config.agents;
492
+ for (const agent of agents2) {
496
493
  const name = agent.runtime ?? "acp";
497
494
  if (!runtimeRegistry.has(name)) {
498
495
  const supported = runtimeRegistry.list().join(", ");
@@ -512,6 +509,12 @@ async function assertRuntimesAvailable(config) {
512
509
  process.exit(1);
513
510
  }
514
511
  }
512
+ try {
513
+ await validateToolsPolicy(config);
514
+ } catch (error) {
515
+ console.error(`\x1B[31mError: ${error instanceof Error ? error.message : String(error)}\x1B[0m`);
516
+ process.exit(1);
517
+ }
515
518
  }
516
519
 
517
520
  // src/reporters/ConsoleReporter.ts
package/dist/lib.js CHANGED
@@ -1,14 +1,17 @@
1
1
  // src/lib.ts
2
2
  import {
3
3
  detectProviders,
4
+ hasExplicitTools,
4
5
  presentProviders,
5
6
  resolveCommand,
6
- runtimeRegistry
7
+ runtimeRegistry,
8
+ validateToolsPolicy
7
9
  } from "@multiclawcli/core";
8
10
  import { agents, defineConfig } from "@multiclawcli/core";
9
11
  async function assertRuntimesAvailable(config) {
10
12
  const checked = /* @__PURE__ */ new Set();
11
- for (const agent of config.agents) {
13
+ const agents2 = config.leader && config.useLeader !== false && hasExplicitTools(config.leader) ? [config.leader, ...config.agents] : config.agents;
14
+ for (const agent of agents2) {
12
15
  const name = agent.runtime ?? "acp";
13
16
  if (!runtimeRegistry.has(name)) {
14
17
  const supported = runtimeRegistry.list().join(", ");
@@ -28,6 +31,12 @@ async function assertRuntimesAvailable(config) {
28
31
  process.exit(1);
29
32
  }
30
33
  }
34
+ try {
35
+ await validateToolsPolicy(config);
36
+ } catch (error) {
37
+ console.error(`\x1B[31mError: ${error instanceof Error ? error.message : String(error)}\x1B[0m`);
38
+ process.exit(1);
39
+ }
31
40
  }
32
41
  async function availableRuntimes() {
33
42
  const detected = await detectProviders();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "multiclaw",
3
- "version": "0.6.1",
3
+ "version": "0.6.3",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "multiclaw": "dist/index.js"
@@ -30,8 +30,8 @@
30
30
  "@agentclientprotocol/claude-agent-acp": "^0.95.0",
31
31
  "@agentclientprotocol/codex-acp": "^2.2.2",
32
32
  "@inquirer/prompts": "^8.7.4",
33
- "@multiclawcli/core": "0.6.1",
34
- "@multiclawcli/dashboard": "0.6.1",
33
+ "@multiclawcli/core": "0.6.3",
34
+ "@multiclawcli/dashboard": "0.6.3",
35
35
  "commander": "^15.0.0",
36
36
  "jiti": "^2.7.0"
37
37
  },