chatroom-cli 1.119.2 → 1.120.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.
package/dist/index.js CHANGED
@@ -45821,8 +45821,7 @@ class AgentProcessManager {
45821
45821
  sessionId: this.deps.sessionId,
45822
45822
  machineId: this.deps.machineId,
45823
45823
  chatroomId: opts.chatroomId,
45824
- role: opts.role,
45825
- taskId: opts.taskId
45824
+ role: opts.role
45826
45825
  });
45827
45826
  if (!authorization.allowed) {
45828
45827
  this.resetSlotIdle(slot);
@@ -47087,6 +47086,15 @@ function createTaskService(deps) {
47087
47086
  turnEndAttemptCounts.delete(key);
47088
47087
  redeliveryExhaustedKeys.delete(key);
47089
47088
  };
47089
+ const forgetStaleTask = ({
47090
+ chatroomId,
47091
+ role,
47092
+ taskId
47093
+ }) => {
47094
+ taskInboxState.remove(chatroomId, role, taskId, Date.now());
47095
+ pendingTaskReconciliationWatcher.clear(chatroomId, role, taskId);
47096
+ clearRedeliveryTrackingForTask(chatroomId, role, taskId);
47097
+ };
47090
47098
  const sweepUncoveredInProgressTasks = async () => {
47091
47099
  let released = 0;
47092
47100
  let failures3 = 0;
@@ -47456,7 +47464,8 @@ function createTaskService(deps) {
47456
47464
  isRedeliveryExhausted,
47457
47465
  clearRedeliveryTracking: ({ chatroomId, role }) => {
47458
47466
  clearRoleRedeliveryTracking(chatroomId, role);
47459
- }
47467
+ },
47468
+ forgetStaleTask
47460
47469
  };
47461
47470
  return service4;
47462
47471
  }
@@ -47704,7 +47713,9 @@ class NativeTaskDeliveryCoordinator {
47704
47713
  const result = await executors.deliverTask(row, agentConfig);
47705
47714
  if (!result || result.kind === "task-unavailable") {
47706
47715
  console.warn(`[NativeDelivery:execution] attempt=${attemptId} role=${role} chatroom=${row.chatroomId} task=${row.taskId} operation=inject result=task_hydration_missing`);
47707
- await recordDeliveryFailure(taskService, row.taskId, "injection_not_confirmed");
47716
+ if (!result?.stale) {
47717
+ await recordDeliveryFailure(taskService, row.taskId, "injection_not_confirmed");
47718
+ }
47708
47719
  } else if (result.kind === "failed") {
47709
47720
  console.warn(`[NativeDelivery:failure] attempt=${attemptId} role=${role} chatroom=${row.chatroomId} task=${row.taskId} operation=inject reason=${result.reason}`);
47710
47721
  await recordDeliveryFailure(taskService, row.taskId, result.reason);
@@ -47781,23 +47792,55 @@ async function processTasksUpdate(taskService, configurationService, pass, isTas
47781
47792
  ...startInput,
47782
47793
  ...ephemeralOverrides ? { overrides: ephemeralOverrides } : {}
47783
47794
  };
47795
+ const taskLookup = {
47796
+ chatroomId: task.chatroomId,
47797
+ role: task.agentConfig.role,
47798
+ taskId: task.taskId
47799
+ };
47800
+ const fullBeforeSlot = await taskService.loadAssignedTaskForAction(taskLookup);
47801
+ if (!fullBeforeSlot) {
47802
+ taskService.forgetStaleTask(taskLookup);
47803
+ console.warn(`[NativeDelivery:stale-task] chatroom=${task.chatroomId} role=${task.agentConfig.role} task=${task.taskId} reason=authoritative_task_missing`);
47804
+ return { kind: "task-unavailable", stale: true };
47805
+ }
47784
47806
  const slot = await acquireNativeDeliverySlot({
47785
47807
  ...effectiveStartInput,
47786
47808
  timeoutMs: 30000
47787
47809
  });
47788
- const full = await taskService.loadAssignedTaskForAction({
47810
+ const full = await taskService.loadAssignedTaskForAction(taskLookup);
47811
+ if (!full) {
47812
+ taskService.forgetStaleTask(taskLookup);
47813
+ console.warn(`[NativeDelivery:stale-task] chatroom=${task.chatroomId} role=${task.agentConfig.role} task=${task.taskId} reason=authoritative_task_missing_after_slot`);
47814
+ return { kind: "task-unavailable", stale: true };
47815
+ }
47816
+ if (!slot?.harnessSessionId)
47817
+ return { kind: "task-unavailable" };
47818
+ const delivery = {
47789
47819
  chatroomId: task.chatroomId,
47790
47820
  role: task.agentConfig.role,
47791
- taskId: task.taskId
47792
- });
47793
- if (!full || !slot?.harnessSessionId)
47794
- return { kind: "task-unavailable" };
47821
+ taskId: task.taskId,
47822
+ harnessSessionId: slot.harnessSessionId
47823
+ };
47824
+ options.onTaskDeliveryStarted?.(delivery);
47795
47825
  let delivered;
47796
- await taskService.deliverNativeTask(full, slot.harnessSessionId, (result) => {
47797
- delivered = result;
47798
- });
47799
- if (!delivered)
47826
+ try {
47827
+ await taskService.deliverNativeTask(full, slot.harnessSessionId, (result) => {
47828
+ delivered = result;
47829
+ });
47830
+ } catch (error51) {
47831
+ options.onTaskDeliveryFailed?.({
47832
+ ...delivery,
47833
+ reason: "injection_not_confirmed"
47834
+ });
47835
+ throw error51;
47836
+ }
47837
+ if (!delivered) {
47838
+ options.onTaskDeliveryFailed?.({
47839
+ ...delivery,
47840
+ reason: "injection_not_confirmed"
47841
+ });
47800
47842
  return { kind: "failed", reason: "injection_not_confirmed" };
47843
+ }
47801
47844
  return { kind: "delivered", delivered };
47802
47845
  }
47803
47846
  };
