chatroom-cli 1.0.74 → 1.0.75

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 +31 -230
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -10717,9 +10717,6 @@ var init_task_started = __esm(() => {
10717
10717
  });
10718
10718
 
10719
10719
  // ../../services/backend/prompts/base/cli/wait-for-task/reminder.ts
10720
- function getWaitForTaskReminder() {
10721
- return "Message availability is critical: Use `wait-for-task` in the foreground to stay connected, otherwise your team cannot reach you";
10722
- }
10723
10720
  function getWaitForTaskGuidance() {
10724
10721
  return `\uD83D\uDD17 STAYING CONNECTED TO YOUR TEAM
10725
10722
 
@@ -10735,11 +10732,11 @@ Two requirements:
10735
10732
 
10736
10733
  2. **Blocking execution** - Wait for command completion
10737
10734
  • Do not respond to user or perform other work while running
10738
- • Only proceed after the command exits (timeout or task received)
10735
+ • Only proceed after the command exits (signal or task received)
10739
10736
 
10740
- ⏱️ UNDERSTANDING TIMEOUTS
10741
- Timeouts are normal and expected - they keep agents responsive
10742
- • When the command terminates:
10737
+ ⚠️ WHEN THE PROCESS IS TERMINATED OR TIMED OUT
10738
+ Your harness may kill long-running commands after a set duration
10739
+ • When the command terminates unexpectedly:
10743
10740
  1. Do you have urgent pending work?
10744
10741
  2. Without wait-for-task, your team cannot reach you
10745
10742
  3. If no urgent work, reconnect immediately
@@ -10812,9 +10809,8 @@ function waitForTaskCommand(params) {
10812
10809
  }
10813
10810
 
10814
10811
  // src/config.ts
10815
- var DEFAULT_WAIT_TIMEOUT_MS, DEFAULT_ACTIVE_TIMEOUT_MS, WEB_SERVER_PORT;
10812
+ var DEFAULT_ACTIVE_TIMEOUT_MS, WEB_SERVER_PORT;
10816
10813
  var init_config2 = __esm(() => {
10817
- DEFAULT_WAIT_TIMEOUT_MS = 10 * 60 * 1000;
10818
10814
  DEFAULT_ACTIVE_TIMEOUT_MS = 60 * 60 * 1000;
10819
10815
  WEB_SERVER_PORT = parseInt(process.env.WEB_PORT || "3456", 10);
10820
10816
  });
@@ -10822,38 +10818,11 @@ var init_config2 = __esm(() => {
10822
10818
  // src/commands/wait-for-task.ts
10823
10819
  var exports_wait_for_task = {};
10824
10820
  __export(exports_wait_for_task, {
10825
- waitForTask: () => waitForTask,
10826
- parseDuration: () => parseDuration
10821
+ waitForTask: () => waitForTask
10827
10822
  });
10828
- function parseDuration(duration) {
10829
- const match = duration.trim().match(/^(\d+(?:\.\d+)?)\s*(s|sec|second|seconds|m|min|minute|minutes|h|hr|hour|hours)?$/i);
10830
- if (!match)
10831
- return null;
10832
- const value = parseFloat(match[1]);
10833
- const unit = (match[2] || "s").toLowerCase();
10834
- switch (unit) {
10835
- case "s":
10836
- case "sec":
10837
- case "second":
10838
- case "seconds":
10839
- return value * 1000;
10840
- case "m":
10841
- case "min":
10842
- case "minute":
10843
- case "minutes":
10844
- return value * 60 * 1000;
10845
- case "h":
10846
- case "hr":
10847
- case "hour":
10848
- case "hours":
10849
- return value * 60 * 60 * 1000;
10850
- default:
10851
- return null;
10852
- }
10853
- }
10854
10823
  async function waitForTask(chatroomId, options) {
10855
10824
  const client2 = await getConvexClient();
10856
- const { role, timeout, silent } = options;
10825
+ const { role, silent } = options;
10857
10826
  const convexUrl = getConvexUrl();
10858
10827
  const cliEnvPrefix = getCliEnvPrefix(convexUrl);
10859
10828
  const sessionId = getSessionId();
@@ -10930,14 +10899,11 @@ async function waitForTask(chatroomId, options) {
10930
10899
  console.warn(`⚠️ Machine registration failed: ${machineError.message}`);
10931
10900
  }
10932
10901
  }
10933
- const effectiveTimeout = timeout || DEFAULT_WAIT_TIMEOUT_MS;
10934
- const readyUntil = Date.now() + effectiveTimeout;
10935
10902
  const connectionId = `${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
10936
10903
  await client2.mutation(api.participants.join, {
10937
10904
  sessionId,
10938
10905
  chatroomId,
10939
10906
  role,
10940
- readyUntil,
10941
10907
  connectionId
10942
10908
  });
10943
10909
  const connectionTime = new Date().toISOString().replace("T", " ").substring(0, 19);
@@ -10975,22 +10941,6 @@ async function waitForTask(chatroomId, options) {
10975
10941
  } catch {}
10976
10942
  let taskProcessed = false;
10977
10943
  let unsubscribe = null;
10978
- const timeoutHandle = setTimeout(() => {
10979
- if (unsubscribe)
10980
- unsubscribe();
10981
- const timeoutTime = new Date().toISOString().replace("T", " ").substring(0, 19);
10982
- console.log(`
10983
- ${"─".repeat(50)}`);
10984
- console.log(`⚠️ RECONNECTION REQUIRED
10985
- `);
10986
- console.log(`[${timeoutTime}] Why: Session timeout reached (normal and expected behavior)`);
10987
- console.log(`Impact: You are no longer listening for tasks`);
10988
- console.log(`Action: Run this command immediately to resume availability
10989
- `);
10990
- console.log(waitForTaskCommand({ chatroomId, role, cliEnvPrefix }));
10991
- console.log(`${"─".repeat(50)}`);
10992
- process.exit(0);
10993
- }, effectiveTimeout);
10994
10944
  const handlePendingTasks = async (pendingTasks) => {
10995
10945
  if (taskProcessed)
10996
10946
  return;
@@ -11002,7 +10952,6 @@ ${"─".repeat(50)}`);
11002
10952
  if (currentConnectionId && currentConnectionId !== connectionId) {
11003
10953
  if (unsubscribe)
11004
10954
  unsubscribe();
11005
- clearTimeout(timeoutHandle);
11006
10955
  const takeoverTime = new Date().toISOString().replace("T", " ").substring(0, 19);
11007
10956
  console.log(`
11008
10957
  ${"─".repeat(50)}`);
@@ -11022,15 +10971,26 @@ ${"─".repeat(50)}`);
11022
10971
  return;
11023
10972
  }
11024
10973
  const { task, message } = taskWithMessage;
11025
- try {
11026
- await client2.mutation(api.tasks.claimTask, {
11027
- sessionId,
11028
- chatroomId,
11029
- role
11030
- });
11031
- } catch (_claimError) {
11032
- console.log(`\uD83D\uDD04 Task already claimed by another agent, continuing to wait...`);
11033
- return;
10974
+ if (task.status === "acknowledged") {
10975
+ const acknowledgedAt = task.acknowledgedAt || task.updatedAt;
10976
+ const elapsedMs = Date.now() - acknowledgedAt;
10977
+ const RECOVERY_GRACE_PERIOD_MS = 60 * 1000;
10978
+ if (elapsedMs < RECOVERY_GRACE_PERIOD_MS) {
10979
+ const remainingSec = Math.ceil((RECOVERY_GRACE_PERIOD_MS - elapsedMs) / 1000);
10980
+ console.log(`\uD83D\uDD04 Task was recently acknowledged (${remainingSec}s remaining). ` + `Re-run wait-for-task in 1 minute to recover it if the other agent is unresponsive.`);
10981
+ return;
10982
+ }
10983
+ } else {
10984
+ try {
10985
+ await client2.mutation(api.tasks.claimTask, {
10986
+ sessionId,
10987
+ chatroomId,
10988
+ role
10989
+ });
10990
+ } catch (_claimError) {
10991
+ console.log(`\uD83D\uDD04 Task already claimed by another agent, continuing to wait...`);
10992
+ return;
10993
+ }
11034
10994
  }
11035
10995
  taskProcessed = true;
11036
10996
  if (message) {
@@ -11042,7 +11002,6 @@ ${"─".repeat(50)}`);
11042
11002
  }
11043
11003
  if (unsubscribe)
11044
11004
  unsubscribe();
11045
- clearTimeout(timeoutHandle);
11046
11005
  const activeUntil = Date.now() + DEFAULT_ACTIVE_TIMEOUT_MS;
11047
11006
  await client2.mutation(api.participants.updateStatus, {
11048
11007
  sessionId,
@@ -11063,151 +11022,7 @@ ${"─".repeat(50)}`);
11063
11022
  console.log(`
11064
11023
  [${taskReceivedTime}] \uD83D\uDCE8 Task received!
11065
11024
  `);
11066
- console.log(`${"=".repeat(60)}`);
11067
- console.log(`\uD83C\uDD94 TASK INFORMATION`);
11068
- console.log(`${"=".repeat(60)}`);
11069
- console.log(`Task ID: ${task._id}`);
11070
- if (message) {
11071
- console.log(`Message ID: ${message._id}`);
11072
- }
11073
- console.log(`
11074
- \uD83D\uDCCB NEXT STEPS`);
11075
- console.log(`${"=".repeat(60)}`);
11076
- const isUserMessage = message && message.senderRole.toLowerCase() === "user";
11077
- if (isUserMessage) {
11078
- console.log(`To acknowledge and classify this message, run:
11079
- `);
11080
- const baseCmd = taskStartedCommand({
11081
- chatroomId,
11082
- role,
11083
- taskId: task._id,
11084
- classification: "question",
11085
- cliEnvPrefix
11086
- }).replace("--origin-message-classification=question", "--origin-message-classification=<type>");
11087
- console.log(baseCmd);
11088
- console.log(`
11089
- \uD83D\uDCDD Classification Requirements:`);
11090
- console.log(` • question: No additional fields required`);
11091
- console.log(` • follow_up: No additional fields required`);
11092
- console.log(` • new_feature: REQUIRES --title, --description, --tech-specs`);
11093
- console.log(`
11094
- \uD83D\uDCA1 Example for new_feature:`);
11095
- console.log(taskStartedCommand({
11096
- chatroomId,
11097
- role,
11098
- taskId: task._id,
11099
- classification: "new_feature",
11100
- title: "<title>",
11101
- description: "<description>",
11102
- techSpecs: "<tech-specs>",
11103
- cliEnvPrefix
11104
- }));
11105
- console.log(`
11106
- Classification types: question, new_feature, follow_up`);
11107
- } else if (message) {
11108
- console.log(`Task handed off from ${message.senderRole}.`);
11109
- console.log(`The original user message was already classified - you can start work immediately.`);
11110
- } else {
11111
- console.log(`No message found. Task ID: ${task._id}`);
11112
- }
11113
- console.log(`${"=".repeat(60)}`);
11114
- console.log(`
11115
- <!-- CONTEXT: Available Actions & Role Instructions`);
11116
- console.log(taskDeliveryPrompt.humanReadable);
11117
- console.log(`-->`);
11118
- const currentContext = taskDeliveryPrompt.json?.contextWindow?.currentContext;
11119
- const originMessage = taskDeliveryPrompt.json?.contextWindow?.originMessage;
11120
- console.log(`
11121
- ${"=".repeat(60)}`);
11122
- console.log(`\uD83D\uDCCD PINNED - Work on this immediately`);
11123
- console.log(`${"=".repeat(60)}`);
11124
- if (currentContext) {
11125
- console.log(`
11126
- ## Context`);
11127
- console.log(`<context>`);
11128
- console.log(currentContext.content);
11129
- const messagesSinceContext = currentContext.messagesSinceContext ?? 0;
11130
- const elapsedHours = currentContext.elapsedHours ?? 0;
11131
- if (messagesSinceContext >= 10) {
11132
- console.log(`
11133
- ⚠️ WARNING: ${messagesSinceContext} messages since this context was set.`);
11134
- console.log(` Consider updating the context with a summary of recent developments.`);
11135
- console.log(` Create a new context with:`);
11136
- console.log(` ${cliEnvPrefix}chatroom context new --chatroom-id=${chatroomId} --role=${role} --content="<summary>"`);
11137
- }
11138
- if (elapsedHours >= 24) {
11139
- const ageDays = Math.floor(elapsedHours / 24);
11140
- console.log(`
11141
- ⚠️ WARNING: This context is ${ageDays} day(s) old.`);
11142
- console.log(` Consider creating a new context with updated summary.`);
11143
- console.log(` ${cliEnvPrefix}chatroom context new --chatroom-id=${chatroomId} --role=${role} --content="<summary>"`);
11144
- }
11145
- console.log(`</context>`);
11146
- } else if (originMessage && originMessage.senderRole.toLowerCase() === "user") {
11147
- console.log(`
11148
- ## User Message`);
11149
- console.log(`<user-message>`);
11150
- console.log(originMessage.content);
11151
- if (originMessage.attachedTasks && originMessage.attachedTasks.length > 0) {
11152
- console.log(`
11153
- ATTACHED BACKLOG (${originMessage.attachedTasks.length})`);
11154
- for (const attachedTask of originMessage.attachedTasks) {
11155
- console.log(`${attachedTask.content}`);
11156
- }
11157
- }
11158
- const followUpCount = taskDeliveryPrompt.json?.contextWindow?.followUpCountSinceOrigin ?? 0;
11159
- const originCreatedAt = taskDeliveryPrompt.json?.contextWindow?.originMessageCreatedAt;
11160
- if (followUpCount >= 5) {
11161
- console.log(`
11162
- ⚠️ WARNING: ${followUpCount} follow-up messages since this pinned message.`);
11163
- console.log(` The user may have moved on to a different topic.`);
11164
- console.log(` Consider creating a context with:`);
11165
- console.log(` ${cliEnvPrefix}chatroom context new --chatroom-id=${chatroomId} --role=${role} --content="<summary>"`);
11166
- }
11167
- if (originCreatedAt) {
11168
- const ageMs = Date.now() - originCreatedAt;
11169
- const ageHours = ageMs / (1000 * 60 * 60);
11170
- if (ageHours >= 24) {
11171
- const ageDays = Math.floor(ageHours / 24);
11172
- console.log(`
11173
- ⚠️ WARNING: This pinned message is ${ageDays} day(s) old.`);
11174
- console.log(` Consider creating a context with:`);
11175
- console.log(` ${cliEnvPrefix}chatroom context new --chatroom-id=${chatroomId} --role=${role} --content="<summary>"`);
11176
- }
11177
- }
11178
- console.log(`</user-message>`);
11179
- }
11180
- console.log(`
11181
- ## Task`);
11182
- console.log(task.content);
11183
- const existingClassification = originMessage?.classification;
11184
- if (existingClassification) {
11185
- console.log(`
11186
- Classification: ${existingClassification.toUpperCase()}`);
11187
- }
11188
- console.log(`
11189
- ${"=".repeat(60)}`);
11190
- console.log(`\uD83D\uDCCB PROCESS`);
11191
- console.log(`${"=".repeat(60)}`);
11192
- console.log(`
11193
- 1. Mark task as started:`);
11194
- if (isUserMessage) {
11195
- console.log(` ${taskStartedCommand({ chatroomId, role, taskId: task._id, classification: "follow_up", cliEnvPrefix })}`);
11196
- } else {
11197
- console.log(` ${cliEnvPrefix}chatroom task-started --chatroom-id=${chatroomId} --role=${role} --task-id=${task._id} --no-classify`);
11198
- }
11199
- console.log(`
11200
- 2. Do the work`);
11201
- console.log(`
11202
- 3. Hand off when complete:`);
11203
- console.log(` ${cliEnvPrefix}chatroom handoff --chatroom-id=${chatroomId} --role=${role} --next-role=<target>`);
11204
- console.log(`
11205
- 4. Resume listening:`);
11206
- console.log(` ${waitForTaskCommand({ chatroomId, role, cliEnvPrefix })}`);
11207
- console.log(`
11208
- ${"=".repeat(60)}`);
11209
- console.log(getWaitForTaskReminder());
11210
- console.log(`${"=".repeat(60)}`);
11025
+ console.log(taskDeliveryPrompt.fullCliOutput);
11211
11026
  process.exit(0);
11212
11027
  };
11213
11028
  const wsClient2 = await getConvexWsClient();
@@ -11223,7 +11038,6 @@ ${"=".repeat(60)}`);
11223
11038
  const handleSignal = (_signal) => {
11224
11039
  if (unsubscribe)
11225
11040
  unsubscribe();
11226
- clearTimeout(timeoutHandle);
11227
11041
  const signalTime = new Date().toISOString().replace("T", " ").substring(0, 19);
11228
11042
  console.log(`
11229
11043
  ${"─".repeat(50)}`);
@@ -14129,24 +13943,11 @@ program2.command("register-agent").description("Register agent type for a chatro
14129
13943
  type: options.type
14130
13944
  });
14131
13945
  });
14132
- program2.command("wait-for-task").description("Join a chatroom and wait for tasks").requiredOption("--chatroom-id <id>", "Chatroom identifier").requiredOption("--role <role>", "Role to join as (e.g., builder, reviewer)").option("--timeout <ms>", "Optional timeout in milliseconds (deprecated, use --duration)").option("--duration <duration>", 'How long to wait (e.g., "1m", "5m", "30s")').action(async (options) => {
13946
+ program2.command("wait-for-task").description("Join a chatroom and wait for tasks").requiredOption("--chatroom-id <id>", "Chatroom identifier").requiredOption("--role <role>", "Role to join as (e.g., builder, reviewer)").action(async (options) => {
14133
13947
  await maybeRequireAuth();
14134
- const { waitForTask: waitForTask2, parseDuration: parseDuration2 } = await Promise.resolve().then(() => (init_wait_for_task(), exports_wait_for_task));
14135
- let timeoutMs;
14136
- if (options.duration) {
14137
- const parsed = parseDuration2(options.duration);
14138
- if (parsed === null) {
14139
- console.error(`❌ Invalid duration format: "${options.duration}". Use formats like "1m", "5m", "30s".`);
14140
- process.exit(1);
14141
- }
14142
- timeoutMs = parsed;
14143
- } else if (options.timeout) {
14144
- timeoutMs = parseInt(options.timeout, 10);
14145
- }
13948
+ const { waitForTask: waitForTask2 } = await Promise.resolve().then(() => (init_wait_for_task(), exports_wait_for_task));
14146
13949
  await waitForTask2(options.chatroomId, {
14147
- role: options.role,
14148
- timeout: timeoutMs,
14149
- duration: options.duration
13950
+ role: options.role
14150
13951
  });
14151
13952
  });
14152
13953
  program2.command("task-started").description("Acknowledge a task and optionally classify the user message").requiredOption("--chatroom-id <id>", "Chatroom identifier").requiredOption("--role <role>", "Your role").option("--origin-message-classification <type>", "Original message classification: question, new_feature, or follow_up (for entry point roles)").option("--no-classify", "Skip classification (for handoff recipients - classification already done by entry point)").requiredOption("--task-id <taskId>", "Task ID to acknowledge").action(async (options) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chatroom-cli",
3
- "version": "1.0.74",
3
+ "version": "1.0.75",
4
4
  "description": "CLI for multi-agent chatroom collaboration",
5
5
  "type": "module",
6
6
  "bin": {