chatroom-cli 1.13.2 → 1.14.0

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.
Files changed (2) hide show
  1. package/dist/index.js +178 -52
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -10227,7 +10227,7 @@ class BaseCLIAgentService {
10227
10227
  }
10228
10228
  checkVersion(command) {
10229
10229
  try {
10230
- const output = this.deps.execSync(`${command} --version`, {
10230
+ const output = this.deps.execSync(`${command} --version 2>&1`, {
10231
10231
  stdio: ["pipe", "pipe", "pipe"],
10232
10232
  timeout: 5000
10233
10233
  }).toString().trim();
@@ -10500,7 +10500,7 @@ var init_pi_agent_service = __esm(() => {
10500
10500
  }
10501
10501
  async listModels() {
10502
10502
  try {
10503
- const output = this.deps.execSync(`${PI_COMMAND} --list-models`, {
10503
+ const output = this.deps.execSync(`${PI_COMMAND} --list-models 2>&1`, {
10504
10504
  stdio: ["pipe", "pipe", "pipe"],
10505
10505
  timeout: 1e4
10506
10506
  }).toString().trim();
@@ -12552,7 +12552,7 @@ async function createDefaultDeps8() {
12552
12552
  }
12553
12553
  async function handoff(chatroomId, options, deps) {
12554
12554
  const d = deps ?? await createDefaultDeps8();
12555
- const { role, message, nextRole, attachedArtifactIds = [] } = options;
12555
+ const { role, message, nextRole, attachedArtifactIds = [], attachedWorkflowKeys = [] } = options;
12556
12556
  const sessionId = d.session.getSessionId();
12557
12557
  if (!sessionId) {
12558
12558
  const otherUrls = d.session.getOtherSessionUrls();
@@ -12582,6 +12582,22 @@ async function handoff(chatroomId, options, deps) {
12582
12582
  process.exit(1);
12583
12583
  }
12584
12584
  }
12585
+ const resolvedWorkflowIds = [];
12586
+ if (attachedWorkflowKeys.length > 0) {
12587
+ for (const key of attachedWorkflowKeys) {
12588
+ try {
12589
+ const result2 = await d.backend.query(api.workflows.resolveWorkflowId, {
12590
+ sessionId,
12591
+ chatroomId,
12592
+ workflowKey: key
12593
+ });
12594
+ resolvedWorkflowIds.push(result2.workflowId);
12595
+ } catch {
12596
+ formatError(`Workflow "${key}" not found`, ["Check the workflow key and try again"]);
12597
+ process.exit(1);
12598
+ }
12599
+ }
12600
+ }
12585
12601
  let result;
12586
12602
  try {
12587
12603
  result = await d.backend.mutation(api.messages.handoff, {
@@ -12592,6 +12608,9 @@ async function handoff(chatroomId, options, deps) {
12592
12608
  targetRole: nextRole,
12593
12609
  ...attachedArtifactIds.length > 0 && {
12594
12610
  attachedArtifactIds
12611
+ },
12612
+ ...resolvedWorkflowIds.length > 0 && {
12613
+ attachedWorkflowIds: resolvedWorkflowIds
12595
12614
  }
12596
12615
  });
12597
12616
  } catch (error) {
@@ -12665,6 +12684,32 @@ ${error instanceof Error ? error.message : String(error)}`);
12665
12684
  console.log(` • ${id}`);
12666
12685
  });
12667
12686
  }
12687
+ if (resolvedWorkflowIds.length > 0) {
12688
+ for (const wfId of resolvedWorkflowIds) {
12689
+ try {
12690
+ const detail = await d.backend.query(api.workflows.getWorkflowDetail, {
12691
+ sessionId,
12692
+ chatroomId,
12693
+ workflowId: wfId
12694
+ });
12695
+ const wf = detail.workflow;
12696
+ console.log("");
12697
+ console.log(`\uD83D\uDCCA Attached Workflow: ${wf.workflowKey} (${wf.status}, ${detail.steps.length} steps)`);
12698
+ for (let i2 = 0;i2 < detail.steps.length; i2++) {
12699
+ const step = detail.steps[i2];
12700
+ const isLast = i2 === detail.steps.length - 1;
12701
+ const prefix = isLast ? "└─" : "├─";
12702
+ const statusEmoji = step.status === "completed" ? "✅" : step.status === "in_progress" ? "\uD83D\uDD04" : step.status === "cancelled" ? "❌" : "⏳";
12703
+ const roleLabel = step.assigneeRole ? ` [${step.assigneeRole}]` : "";
12704
+ const deps2 = step.dependsOn.length > 0 ? ` (depends: ${step.dependsOn.join(", ")})` : "";
12705
+ console.log(` ${prefix} ${step.stepKey}${roleLabel} ${statusEmoji} ${step.status}${deps2}`);
12706
+ }
12707
+ console.log("");
12708
+ console.log(` Inspect: chatroom workflow status --chatroom-id=${chatroomId} --workflow-key=${wf.workflowKey}`);
12709
+ console.log(` View step: chatroom workflow step-view --chatroom-id=${chatroomId} --workflow-key=${wf.workflowKey} --step-key=<key>`);
12710
+ } catch {}
12711
+ }
12712
+ }
12668
12713
  const convexUrl = d.session.getConvexUrl();
12669
12714
  const cliEnvPrefix = getCliEnvPrefix(convexUrl);
12670
12715
  console.log(`
@@ -13428,14 +13473,14 @@ var init_file_content = () => {};
13428
13473
  // src/commands/workflow/index.ts
13429
13474
  var exports_workflow = {};
13430
13475
  __export(exports_workflow, {
13476
+ viewStep: () => viewStep,
13431
13477
  specifyWorkflowStep: () => specifyWorkflowStep,
13432
13478
  parseSections: () => parseSections,
13433
13479
  getWorkflowStatus: () => getWorkflowStatus,
13434
13480
  exitWorkflow: () => exitWorkflow,
13435
13481
  executeWorkflow: () => executeWorkflow,
13436
13482
  createWorkflow: () => createWorkflow,
13437
- completeStep: () => completeStep,
13438
- cancelStep: () => cancelStep
13483
+ completeStep: () => completeStep
13439
13484
  });
13440
13485
  async function createDefaultDeps11() {
13441
13486
  const client2 = await getConvexClient();
@@ -13612,10 +13657,11 @@ async function specifyWorkflowStep(chatroomId, options, deps) {
13612
13657
  const d = deps ?? await createDefaultDeps11();
13613
13658
  const sessionId = requireAuth3(d);
13614
13659
  validateChatroomId2(chatroomId);
13615
- const sections = parseSections(options.stdinContent, ["GOAL", "REQUIREMENTS"], ["WARNINGS"]);
13660
+ const sections = parseSections(options.stdinContent, ["GOAL", "REQUIREMENTS"], ["WARNINGS", "SKILLS"]);
13616
13661
  const goal = sections.get("GOAL");
13617
13662
  const requirements = sections.get("REQUIREMENTS");
13618
13663
  const warnings = sections.get("WARNINGS") || undefined;
13664
+ const skills = sections.get("SKILLS") || undefined;
13619
13665
  try {
13620
13666
  await d.backend.mutation(api.workflows.specifyStep, {
13621
13667
  sessionId,
@@ -13625,7 +13671,8 @@ async function specifyWorkflowStep(chatroomId, options, deps) {
13625
13671
  assigneeRole: options.assigneeRole,
13626
13672
  goal,
13627
13673
  requirements,
13628
- warnings
13674
+ warnings,
13675
+ skills
13629
13676
  });
13630
13677
  console.log("");
13631
13678
  console.log("✅ Step specified");
@@ -13732,6 +13779,9 @@ async function getWorkflowStatus(chatroomId, options, deps) {
13732
13779
  if (spec.goal) {
13733
13780
  console.log(` \uD83D\uDCCE Goal: ${spec.goal}`);
13734
13781
  }
13782
+ if (spec.skills) {
13783
+ console.log(` \uD83D\uDD27 Skills: ${spec.skills}`);
13784
+ }
13735
13785
  if (spec.requirements) {
13736
13786
  console.log(` \uD83D\uDCCE Requirements: ${spec.requirements}`);
13737
13787
  }
@@ -13787,58 +13837,118 @@ async function completeStep(chatroomId, options, deps) {
13787
13837
  return;
13788
13838
  }
13789
13839
  }
13790
- async function cancelStep(chatroomId, options, deps) {
13840
+ async function exitWorkflow(chatroomId, options, deps) {
13791
13841
  const d = deps ?? await createDefaultDeps11();
13792
13842
  const sessionId = requireAuth3(d);
13793
13843
  validateChatroomId2(chatroomId);
13794
13844
  if (!options.reason || options.reason.trim().length === 0) {
13795
- console.error("❌ Reason is required when cancelling a step");
13845
+ console.error("❌ Reason is required when exiting a workflow");
13796
13846
  process.exit(1);
13797
13847
  return;
13798
13848
  }
13799
13849
  try {
13800
- await d.backend.mutation(api.workflows.cancelStep, {
13850
+ await d.backend.mutation(api.workflows.exitWorkflow, {
13801
13851
  sessionId,
13802
13852
  chatroomId,
13803
13853
  workflowKey: options.workflowKey,
13804
- stepKey: options.stepKey,
13805
13854
  reason: options.reason.trim()
13806
13855
  });
13807
13856
  console.log("");
13808
- console.log("❌ Step cancelled");
13809
- console.log(` Workflow: ${options.workflowKey}`);
13810
- console.log(` Step: ${options.stepKey}`);
13857
+ console.log("❌ Workflow exited (cancelled)");
13858
+ console.log(` Key: ${options.workflowKey}`);
13811
13859
  console.log(` Reason: ${options.reason.trim()}`);
13812
13860
  console.log("");
13813
13861
  } catch (error) {
13814
- console.error(`❌ Failed to cancel step: ${error.message}`);
13862
+ console.error(`❌ Failed to exit workflow: ${error.message}`);
13815
13863
  process.exit(1);
13816
13864
  return;
13817
13865
  }
13818
13866
  }
13819
- async function exitWorkflow(chatroomId, options, deps) {
13867
+ async function viewStep(chatroomId, options, deps) {
13820
13868
  const d = deps ?? await createDefaultDeps11();
13821
13869
  const sessionId = requireAuth3(d);
13822
13870
  validateChatroomId2(chatroomId);
13823
- if (!options.reason || options.reason.trim().length === 0) {
13824
- console.error("❌ Reason is required when exiting a workflow");
13825
- process.exit(1);
13826
- return;
13827
- }
13828
13871
  try {
13829
- await d.backend.mutation(api.workflows.exitWorkflow, {
13872
+ const result = await d.backend.query(api.workflows.getStepView, {
13830
13873
  sessionId,
13831
13874
  chatroomId,
13832
13875
  workflowKey: options.workflowKey,
13833
- reason: options.reason.trim()
13876
+ stepKey: options.stepKey
13834
13877
  });
13878
+ const step = result.step;
13879
+ const emoji = getStepStatusEmoji(step.status);
13835
13880
  console.log("");
13836
- console.log("❌ Workflow exited (cancelled)");
13837
- console.log(` Key: ${options.workflowKey}`);
13838
- console.log(` Reason: ${options.reason.trim()}`);
13881
+ console.log("══════════════════════════════════════════════════");
13882
+ console.log(`${emoji} STEP: ${step.stepKey}`);
13883
+ console.log("══════════════════════════════════════════════════");
13884
+ console.log(`Workflow: ${result.workflowKey} (${result.workflowStatus})`);
13885
+ console.log(`Description: ${step.description}`);
13886
+ console.log(`Status: ${step.status.toUpperCase()}`);
13887
+ if (step.assigneeRole) {
13888
+ console.log(`Assignee: ${step.assigneeRole}`);
13889
+ }
13890
+ if (step.dependsOn.length > 0) {
13891
+ console.log(`Dependencies: ${step.dependsOn.join(", ")}`);
13892
+ }
13893
+ console.log(`Order: ${step.order}`);
13894
+ if (step.completedAt) {
13895
+ const completedDate = new Date(step.completedAt).toLocaleString("en-US", {
13896
+ month: "short",
13897
+ day: "numeric",
13898
+ hour: "2-digit",
13899
+ minute: "2-digit",
13900
+ hour12: false
13901
+ });
13902
+ console.log(`Completed: ${completedDate}`);
13903
+ }
13904
+ if (step.cancelledAt) {
13905
+ const cancelledDate = new Date(step.cancelledAt).toLocaleString("en-US", {
13906
+ month: "short",
13907
+ day: "numeric",
13908
+ hour: "2-digit",
13909
+ minute: "2-digit",
13910
+ hour12: false
13911
+ });
13912
+ console.log(`Cancelled: ${cancelledDate}`);
13913
+ if (step.cancelReason) {
13914
+ console.log(`Cancel reason: ${step.cancelReason}`);
13915
+ }
13916
+ }
13917
+ if (step.specification) {
13918
+ const spec = step.specification;
13919
+ console.log("");
13920
+ console.log("──────────────────────────────────────────────────");
13921
+ console.log("\uD83D\uDCCB SPECIFICATION");
13922
+ console.log("──────────────────────────────────────────────────");
13923
+ if (spec.goal) {
13924
+ console.log("");
13925
+ console.log("Goal:");
13926
+ console.log(spec.goal);
13927
+ }
13928
+ if (spec.skills) {
13929
+ console.log("");
13930
+ console.log("Skills:");
13931
+ console.log(spec.skills);
13932
+ }
13933
+ if (spec.requirements) {
13934
+ console.log("");
13935
+ console.log("Requirements:");
13936
+ console.log(spec.requirements);
13937
+ }
13938
+ if (spec.warnings) {
13939
+ console.log("");
13940
+ console.log("⚠️ Warnings:");
13941
+ console.log(spec.warnings);
13942
+ }
13943
+ } else {
13944
+ console.log("");
13945
+ console.log("⚠️ No specification set. Run `workflow specify` to add one.");
13946
+ }
13947
+ console.log("");
13948
+ console.log("══════════════════════════════════════════════════");
13839
13949
  console.log("");
13840
13950
  } catch (error) {
13841
- console.error(`❌ Failed to exit workflow: ${error.message}`);
13951
+ console.error(`❌ Failed to view step: ${error.message}`);
13842
13952
  process.exit(1);
13843
13953
  return;
13844
13954
  }
@@ -14883,7 +14993,7 @@ var init_on_request_start_agent = __esm(() => {
14883
14993
 
14884
14994
  // src/commands/machine/daemon-start/handlers/stop-agent.ts
14885
14995
  async function executeStopAgent(ctx, args) {
14886
- const { chatroomId, role, reason } = args;
14996
+ const { chatroomId, role, reason, pid } = args;
14887
14997
  console.log(` ↪ stop-agent command received`);
14888
14998
  console.log(` Chatroom: ${chatroomId}`);
14889
14999
  console.log(` Role: ${role}`);
@@ -14891,7 +15001,8 @@ async function executeStopAgent(ctx, args) {
14891
15001
  const result = await ctx.deps.agentProcessManager.stop({
14892
15002
  chatroomId,
14893
15003
  role,
14894
- reason
15004
+ reason,
15005
+ pid
14895
15006
  });
14896
15007
  const msg = result.success ? `Agent stopped (${role})` : `Failed to stop agent (${role})`;
14897
15008
  console.log(` ${result.success ? "✅" : "⚠️ "} ${msg}`);
@@ -14907,7 +15018,8 @@ async function onRequestStopAgent(ctx, event) {
14907
15018
  await executeStopAgent(ctx, {
14908
15019
  chatroomId: event.chatroomId,
14909
15020
  role: event.role,
14910
- reason: event.reason
15021
+ reason: event.reason,
15022
+ pid: event.pid
14911
15023
  });
14912
15024
  }
14913
15025
  var init_on_request_stop_agent = () => {};
@@ -15848,9 +15960,7 @@ var init_crash_loop_tracker = __esm(() => {
15848
15960
  });
15849
15961
 
15850
15962
  // src/infrastructure/machine/stop-reason.ts
15851
- function resolveStopReason(code2, signal, wasIntentional) {
15852
- if (wasIntentional)
15853
- return "user.stop";
15963
+ function resolveStopReason(code2, signal) {
15854
15964
  if (signal !== null)
15855
15965
  return "agent_process.signal";
15856
15966
  if (code2 === 0)
@@ -15866,7 +15976,6 @@ function agentKey2(chatroomId, role) {
15866
15976
  class AgentProcessManager {
15867
15977
  deps;
15868
15978
  slots = new Map;
15869
- pendingStopReasons = new Map;
15870
15979
  constructor(deps) {
15871
15980
  this.deps = deps;
15872
15981
  }
@@ -15890,12 +15999,18 @@ class AgentProcessManager {
15890
15999
  const key = agentKey2(opts.chatroomId, opts.role);
15891
16000
  const slot = this.slots.get(key);
15892
16001
  if (!slot || slot.state === "idle") {
16002
+ const eventPid = opts.pid;
16003
+ if (eventPid && eventPid > 0) {
16004
+ try {
16005
+ this.deps.processes.kill(eventPid, "SIGTERM");
16006
+ } catch {}
16007
+ }
15893
16008
  this.deps.backend.mutation(api.machines.recordAgentExited, {
15894
16009
  sessionId: this.deps.sessionId,
15895
16010
  machineId: this.deps.machineId,
15896
16011
  chatroomId: opts.chatroomId,
15897
16012
  role: opts.role,
15898
- pid: 0,
16013
+ pid: eventPid ?? 0,
15899
16014
  stopReason: opts.reason,
15900
16015
  exitCode: undefined,
15901
16016
  signal: undefined,
@@ -15915,7 +16030,6 @@ class AgentProcessManager {
15915
16030
  slot.pendingOperation = undefined;
15916
16031
  return { success: true };
15917
16032
  }
15918
- this.pendingStopReasons.set(key, opts.reason);
15919
16033
  slot.state = "stopping";
15920
16034
  const operation = this.doStop(key, slot, pid, opts);
15921
16035
  slot.pendingOperation = operation;
@@ -15931,9 +16045,7 @@ class AgentProcessManager {
15931
16045
  if (slot.state === "stopping") {
15932
16046
  return;
15933
16047
  }
15934
- const intentionalReason = this.pendingStopReasons.get(key);
15935
- this.pendingStopReasons.delete(key);
15936
- const stopReason = intentionalReason ?? resolveStopReason(opts.code, opts.signal, false);
16048
+ const stopReason = resolveStopReason(opts.code, opts.signal);
15937
16049
  this.deps.spawning.recordExit(opts.chatroomId);
15938
16050
  const harness = slot.harness;
15939
16051
  const model = slot.model;
@@ -17297,6 +17409,8 @@ program2.command("classify").description("Classify a task's origin message (entr
17297
17409
  });
17298
17410
  program2.command("handoff").description("Complete your task and hand off to the next role").requiredOption("--chatroom-id <id>", "Chatroom identifier").requiredOption("--role <role>", "Your role").requiredOption("--next-role <nextRole>", "Role to hand off to").option("--attach-artifact <artifactId>", "Attach artifact to handoff (can be used multiple times)", (value, previous) => {
17299
17411
  return previous ? [...previous, value] : [value];
17412
+ }, []).option("--attachment <type:value>", "Attach a resource (can be used multiple times). Format: type:value. Supported: workflow-key:<key>", (value, previous) => {
17413
+ return previous ? [...previous, value] : [value];
17300
17414
  }, []).action(async (options) => {
17301
17415
  await maybeRequireAuth();
17302
17416
  const { decode: decode2 } = await Promise.resolve().then(() => exports_decode);
@@ -17313,12 +17427,29 @@ program2.command("handoff").description("Complete your task and hand off to the
17313
17427
  console.error("❌ Message is empty");
17314
17428
  process.exit(1);
17315
17429
  }
17430
+ const attachedWorkflowKeys = [];
17431
+ for (const att of options.attachment || []) {
17432
+ const colonIndex = att.indexOf(":");
17433
+ if (colonIndex === -1) {
17434
+ console.error(`❌ Invalid attachment format: "${att}". Expected type:value (e.g., workflow-key:my-workflow)`);
17435
+ process.exit(1);
17436
+ }
17437
+ const type = att.substring(0, colonIndex);
17438
+ const value = att.substring(colonIndex + 1);
17439
+ if (type === "workflow-key") {
17440
+ attachedWorkflowKeys.push(value);
17441
+ } else {
17442
+ console.error(`❌ Unknown attachment type: "${type}". Supported: workflow-key`);
17443
+ process.exit(1);
17444
+ }
17445
+ }
17316
17446
  const { handoff: handoff2 } = await Promise.resolve().then(() => (init_handoff(), exports_handoff));
17317
17447
  await handoff2(options.chatroomId, {
17318
17448
  role: options.role,
17319
17449
  message,
17320
17450
  nextRole: options.nextRole,
17321
- attachedArtifactIds: options.attachArtifact || []
17451
+ attachedArtifactIds: options.attachArtifact || [],
17452
+ attachedWorkflowKeys
17322
17453
  });
17323
17454
  });
17324
17455
  program2.command("report-progress").description("Report progress on current task (does not complete the task)").requiredOption("--chatroom-id <id>", "Chatroom identifier").requiredOption("--role <role>", "Your role").action(async (options) => {
@@ -17504,31 +17635,26 @@ workflowCommand.command("step-complete").description("Mark a workflow step as co
17504
17635
  stepKey: options.stepKey
17505
17636
  });
17506
17637
  });
17507
- workflowCommand.command("step-cancel").description("Cancel a workflow step with a reason").requiredOption("--chatroom-id <id>", "Chatroom identifier").requiredOption("--role <role>", "Your role").requiredOption("--workflow-key <key>", "Workflow key").requiredOption("--step-key <stepKey>", "Step key to cancel").requiredOption("--reason <text>", "Reason for cancellation (required)").action(async (options) => {
17638
+ workflowCommand.command("exit").description("Exit (cancel) an entire workflow with a reason").requiredOption("--chatroom-id <id>", "Chatroom identifier").requiredOption("--role <role>", "Your role").requiredOption("--workflow-key <key>", "Workflow key to exit").requiredOption("--reason <text>", "Reason for exiting the workflow (required)").action(async (options) => {
17508
17639
  await maybeRequireAuth();
17509
17640
  if (!options.reason || options.reason.trim().length === 0) {
17510
17641
  console.error("❌ --reason is required and cannot be empty");
17511
17642
  process.exit(1);
17512
17643
  }
17513
- const { cancelStep: cancelStep2 } = await Promise.resolve().then(() => (init_workflow(), exports_workflow));
17514
- await cancelStep2(options.chatroomId, {
17644
+ const { exitWorkflow: exitWorkflow2 } = await Promise.resolve().then(() => (init_workflow(), exports_workflow));
17645
+ await exitWorkflow2(options.chatroomId, {
17515
17646
  role: options.role,
17516
17647
  workflowKey: options.workflowKey,
17517
- stepKey: options.stepKey,
17518
17648
  reason: options.reason
17519
17649
  });
17520
17650
  });
17521
- workflowCommand.command("exit").description("Exit (cancel) an entire workflow with a reason").requiredOption("--chatroom-id <id>", "Chatroom identifier").requiredOption("--role <role>", "Your role").requiredOption("--workflow-key <key>", "Workflow key to exit").requiredOption("--reason <text>", "Reason for exiting the workflow (required)").action(async (options) => {
17651
+ workflowCommand.command("step-view").description("View the full details and specification of a single workflow step").requiredOption("--chatroom-id <id>", "Chatroom identifier").requiredOption("--role <role>", "Your role").requiredOption("--workflow-key <key>", "Workflow key").requiredOption("--step-key <stepKey>", "Step key to view").action(async (options) => {
17522
17652
  await maybeRequireAuth();
17523
- if (!options.reason || options.reason.trim().length === 0) {
17524
- console.error("❌ --reason is required and cannot be empty");
17525
- process.exit(1);
17526
- }
17527
- const { exitWorkflow: exitWorkflow2 } = await Promise.resolve().then(() => (init_workflow(), exports_workflow));
17528
- await exitWorkflow2(options.chatroomId, {
17653
+ const { viewStep: viewStep2 } = await Promise.resolve().then(() => (init_workflow(), exports_workflow));
17654
+ await viewStep2(options.chatroomId, {
17529
17655
  role: options.role,
17530
17656
  workflowKey: options.workflowKey,
17531
- reason: options.reason
17657
+ stepKey: options.stepKey
17532
17658
  });
17533
17659
  });
17534
17660
  var taskCommand = program2.command("task").description("Manage tasks");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chatroom-cli",
3
- "version": "1.13.2",
3
+ "version": "1.14.0",
4
4
  "description": "CLI for multi-agent chatroom collaboration",
5
5
  "type": "module",
6
6
  "bin": {