@@ -47887,6 +47930,7 @@ class AgentWorkManager {
47887
47930
  recordUncoveredTurnEnd: deps.taskService.recordUncoveredTurnEnd,
47888
47931
  isRedeliveryExhausted: deps.taskService.isRedeliveryExhausted,
47889
47932
  clearRedeliveryTracking: deps.taskService.clearRedeliveryTracking,
47933
+ forgetStaleTask: deps.taskService.forgetStaleTask,
47890
47934
  loadAssignedTaskForAction: deps.taskService.loadAssignedTaskForAction,
47891
47935
  deliverNativeTask: (task, harnessSessionId, onTaskDelivered) => this.nativeTaskDeliveryQueue.enqueue({ task, harnessSessionId, onTaskDelivered })
47892
47936
  };
@@ -48044,6 +48088,17 @@ class AgentWorkManager {
48044
48088
  return;
48045
48089
  }
48046
48090
  if (notification.kind === "periodic-reconcile") {
48091
+ const taskLookup2 = {
48092
+ chatroomId: notification.task.chatroomId,
48093
+ role: notification.task.agentConfig.role,
48094
+ taskId: notification.task.taskId
48095
+ };
48096
+ const currentTask2 = await this.deliveryTaskService.loadAssignedTaskForAction(taskLookup2);
48097
+ if (!currentTask2) {
48098
+ this.deliveryTaskService.forgetStaleTask(taskLookup2);
48099
+ console.warn(`[NativeDelivery:stale-task] chatroom=${taskLookup2.chatroomId} role=${taskLookup2.role} task=${taskLookup2.taskId} reason=periodic_authoritative_task_missing`);
48100
+ return;
48101
+ }
48047
48102
  await this.requestReconcile({
48048
48103
  chatroomId: notification.task.chatroomId,
48049
48104
  role: notification.task.agentConfig.role,
@@ -48070,6 +48125,17 @@ class AgentWorkManager {
48070
48125
  })?.taskId === notification.event.taskId) {
48071
48126
  return { handledEventIds: [notification.event.eventId] };
48072
48127
  }
48128
+ const taskLookup = {
48129
+ chatroomId: notification.event.chatroomId,
48130
+ role: notification.event.role,
48131
+ taskId: notification.event.taskId
48132
+ };
48133
+ const authoritativeTask = await this.deliveryTaskService.loadAssignedTaskForAction(taskLookup);
48134
+ if (!authoritativeTask) {
48135
+ this.deliveryTaskService.forgetStaleTask(taskLookup);
48136
+ console.warn(`[NativeDelivery:stale-task] chatroom=${taskLookup.chatroomId} role=${taskLookup.role} task=${taskLookup.taskId} reason=inbox_authoritative_task_missing`);
48137
+ return { handledEventIds: [notification.event.eventId] };
48138
+ }
48073
48139
  const deliveredTaskIds = await this.requestReconcile({
48074
48140
  chatroomId: notification.event.chatroomId,
48075
48141
  role: notification.event.role,
@@ -48165,12 +48231,23 @@ class AgentWorkManager {
48165
48231
  return [];
48166
48232
  return processTasksUpdate(this.deliveryTaskService, this.deps.configurationService, pass, ({ chatroomId, role, taskId }) => this.deps.agentTaskState.get({ chatroomId, role })?.taskId === taskId, {
48167
48233
  tasks,
48234
+ onTaskDeliveryStarted: (args2) => this.recordTaskDeliveryStarted(args2),
48235
+ onTaskDeliveryFailed: (args2) => this.recordTaskDeliveryFailed(args2),
48168
48236
  onTaskDelivered: (args2) => {
48169
48237
  this.recordTaskDelivered(args2);
48170
48238
  onTaskDelivered?.(args2);
48171
48239
  }
48172
48240
  }, this.deps.acquireNativeDeliverySlot);
48173
48241
  }
48242
+ recordTaskDeliveryStarted(args2) {
48243
+ this.deps.agentTaskState.start(args2);
48244
+ }
48245
+ recordTaskDeliveryFailed(args2) {
48246
+ const key = { chatroomId: args2.chatroomId, role: args2.role };
48247
+ if (this.deps.agentTaskState.get(key)?.taskId === args2.taskId) {
48248
+ this.deps.agentTaskState.clear(key);
48249
+ }
48250
+ }
48174
48251
  recordTaskDelivered(args2) {
48175
48252
  this.deps.agentTaskState.start(args2);
48176
48253
  }
@@ -108556,11 +108633,13 @@ var init_commands_reference = __esm(() => {
108556
108633
  init_command2();
108557
108634
  init_utils3();
108558
108635
  });
108559
-
108560
- // ../../services/backend/prompts/cli/roles/architect.ts
108561
- var init_architect3 = () => {};
108562
108636
  // ../../services/backend/prompts/cli/sections/core-responsibilities.ts
108563
108637
  var init_core_responsibilities = () => {};
108638
+ // ../../services/backend/prompts/cli/sections/inter-role-handoff-rule.ts
108639
+ function getInterRoleHandoffRule() {
108640
+ return "- **To communicate with another team role** → Use `chatroom handoff` to that role, even for a short test or status message. Do not use `chatroom message(s) send`: those are user-ingress commands that persist `senderRole=user` and `type=message`.";
108641
+ }
108642
+
108564
108643
  // ../../services/backend/prompts/cli/sections/handoff-rules.ts
108565
108644
  var init_handoff_rules = () => {};
108566
108645
  // ../../services/backend/prompts/cli/sections/proof-of-verification.ts
@@ -108577,6 +108656,33 @@ var init_sections = __esm(() => {
108577
108656
  init_operating_model();
108578
108657
  });
108579
108658
 
108659
+ // ../../services/backend/prompts/cli/roles/architect.ts
108660
+ var ARCHITECT_GUIDANCE;
108661
+ var init_architect3 = __esm(() => {
108662
+ init_sections();
108663
+ ARCHITECT_GUIDANCE = `## Architect Operating Model
108664
+
108665
+ You are the architect responsible for careful coding and system design. You are advisory only: do not implement code, edit files, or act as the builder.
108666
+
108667
+ ${"{SESSION_CONTINUITY}"}
108668
+
108669
+ ${getInterRoleHandoffRule()}
108670
+
108671
+ 1. Recover the authoritative user request and relevant chatroom history before designing. Inspect the repository and cite the existing modules, APIs, schemas, queries, tests, and conventions that constrain the change.
108672
+ 2. Treat the injected \`<handoff-templates>\` Architect Design Handoff Brief as authoritative. Complete every section in its exact order, using \`Not Applicable.\` only for a genuinely inapplicable section and never as filler.
108673
+ 3. Produce exactly one recommended, evidence-backed design. Do not present alternatives or generic architecture advice. Include concrete repository paths, domain model/entity ownership, lifecycle, invariants, identifiers and relationships; service/module boundaries; public/internal API signatures; side-effect ownership; and schema/query/mutation shapes.
108674
+ 4. Analyze concurrent writers and races, idempotency, ordering/monotonicity, retries, transactions, failure/recovery, primary read paths, indexes, projections/read models, query shapes, scan/transaction limits, and invalidation/subscription scope.
108675
+ 5. Account for Convex reactivity and bandwidth: avoid unnecessary reactive fanout and separate high-frequency heartbeat/liveness/status fields from low-frequency identity/configuration fields. Specify migration/backfill sequence, tests, acceptance criteria, and the implementation and verification sequence.
108676
+ 6. Keep the proposal within the user's request and the repository's established patterns. Do not expand scope, spawn subagents, implement the design, edit files, or act as the builder.
108677
+ 7. Hand the complete design brief to the configured entry point with the normal command, then stop:
108678
+
108679
+ \`\`\`bash
108680
+ chatroom handoff --chatroom-id="<chatroom-id>" --role="architect" --next-role="{ENTRY_POINT_ROLE}"
108681
+ \`\`\`
108682
+
108683
+ The handoff must contain every required brief section, repository evidence, chosen design, exact file/API/schema details, risks, acceptance criteria, tests, and implementation sequence the configured entry point needs to coordinate implementation. It must not contain implementation edits or alternative designs.`;
108684
+ });
108685
+
108580
108686
  // ../../services/backend/prompts/cli/roles/builder.ts
108581
108687
  var init_builder2 = __esm(() => {
108582
108688
  init_sections();
@@ -108589,7 +108695,31 @@ var init_planner2 = __esm(() => {
108589
108695
  });
108590
108696
 
108591
108697
  // ../../services/backend/prompts/cli/roles/uiux-engineer.ts
108592
- var init_uiux_engineer3 = () => {};
108698
+ var UIUX_ENGINEER_GUIDANCE;
108699
+ var init_uiux_engineer3 = __esm(() => {
108700
+ init_sections();
108701
+ UIUX_ENGINEER_GUIDANCE = `## UI/UX Engineer Operating Model
108702
+
108703
+ You are the UI/UX engineer responsible for producing one complete interface and experience design for the request. You are advisory only: do not implement code, edit files, or act as the builder.
108704
+
108705
+ ${"{SESSION_CONTINUITY}"}
108706
+
108707
+ ${getInterRoleHandoffRule()}
108708
+
108709
+ 1. Recover the authoritative user request and relevant chatroom history before designing. Inspect existing UI patterns, components, tokens, interaction conventions, and nearby tests that constrain the experience.
108710
+ 2. Treat the injected \`<handoff-templates>\` UI/UX Engineer Design Handoff Brief as authoritative. Complete every section in its exact order, using \`Not Applicable.\` only for a genuinely inapplicable section and never as filler.
108711
+ 3. Produce exactly one recommended, evidence-backed interface and experience design. Do not present alternatives or generic UX advice. Include concrete repository paths, complete user flows, and explicit loading, empty, error, success states (with loading, empty, error, and success states covered), plus disabled and retry states where applicable.
108712
+ 4. Specify exact keyboard shortcuts, focus order, keyboard navigation, focus restoration, accessible semantics and labels, component hierarchy and ownership, props/state/events, data boundaries, and interaction behavior.
108713
+ 5. Choose concrete ShadCN components using the Base UI backend and existing icon conventions. Specify exact Tailwind utility or semantic theme-token classes for layout, spacing, sizing, typography, states, responsive behavior, and dark mode; keep the styling theme-aware and make state ownership explicit. Also specify responsive breakpoints, visual feedback, destructive-action safeguards, and the UI/integration/accessibility test plan.
108714
+ 6. Keep the proposal within the user's request and the repository's established patterns. Do not expand scope, spawn subagents, implement the design, edit files, or act as the builder.
108715
+ 7. Hand the complete design brief to the configured entry point with the normal command, then stop:
108716
+
108717
+ \`\`\`bash
108718
+ chatroom handoff --chatroom-id="<chatroom-id>" --role="uiux-engineer" --next-role="{ENTRY_POINT_ROLE}"
108719
+ \`\`\`
108720
+
108721
+ The handoff must contain every required brief section, repository evidence, chosen flow, exact component/prop/state details, explicit states, accessibility details, ownership decisions, concrete classes/tokens, risks, acceptance criteria, tests, and implementation sequence the configured entry point needs to coordinate implementation. It must not contain implementation edits or alternative designs.`;
108722
+ });
108593
108723
 
108594
108724
  // ../../services/backend/prompts/cli/roles/planner-guidance-context.ts
108595
108725
  var init_planner_guidance_context = __esm(() => {
@@ -136096,4 +136226,4 @@ program2.hook("preAction", async (_thisCommand, actionCommand) => {
136096
136226
  });
136097
136227
  program2.parse();
136098
136228
 
136099
- //# debugId=35DA39C4D925D97464756E2164756E21
136229
+ //# debugId=7D24D868FFCC86DF64756E2164756E21