multiclaw 0.10.0 → 0.10.1

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.
@@ -9,24 +9,12 @@
9
9
  * `agents.<id>(` in the block string.
10
10
  */
11
11
  export declare const PRESET_AGENT_IDS: Record<string, string[]>;
12
- /**
13
- * The override choices for a preset: the leader (which belongs to no preset)
14
- * plus the preset's own agents. Filtering by preset is what stops an override
15
- * for an agent the preset does not contain from being offered and then dropped.
16
- */
17
- export declare function overrideChoices(preset: string): Array<{
18
- value: string;
19
- name: string;
20
- }>;
21
12
  export declare function generateConfig(opts: {
22
13
  preset: string;
23
14
  workDir: string;
24
15
  projectName: string;
25
16
  provider: string;
26
- model?: string;
27
- overrides?: Array<{
28
- id: string;
29
- model: string;
30
- }>;
31
17
  }): string;
32
- export declare function initCommand(): Promise<void>;
18
+ export declare function initCommand(options?: {
19
+ force?: boolean;
20
+ }): Promise<void>;
package/dist/index.js CHANGED
@@ -232,8 +232,8 @@ async function loadConfigSafe(configPath) {
232
232
  // src/commands/init.ts
233
233
  import * as fs2 from "fs";
234
234
  import * as path2 from "path";
235
- import { checkbox, input, Separator, select } from "@inquirer/prompts";
236
- import { detectProviders as detectProviders2, specForProvider as specForProvider2, tierModel } from "@multiclawcli/core";
235
+ import { input, select } from "@inquirer/prompts";
236
+ import { detectProviders as detectProviders2, specForProvider as specForProvider2 } from "@multiclawcli/core";
237
237
  var AGENT_BLOCKS = {
238
238
  backend: ` agents.productManager(),
239
239
  agents.architect({ dependsOn: ["product-manager"] }),
@@ -264,101 +264,37 @@ var PRESET_DESCRIPTIONS = {
264
264
  frontend: "Architect \u2192 UI Designer \u2192 UI Design Reviewer \u2192 Frontend Developer \u2192 Tester \u2192 Code Reviewer (6 agents)",
265
265
  fullstack: "Product Manager \u2192 Architect \u2192 Arch Design Reviewer \u2192 Backend Developer + UI Designer \u2192 UI Design Reviewer \u2192 Frontend Developer \u2192 Tester \u2192 Code Reviewer + DevOps (10 agents)"
266
266
  };
267
- var PRESET_AGENT_IDS = {
268
- backend: [
269
- "productManager",
270
- "architect",
271
- "archDesignReviewer",
272
- "backendDeveloper",
273
- "tester",
274
- "codeReviewer",
275
- "devops"
276
- ],
277
- frontend: [
278
- "architect",
279
- "uiDesigner",
280
- "uiDesignReviewer",
281
- "frontendDeveloper",
282
- "tester",
283
- "codeReviewer"
284
- ],
285
- fullstack: [
286
- "productManager",
287
- "architect",
288
- "archDesignReviewer",
289
- "backendDeveloper",
290
- "uiDesigner",
291
- "uiDesignReviewer",
292
- "frontendDeveloper",
293
- "tester",
294
- "codeReviewer",
295
- "devops"
296
- ]
297
- };
298
- var OVERRIDE_LABELS = {
299
- leader: "\u2605 Leader",
300
- productManager: "Product Manager",
301
- architect: "Architect",
302
- archDesignReviewer: "Arch Design Reviewer",
303
- backendDeveloper: "Backend Developer",
304
- frontendDeveloper: "Frontend Developer",
305
- uiDesigner: "UI Designer",
306
- uiDesignReviewer: "UI Design Reviewer",
307
- tester: "Tester",
308
- codeReviewer: "Code Reviewer",
309
- devops: "DevOps"
310
- };
311
- function overrideChoices(preset) {
312
- const ids = PRESET_AGENT_IDS[preset] ?? [];
313
- return [
314
- { value: "leader", name: OVERRIDE_LABELS.leader },
315
- ...ids.map((id) => ({ value: id, name: OVERRIDE_LABELS[id] ?? id }))
316
- ];
317
- }
318
267
  function generateConfig(opts) {
319
268
  const name = JSON.stringify(opts.projectName);
320
269
  const workDir = JSON.stringify(opts.workDir);
321
- const defaultsParts = [`provider: ${JSON.stringify(opts.provider)}`];
322
- if (opts.model) defaultsParts.push(`model: ${JSON.stringify(opts.model)}`);
323
- const leaderOverride = opts.overrides?.find((o) => o.id === "leader");
324
- const leaderLine = leaderOverride ? ` leader: agents.leader({ model: ${JSON.stringify(leaderOverride.model)} }),` : ` leader: agents.leader(),`;
325
- let agentBlock = AGENT_BLOCKS[opts.preset];
326
- if (opts.overrides && opts.overrides.length > 0) {
327
- for (const ov of opts.overrides) {
328
- const id = ov.id;
329
- if (id === "leader") continue;
330
- const model = JSON.stringify(ov.model);
331
- const re = new RegExp(`(agents\\.${id}\\([^)]*\\))`, "g");
332
- agentBlock = agentBlock.replace(re, (match) => {
333
- const body = match.slice(id.length + 8, -1).trim().replace(/^\{/, "").replace(/\}$/, "").trim();
334
- const sep = body ? ", " : "";
335
- return `agents.${id}({ ${body}${sep}model: ${model} })`;
336
- });
337
- }
338
- }
339
270
  return `import { defineConfig, agents } from "multiclaw"
340
271
 
341
272
  export default defineConfig({
342
273
  name: ${name},
343
274
  workDir: ${workDir},
344
- ${leaderLine}
275
+ leader: agents.leader(),
345
276
  context: {
346
277
  projectName: ${name},
347
278
  },
348
279
  defaults: {
349
- ${defaultsParts.join(",\n ")},
280
+ provider: ${JSON.stringify(opts.provider)},
350
281
  },
351
282
  agents: [
352
- ${agentBlock}
283
+ ${AGENT_BLOCKS[opts.preset]}
353
284
  ],
354
285
  })
355
286
  `;
356
287
  }
357
- async function initCommand() {
288
+ async function initCommand(options = {}) {
358
289
  const configPath = path2.resolve(process.cwd(), "multiclaw.config.ts");
359
290
  if (fs2.existsSync(configPath)) {
360
- console.error("\x1B[31mError: multiclaw.config.ts already exists\x1B[0m");
361
- process.exit(1);
291
+ if (!options.force) {
292
+ console.error(
293
+ "\x1B[31mError: multiclaw.config.ts already exists (use --force to overwrite)\x1B[0m"
294
+ );
295
+ process.exit(1);
296
+ }
297
+ console.log("\x1B[33mWarning: overwriting existing multiclaw.config.ts\x1B[0m");
362
298
  }
363
299
  const defaultProjectName = path2.basename(process.cwd());
364
300
  const projectName = await input({
@@ -386,45 +322,12 @@ async function initCommand() {
386
322
  if (!spec) {
387
323
  throw new Error(`Unknown provider: ${provider}`);
388
324
  }
389
- const modelAnswer = await select({
390
- message: "Team model preference:",
391
- choices: [
392
- { value: "", name: "Role-based tier defaults (recommended)" },
393
- new Separator("---"),
394
- ...[
395
- { label: "Strong (architect, devops)", tier: "strong" },
396
- { label: "Balanced (backend, frontend)", tier: "balanced" },
397
- { label: "Fast (reviewer, tester)", tier: "fast" }
398
- ].map((t) => {
399
- const m = tierModel(spec, t.tier);
400
- return m ? { value: m, name: `${t.label} \u2192 ${m}` } : void 0;
401
- }).filter((x) => x !== void 0),
402
- new Separator("---"),
403
- ...spec.models.map((m) => ({ value: m.id, name: m.label }))
404
- ]
405
- });
406
- const modelDefault = modelAnswer || void 0;
407
- const overrideIds = await checkbox({
408
- message: "Override model for specific agents? (space to select, enter to confirm)",
409
- choices: overrideChoices(preset)
410
- });
411
- const overrides = [];
412
- for (const id of overrideIds) {
413
- const ov = await select({
414
- message: `Model for ${id}:`.replace(/([A-Z])/g, " $1").replace(/^./, (c) => c.toUpperCase()),
415
- choices: spec.models.map((m) => ({ value: m.id, name: m.label }))
416
- });
417
- overrides.push({ id, model: ov });
418
- }
419
325
  const workDir = await input({
420
326
  message: "Work directory (where agents read and write files):",
421
327
  default: "."
422
328
  });
423
329
  try {
424
- fs2.writeFileSync(
425
- configPath,
426
- generateConfig({ preset, workDir, projectName, provider, model: modelDefault, overrides })
427
- );
330
+ fs2.writeFileSync(configPath, generateConfig({ preset, workDir, projectName, provider }));
428
331
  if (workDir !== ".") {
429
332
  fs2.mkdirSync(path2.resolve(process.cwd(), workDir), { recursive: true });
430
333
  }
@@ -442,11 +345,7 @@ async function initCommand() {
442
345
  ` ${detectedProvider.command}${detectedProvider.version ? ` ${detectedProvider.version}` : ""}`
443
346
  );
444
347
  }
445
- console.log(` model: ${modelDefault || "role-based tier defaults"}`);
446
348
  console.log(` workDir: ${workDir}`);
447
- if (overrides.length > 0) {
448
- console.log(` overrides: ${overrides.map((o) => `${o.id}=${o.model}`).join(", ")}`);
449
- }
450
349
  console.log("");
451
350
  if (detectedProvider?.status === "missing") {
452
351
  console.log(`\x1B[33m\u26A0 ${spec.label} is not installed.\x1B[0m`);
@@ -471,7 +370,7 @@ async function initCommand() {
471
370
  // src/commands/prune.ts
472
371
  import * as fs3 from "fs";
473
372
  import * as path3 from "path";
474
- import { checkbox as checkbox2, confirm } from "@inquirer/prompts";
373
+ import { checkbox, confirm } from "@inquirer/prompts";
475
374
  function scanPruneItems(workDir) {
476
375
  const items = [];
477
376
  const multiclawDir = path3.join(workDir, ".multiclaw");
@@ -587,7 +486,7 @@ async function pruneCommand(options) {
587
486
  value: item.id,
588
487
  name: item.label
589
488
  }));
590
- selectedIds = await checkbox2({
489
+ selectedIds = await checkbox({
591
490
  message: "Select items to prune (space to select, enter to confirm):",
592
491
  choices
593
492
  });
@@ -1380,7 +1279,7 @@ var program = new Command();
1380
1279
  program.name("multiclaw").description("Multi-agent orchestration CLI").version(pkg.version, "-v, --version", "Display version number").option("--config <path>", "Config file path (default: auto-discover ./multiclaw.config.ts)").option("--new", "Start a new session instead of continuing the most recent").option("-r, --resume [id]", "Resume a session by id, or open the session picker").action(
1381
1280
  (options) => tuiCommand(options)
1382
1281
  );
1383
- program.command("init").description("Scaffold a config file (interactive)").action(() => initCommand());
1282
+ program.command("init").description("Scaffold a config file (interactive)").option("--force", "Overwrite existing multiclaw.config.ts").action((opts) => initCommand(opts));
1384
1283
  program.command("run [requirement]").description("Run an orchestration headlessly").option("--config <path>", "Config file path (default: auto-discover ./multiclaw.config.ts)").option("--no-leader", "Batch mode only: skip routing and run the full team").option("--dry-run", "Preview the routed plan without running the pipeline").option(
1385
1284
  "--resume [path]",
1386
1285
  "Resume a previous run, continuing agent sessions (default: the latest)"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "multiclaw",
3
- "version": "0.10.0",
3
+ "version": "0.10.1",
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.10.0",
34
- "@multiclawcli/dashboard": "0.10.0",
33
+ "@multiclawcli/core": "0.10.1",
34
+ "@multiclawcli/dashboard": "0.10.1",
35
35
  "commander": "^15.0.0",
36
36
  "jiti": "^2.7.0"
37
37
  },