chatroom-cli 1.77.5 → 1.79.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
@@ -9916,10 +9916,6 @@ var init_api2 = __esm(() => {
9916
9916
  });
9917
9917
 
9918
9918
  // src/api.ts
9919
- var exports_api = {};
9920
- __export(exports_api, {
9921
- api: () => api
9922
- });
9923
9919
  var init_api3 = __esm(() => {
9924
9920
  init_api2();
9925
9921
  });
@@ -33039,6 +33035,7 @@ function startSessionEventForwarder(client4, options) {
33039
33035
  }
33040
33036
  case "busy": {
33041
33037
  clearRetryIdleTimeout();
33038
+ options.onActivity?.();
33042
33039
  return;
33043
33040
  }
33044
33041
  default: {
@@ -76374,24 +76371,6 @@ var init_register_agent = __esm(() => {
76374
76371
  init_services();
76375
76372
  init_convex_error();
76376
76373
  });
76377
-
76378
- // ../../services/backend/prompts/base/shared/context-rule.ts
76379
- function getContextRuleBlock(contextNewCmd, contextHint) {
76380
- return `**Context Rule:** Set a new context for every user message by default — skip ONLY when the message is clearly a follow-up of the current chatroom task. **Before running \`context new\`, run \`context read\` — if the pinned context already uses the same \`--trigger-message-id\` as this task's Origin Message ID, do NOT create another context** (avoids duplicate timeline dividers). Only the entry point role can set contexts:
76381
- \`\`\`bash
76382
- ${contextNewCmd}
76383
- \`\`\`
76384
- ${contextHint}`;
76385
- }
76386
-
76387
- // ../../services/backend/prompts/base/shared/token-activity-note.ts
76388
- function getTokenActivityInProgressNote() {
76389
- return "Begin working from the task content above. The daemon detects harness output (stdout tokens) and marks the task `in_progress` automatically — **do not run `task read`** unless you need backlog items or context details not shown in the delivery.";
76390
- }
76391
- function getNativeTokenActivityInProgressNote() {
76392
- return "Begin working from the task content above. The daemon detects harness output (stdout tokens) and marks the task `in_progress` automatically.";
76393
- }
76394
-
76395
76374
  // ../../services/backend/prompts/cli/context/context-template.ts
76396
76375
  function getContextViewTemplate() {
76397
76376
  return CONTEXT_VIEW_TEMPLATE;
@@ -76410,60 +76389,20 @@ var CONTEXT_VIEW_TEMPLATE = `## Goal
76410
76389
  - _Out-of-scope work or anti-patterns to skip._`;
76411
76390
 
76412
76391
  // ../../services/backend/prompts/cli/context/view-template.ts
76413
- function contextViewTemplateCommand(params) {
76414
- const prefix = params.cliEnvPrefix || "";
76415
- return `${prefix}chatroom context view-template`;
76416
- }
76417
76392
  var init_view_template = () => {};
76418
76393
 
76419
76394
  // ../../services/backend/prompts/cli/context/new.ts
76420
- function contextNewHint(params) {
76421
- const viewTemplateCmd = contextViewTemplateCommand({ cliEnvPrefix: params.cliEnvPrefix });
76422
- return `REQUIRED: All context content MUST conform to the template. Run \`${viewTemplateCmd}\` (no flags). \`--trigger-message-id\` must be the task's \`origin-message-id\` attribute (never \`task-id\`). Use the pre-filled value in the command above when provided.`;
76423
- }
76424
- function contextNewCommand(params) {
76425
- const prefix = params.cliEnvPrefix || "";
76426
- const chatroomId = params.chatroomId || "CHATROOM_ID";
76427
- const role = params.role || "ROLE";
76428
- const triggerMessageId = params.triggerMessageId ?? "ORIGIN_MESSAGE_ID";
76429
- const commandPrefix = `${prefix}chatroom context new --chatroom-id="${chatroomId}" --role="${role}" --trigger-message-id="${triggerMessageId}"`;
76430
- return formatStdinHeredocCommand(commandPrefix, CONTEXT_STDIN_DELIMITER, getContextViewTemplate());
76431
- }
76432
76395
  var init_new = __esm(() => {
76433
76396
  init_stdin_heredoc();
76434
76397
  init_view_template();
76435
76398
  });
76436
76399
 
76437
76400
  // ../../services/backend/prompts/cli/task-started/main-prompt.ts
76438
- function getTaskStartedPrompt(ctx) {
76439
- const { chatroomId, role, cliEnvPrefix, triggerMessageId } = ctx;
76440
- const contextNewCmd = contextNewCommand({
76441
- chatroomId,
76442
- role,
76443
- cliEnvPrefix,
76444
- triggerMessageId
76445
- });
76446
- return `### Start working
76447
-
76448
- ${getTokenActivityInProgressNote()}
76449
-
76450
- ${getContextRuleBlock(contextNewCmd, contextNewHint({ cliEnvPrefix }))}`;
76451
- }
76452
- function getTaskStartedPromptForHandoffRecipient(_ctx) {
76453
- return `### Start Working
76454
-
76455
- The task body contains your work description. ${getTokenActivityInProgressNote()}`;
76456
- }
76457
76401
  var init_main_prompt = __esm(() => {
76458
76402
  init_new();
76459
76403
  });
76460
76404
 
76461
76405
  // ../../services/backend/prompts/cli/task-started/index.ts
76462
- var exports_task_started = {};
76463
- __export(exports_task_started, {
76464
- getTaskStartedPromptForHandoffRecipient: () => getTaskStartedPromptForHandoffRecipient,
76465
- getTaskStartedPrompt: () => getTaskStartedPrompt
76466
- });
76467
76406
  var init_task_started = __esm(() => {
76468
76407
  init_main_prompt();
76469
76408
  });
@@ -76485,14 +76424,6 @@ Exactly one active waiter should own task delivery at a time. Additional or back
76485
76424
 
76486
76425
  After interruption or restart: complete any in-progress work, then restore a single foreground blocking \`get-next-task\` so chatroom tasks can arrive again.`;
76487
76426
  }
76488
- function getCompactionRecoveryNote(params) {
76489
- const { cliEnvPrefix, chatroomId, role } = params;
76490
- return `NOTE: If you are an agent that has undergone compaction or summarization, run:
76491
- ${cliEnvPrefix}chatroom get-system-prompt --chatroom-id="${chatroomId}" --role="${role}"
76492
- to reload your full system and role prompt. Then run:
76493
- ${cliEnvPrefix}chatroom context read --chatroom-id="${chatroomId}" --role="${role}"
76494
- to see your current chatroom task context.`;
76495
- }
76496
76427
  var init_reminder = () => {};
76497
76428
  // ../../services/backend/prompts/utils/index.ts
76498
76429
  var init_utils3 = __esm(() => {
@@ -76500,65 +76431,16 @@ var init_utils3 = __esm(() => {
76500
76431
  });
76501
76432
 
76502
76433
  // ../../services/backend/prompts/base/shared/getting-started-content.ts
76503
- function getContextGainingGuidance(params) {
76504
- const { chatroomId, role, convexUrl, agentType } = params;
76505
- const cliEnvPrefix = getCliEnvPrefix(convexUrl);
76506
- const typeValue = agentType && agentType !== "unset" ? agentType : "<remote|custom>";
76507
- return `## Getting Started
76508
-
76509
- ### Workflow Loop
76510
-
76511
- \`\`\`mermaid
76512
- flowchart LR
76513
- A([Start]) --> B[register-agent]
76514
- B --> C[get-next-task
76515
- chatroom task delivery]
76516
- C --> D[Do Work]
76517
- D --> E[handoff]
76518
- E --> C
76519
- \`\`\`
76520
-
76521
- ### Task delivery and activity
76522
-
76523
- When \`get-next-task\` delivers a chatroom task, the **full task content is included in the output**. ${getTokenActivityInProgressNote()}
76524
-
76525
- ⚠️ Remember your two-level model: completing a **chatroom task** (Level B) does NOT end your **session** (Level A). After every handoff, you must run \`get-next-task\` again to continue the session.
76526
-
76527
- ### Context Recovery (after compaction/summarization)
76528
-
76529
- ${getCompactionRecoveryNote({ cliEnvPrefix, chatroomId, role })}
76530
-
76531
- CLI harnesses do not support in-session compaction. After context is lost, the daemon performs a hard restart — you must run \`get-next-task\` again to rejoin the chatroom.
76532
-
76533
- ### Register Agent
76534
- Register your agent type before starting work.
76535
-
76536
- \`\`\`bash
76537
- ${cliEnvPrefix}chatroom register-agent --chatroom-id="${chatroomId}" --role="${role}" --type=${typeValue}
76538
- \`\`\`
76539
-
76540
- ### Get Next Task
76541
- Listen for incoming tasks assigned to your role. A foreground \`get-next-task\` blocks until the user or team message is ready, then resolves with that message as a chatroom task—infer intent from the message rather than following numbered next-steps blindly.
76542
-
76543
- \`\`\`bash
76544
- ${cliEnvPrefix}chatroom get-next-task --chatroom-id="${chatroomId}" --role="${role}"
76545
- \`\`\`
76546
-
76547
- **This loop never ends.** A session (Level A) processes many chatroom tasks (Level B). Each handoff completes Level B — \`get-next-task\` continues Level A. Do not stop or exit after a handoff.
76548
- `;
76549
- }
76550
76434
  var init_getting_started_content = __esm(() => {
76551
76435
  init_reminder();
76552
76436
  init_utils3();
76553
76437
  });
76554
76438
 
76555
76439
  // ../../services/backend/prompts/cli/index.ts
76556
- var getTaskStartedPrompt2, getTaskStartedPromptForHandoffRecipient2;
76557
76440
  var init_cli = __esm(() => {
76558
76441
  init_task_started();
76559
76442
  init_reminder();
76560
76443
  init_getting_started_content();
76561
- ({ getTaskStartedPrompt: getTaskStartedPrompt2, getTaskStartedPromptForHandoffRecipient: getTaskStartedPromptForHandoffRecipient2 } = exports_task_started);
76562
76444
  });
76563
76445
 
76564
76446
  // src/commands/get-next-task/get-next-task-session-service.ts
@@ -77373,35 +77255,52 @@ var init_builder_to_planner = __esm(() => {
77373
77255
  init_role_guidance_disclosure();
77374
77256
  });
77375
77257
 
77376
- // ../../services/backend/prompts/teams/duo/handoff-templates/enhancer-to-planner.ts
77377
- function getEnhancerToPlannerHandoffTemplate() {
77378
- return `${getHandoffRecipientVisibilityCallout("planner")}
77379
-
77380
- ${getHandoffReportTemplateIntro("Planning Feedback (Enhancer → Planner)")}
77381
-
77382
- The planner sent you three XML sections. Your job is **advisory adversarial review** — raise risks, challenge assumptions, and help the planner align with user intent. **Do not prescribe file-level changes or rewrite their builder brief.** The planner makes the final call.
77383
-
77384
- \`\`\`markdown
77258
+ // ../../services/backend/prompts/utils/enhancer-feedback-template-body.ts
77259
+ function getEnhancerFeedbackTemplateBody() {
77260
+ return `<handoff-overview>
77385
77261
  ## Summary
77386
77262
  <one paragraph: overall assessment — strengths, main risks, and whether the approach is sound>
77387
77263
 
77388
77264
  ## User intent alignment
77389
77265
  <does the planner's reading of the user request match what was asked? misreadings or missing constraints?>
77266
+ </handoff-overview>
77390
77267
 
77391
- ## Risks &amp; failure modes
77392
- <what could go wrong if they proceed as planned? common pitfalls for this kind of work?>
77268
+ <!-- UI collapses proofs, direction, and notes by default; overview and action required are expanded -->
77393
77269
 
77270
+ <handoff-proofs>
77271
+ ## Reasoning review
77272
+ <logical errors, weak inference, contradictions — challenge assumptions>
77273
+ </handoff-proofs>
77274
+
77275
+ <handoff-direction>
77276
+ ## Alignment with eventual user handoff
77277
+ <will this approach produce a credible planner→user report? what's missing for user-facing completeness?>
77278
+ </handoff-direction>
77279
+
77280
+ <handoff-notes>
77394
77281
  ## Knowledge gaps
77395
77282
  <facts, context, or research the planner should verify — advisory questions, not answers from codebase>
77283
+ </handoff-notes>
77396
77284
 
77397
- ## Reasoning review
77398
- <logical errors, weak inference, contradictions — challenge assumptions>
77285
+ <handoff-action>
77286
+ ## Risks & failure modes
77287
+ <what could go wrong if they proceed as planned? common pitfalls for this kind of work?>
77399
77288
 
77400
77289
  ## Questions for the planner
77401
77290
  <specific questions they should answer before delegating — not instructions disguised as questions>
77291
+ </handoff-action>`;
77292
+ }
77402
77293
 
77403
- ## Alignment with eventual user handoff
77404
- <will this approach produce a credible planner→user report? what's missing for user-facing completeness?>
77294
+ // ../../services/backend/prompts/teams/duo/handoff-templates/enhancer-to-planner.ts
77295
+ function getEnhancerToPlannerHandoffTemplate() {
77296
+ return `${getHandoffRecipientVisibilityCallout("planner")}
77297
+
77298
+ ${getHandoffReportTemplateIntro("Planning Feedback (Enhancer → Planner)")}
77299
+
77300
+ The planner sent you three XML sections. Your job is **advisory adversarial review** — raise risks, challenge assumptions, and help the planner align with user intent. **Do not prescribe file-level changes or rewrite their builder brief.** The planner makes the final call.
77301
+
77302
+ \`\`\`markdown
77303
+ ${getEnhancerFeedbackTemplateBody()}
77405
77304
  \`\`\`
77406
77305
 
77407
77306
  Return only the feedback markdown — no preamble. Follow this structure; omit sections that truly do not apply.`;
@@ -77910,24 +77809,6 @@ function formatDecodeError(error) {
77910
77809
  }
77911
77810
 
77912
77811
  // ../../services/backend/prompts/native/session-continuity.ts
77913
- function getSessionContinuityLine(nativeIntegration) {
77914
- if (nativeIntegration) {
77915
- return "";
77916
- }
77917
- return "Completing a **chatroom task** (Level B) does NOT end your **session** (Level A). After every handoff, run `get-next-task` to continue.";
77918
- }
77919
- function getHandoffContinuityRule(nativeIntegration) {
77920
- if (nativeIntegration) {
77921
- return "";
77922
- }
77923
- return "⚠️ After ANY handoff (including to `user`), you must run `get-next-task` to stay in the session.";
77924
- }
77925
- function getOperatingModelLoopFooter(nativeIntegration) {
77926
- return nativeIntegration ? "Hand off when complete" : "Run get-next-task";
77927
- }
77928
- function getNativePlannerDelegationWaitNote() {
77929
- return `After delegating to the builder, **run handoff as your last action and end your turn** — no further tool calls after handoff. The system delivers their handback when they finish — do not poll \`messages list\`, sleep, or run other tools while waiting.`;
77930
- }
77931
77812
  function getNativeHandoffTurnEndGuidance(nextRole) {
77932
77813
  const lines = [
77933
77814
  "",
@@ -77943,103 +77824,10 @@ function getNativeHandoffTurnEndGuidance(nextRole) {
77943
77824
  }
77944
77825
 
77945
77826
  // ../../services/backend/prompts/cli/handoff/command.ts
77946
- function handoffCommand(params) {
77947
- const prefix = params.cliEnvPrefix || "";
77948
- const chatroomId = params.chatroomId || "<chatroom-id>";
77949
- const role = params.role || "<role>";
77950
- const nextRole = params.nextRole || "<target>";
77951
- const placeholder = params.messagePlaceholder ?? "[Your message here]";
77952
- const commandPrefix = `${prefix}chatroom handoff --chatroom-id="${chatroomId}" --role="${role}" --next-role="${nextRole}"`;
77953
- return formatStdinHeredocCommand(commandPrefix, HANDOFF_STDIN_DELIMITER, placeholder, {
77954
- messageMarker: HANDOFF_MESSAGE_MARKER
77955
- });
77956
- }
77957
77827
  var init_command2 = __esm(() => {
77958
77828
  init_stdin_heredoc();
77959
77829
  });
77960
-
77961
- // ../../services/backend/prompts/types/sections.ts
77962
- function createSection(id3, type, content) {
77963
- return { id: id3, type, content };
77964
- }
77965
- function composeSections(sections) {
77966
- return sections.filter((s) => s.content.trim()).map((s) => s.content).join(`
77967
-
77968
- `).trim();
77969
- }
77970
-
77971
77830
  // ../../services/backend/prompts/sections/commands-reference.ts
77972
- function getCommandsReferenceSection(params) {
77973
- const cliEnvPrefix = getCliEnvPrefix(params.convexUrl);
77974
- const handoffCmd = handoffCommand({
77975
- chatroomId: params.chatroomId,
77976
- role: params.role,
77977
- nextRole: "<target>",
77978
- cliEnvPrefix
77979
- });
77980
- const waitCmd = getNextTaskCommand({
77981
- chatroomId: params.chatroomId,
77982
- role: params.role,
77983
- cliEnvPrefix
77984
- });
77985
- const content = `### Commands
77986
-
77987
- **Complete chatroom task and hand off:**
77988
-
77989
- \`\`\`bash
77990
- ${handoffCmd}
77991
- \`\`\`
77992
-
77993
- ${HANDOFF_BODY_GUIDANCE}
77994
-
77995
- **Continue receiving messages after \`handoff\`:**
77996
- \`\`\`
77997
- ${waitCmd}
77998
- \`\`\`
77999
-
78000
- ${getNextTaskReminder()}
78001
-
78002
- **Reference commands:**
78003
- - List recent messages: \`${cliEnvPrefix}chatroom messages list --chatroom-id="${params.chatroomId}" --role="${params.role}" --sender-role=user --limit=5 --full\`
78004
- - Git log: \`git log --oneline -10\`
78005
-
78006
- **Recovery commands** (only needed after compaction/restart):
78007
- - Reload system prompt: \`${cliEnvPrefix}chatroom get-system-prompt --chatroom-id="${params.chatroomId}" --role="${params.role}"\`
78008
- - Reload role guidance: \`${roleGuidanceCommand({ chatroomId: params.chatroomId, role: params.role, cliEnvPrefix })}\`
78009
- - Read current chatroom task context: \`${cliEnvPrefix}chatroom context read --chatroom-id="${params.chatroomId}" --role="${params.role}"\``;
78010
- return createSection("commands-reference", "knowledge", content);
78011
- }
78012
- function getNativeCommandsReferenceSection(params) {
78013
- const cliEnvPrefix = getCliEnvPrefix(params.convexUrl);
78014
- const handoffCmd = handoffCommand({
78015
- chatroomId: params.chatroomId,
78016
- role: params.role,
78017
- nextRole: "<target>",
78018
- cliEnvPrefix
78019
- });
78020
- const content = `### Commands
78021
-
78022
- **Complete chatroom task and hand off:**
78023
-
78024
- \`\`\`bash
78025
- ${handoffCmd}
78026
- \`\`\`
78027
-
78028
- ${HANDOFF_BODY_GUIDANCE}
78029
-
78030
- **Do not run \`register-agent\`** — your session was registered when the harness started.
78031
-
78032
- **Reference commands:**
78033
- - List recent messages: \`${cliEnvPrefix}chatroom messages list --chatroom-id="${params.chatroomId}" --role="${params.role}" --sender-role=user --limit=5 --full\`
78034
- - Git log: \`git log --oneline -10\`
78035
-
78036
- **Recovery commands** (only needed after compaction/restart):
78037
- - Reload system prompt: \`${cliEnvPrefix}chatroom get-system-prompt --chatroom-id="${params.chatroomId}" --role="${params.role}"\`
78038
- - Reload role guidance: \`${roleGuidanceCommand({ chatroomId: params.chatroomId, role: params.role, cliEnvPrefix })}\`
78039
- - Read current chatroom task context: \`${cliEnvPrefix}chatroom context read --chatroom-id="${params.chatroomId}" --role="${params.role}"\``;
78040
- return createSection("commands-reference-native", "knowledge", content);
78041
- }
78042
- var HANDOFF_BODY_GUIDANCE = `Fill in the message using the matching template from \`<handoff-templates>\` in your task delivery output. Replace \`[Your message here]\` with that template content. The closing line must be exactly \`CHATROOM_HANDOFF_END\` (not \`EOF\`).`;
78043
77831
  var init_commands_reference = __esm(() => {
78044
77832
  init_command();
78045
77833
  init_reminder();
@@ -78048,650 +77836,25 @@ var init_commands_reference = __esm(() => {
78048
77836
  });
78049
77837
 
78050
77838
  // ../../services/backend/prompts/cli/backlog/command.ts
78051
- function backlogAddCommand(params) {
78052
- const prefix = params.cliEnvPrefix || "";
78053
- const chatroomId = params.chatroomId || "<id>";
78054
- const role = params.role || "<role>";
78055
- const placeholder = params.contentPlaceholder ?? "Your backlog item content here";
78056
- const commandPrefix = `${prefix}chatroom backlog add --chatroom-id=${chatroomId} --role=${role}`;
78057
- return formatStdinHeredocCommand(commandPrefix, BACKLOG_STDIN_DELIMITER, placeholder);
78058
- }
78059
- function backlogUpdateCommand(params) {
78060
- const prefix = params.cliEnvPrefix || "";
78061
- const chatroomId = params.chatroomId || "<id>";
78062
- const role = params.role || "<role>";
78063
- const backlogItemId = params.backlogItemId || "<id>";
78064
- const placeholder = params.contentPlaceholder ?? "New content here";
78065
- const commandPrefix = `${prefix}chatroom backlog update --chatroom-id=${chatroomId} --role=${role} --backlog-item-id=${backlogItemId}`;
78066
- return formatStdinHeredocCommand(commandPrefix, BACKLOG_STDIN_DELIMITER, placeholder);
78067
- }
78068
77839
  var init_command3 = __esm(() => {
78069
77840
  init_stdin_heredoc();
78070
77841
  });
78071
77842
 
78072
77843
  // ../../services/backend/src/domain/usecase/skills/modules/backlog/index.ts
78073
- var backlogSkill;
78074
77844
  var init_backlog = __esm(() => {
78075
77845
  init_command3();
78076
- backlogSkill = {
78077
- skillId: "backlog",
78078
- name: "Backlog Reference",
78079
- description: "Full backlog command reference: list/add/update, scoring, completion, close, export/import, and workflow guides.",
78080
- getPrompt: (cliEnvPrefix) => `You have been activated with the "backlog" skill.
78081
-
78082
- ## Command Reference
78083
-
78084
- ### List
78085
- \`\`\`
78086
- ${cliEnvPrefix}chatroom backlog list --chatroom-id=<id> --role=<role>
78087
- \`\`\`
78088
- Options: \`--limit=<n>\`, \`--sort=date:desc|priority:desc\`, \`--filter=unscored\` (only items without a priority score)
78089
-
78090
- The list output shows scoring info (complexity, value, priority) for each item if it has been scored.
78091
-
78092
- ### History
78093
- \`\`\`
78094
- ${cliEnvPrefix}chatroom backlog history --chatroom-id=<id> --role=<role>
78095
- \`\`\`
78096
- Options: \`--from=YYYY-MM-DD\`, \`--to=YYYY-MM-DD\`, \`--limit=<n>\`
78097
-
78098
- Defaults: last 30 days through today; shows completed and closed tasks in range.
78099
-
78100
- Use \`history\` for finished work; use \`list\` for active backlog items.
78101
-
78102
- ### Add
78103
- Content via **stdin / heredoc** or \`--content-file\`:
78104
-
78105
- \`\`\`
78106
- ${backlogAddCommand({ cliEnvPrefix })}
78107
- \`\`\`
78108
-
78109
- \`\`\`
78110
- ${cliEnvPrefix}chatroom backlog add --chatroom-id=<id> --role=<role> --content-file=./task.md
78111
- \`\`\`
78112
-
78113
- ### Update
78114
- Replace the **text content** of an existing item. Allowed only while the item is in \`backlog\` status. Same input pattern as **add** (stdin/heredoc or \`--content-file\`).
78115
-
78116
- \`\`\`
78117
- ${backlogUpdateCommand({ cliEnvPrefix })}
78118
- \`\`\`
78119
-
78120
- \`\`\`
78121
- ${cliEnvPrefix}chatroom backlog update --chatroom-id=<id> --role=<role> --backlog-item-id=<id> --content-file=./revised.md
78122
- \`\`\`
78123
-
78124
- Use **update** to revise a description in place instead of adding a superseding item.
78125
-
78126
- ### Score
78127
- **Requires at least one** of \`--complexity\`, \`--value\`, or \`--priority\` (you can combine multiple).
78128
-
78129
- \`\`\`
78130
- ${cliEnvPrefix}chatroom backlog score --chatroom-id=<id> --role=<role> --backlog-item-id=<id> \\
78131
- [--complexity=<low|medium|high>] \\
78132
- [--value=<low|medium|high>] \\
78133
- [--priority=<n>]
78134
- \`\`\`
78135
-
78136
- \`--priority\` must be an integer (higher = more important). There is no enforced max in the CLI.
78137
-
78138
- **Important**: Only score items that do not already have all three fields set (complexity, value, priority).
78139
- Check the list output — items showing "Score: ..." are already scored. Skip them to avoid overwriting.
78140
-
78141
- ### Complete
78142
- \`\`\`
78143
- ${cliEnvPrefix}chatroom backlog complete --chatroom-id=<id> --role=<role> --backlog-item-id=<id> [-f|--force]
78144
- \`\`\`
78145
-
78146
- Optional \`-f\` / \`--force\` is a registered flag (see \`chatroom backlog complete --help\`). It is **not** forwarded to the Convex mutation yet, so it does not change server behavior today; omit it unless your runbook says otherwise.
78147
-
78148
- ### Reopen
78149
- \`\`\`
78150
- ${cliEnvPrefix}chatroom backlog reopen --chatroom-id=<id> --role=<role> --backlog-item-id=<id>
78151
- \`\`\`
78152
-
78153
- ### Mark for Review
78154
- \`\`\`
78155
- ${cliEnvPrefix}chatroom backlog mark-for-review --chatroom-id=<id> --role=<role> --backlog-item-id=<id>
78156
- \`\`\`
78157
-
78158
- ### Export
78159
- \`\`\`
78160
- ${cliEnvPrefix}chatroom backlog export --chatroom-id=<id> --role=<role> [--path=<directory>]
78161
- \`\`\`
78162
- Exports all backlog items (status=\`backlog\`) to a \`backlog-export.json\` file in the specified directory.
78163
- Creates the directory if it doesn't exist.
78164
- Default path (if \`--path\` is omitted): \`<cwd>/.chatroom/exports/\`
78165
-
78166
- ### Import
78167
- \`\`\`
78168
- ${cliEnvPrefix}chatroom backlog import --chatroom-id=<id> --role=<role> [--path=<directory>]
78169
- \`\`\`
78170
- Imports backlog items from a \`backlog-export.json\` file in the specified directory.
78171
- - **Idempotent**: skips items whose content already exists (matched by SHA-256 content hash)
78172
- - **Staleness warning**: warns if the export is older than 7 days
78173
- Default path (if \`--path\` is omitted): \`<cwd>/.chatroom/exports/\`
78174
-
78175
- ### Close
78176
- Retires an item as stale, superseded, or duplicate. **\`--reason\` is required** (audit trail).
78177
-
78178
- \`\`\`
78179
- ${cliEnvPrefix}chatroom backlog close --chatroom-id=<id> --role=<role> --backlog-item-id=<id> --reason="duplicate of XYZ"
78180
- \`\`\`
78181
-
78182
- ⚠️ **RESTRICTED: Only use when the user explicitly asks you to close an item.**
78183
- Agents must NEVER close backlog items autonomously. If an item looks stale or already implemented, prefer \`mark-for-review\` so the user decides.
78184
-
78185
- Give a concise, factual reason (e.g. \`User confirmed: shipped in PR #119\`).
78186
-
78187
- ---
78188
-
78189
- ## Lifecycle
78190
-
78191
- Backlog items move through explicit statuses. **When you raise a PR for user review, use \`mark-for-review\` — not \`complete\`.** Only mark \`complete\` after the PR is merged and verified (or the user confirms).
78192
-
78193
- \`\`\`mermaid
78194
- stateDiagram-v2
78195
- [*] --> backlog: user creates
78196
- backlog --> pending_user_review: agent raises PR (mark-for-review)
78197
- pending_user_review --> closed: user confirms / PR merged (complete)
78198
- backlog --> closed: stale/superseded (close)
78199
- closed --> backlog: reopen
78200
- \`\`\`
78201
-
78202
- ### Command decision table
78203
-
78204
- | Situation | Command |
78205
- |-----------|---------|
78206
- | Fix PR opened, awaiting user review/merge | \`mark-for-review\` |
78207
- | PR merged and verified | \`complete\` |
78208
- | Stale/duplicate/won't fix | \`close --reason=...\` |
78209
- | Mistakenly completed early | \`reopen\` then \`mark-for-review\` |
78210
-
78211
- Reference: \`docs/plans/backlog-item-lifecycle-and-attachments.md\`
78212
-
78213
- ---
78214
-
78215
- ## Workflows
78216
-
78217
- ### 1. Score Unscored Items
78218
-
78219
- \`\`\`mermaid
78220
- flowchart TD
78221
- A([Start]) --> B[List backlog items]
78222
- B --> C{Any unscored?}
78223
- C -->|No| D([Done])
78224
- C -->|Yes| E["Check item: does it already have complexity + value + priority set?"]
78225
- E -->|Already scored| F[Skip — do not overwrite existing score]
78226
- F --> C
78227
- E -->|Not scored| G[Score item: complexity, value, priority]
78228
- G --> C
78229
- \`\`\`
78230
-
78231
- An item is "already scored" if the list output shows "Score: complexity=... | value=... | priority=...".
78232
-
78233
- ### 2. After Completing a Backlog Task (PR raised)
78234
-
78235
- \`\`\`mermaid
78236
- flowchart TD
78237
- A([Implementation complete]) --> B[Open PR for user review]
78238
- B --> C["mark-for-review (NOT complete)"]
78239
- C --> D[Hand off to user with PR link + summary]
78240
- D --> E([User reviews in Pending Review section])
78241
- \`\`\`
78242
-
78243
- Moves item to \`pending_user_review\`. User confirms completion (\`complete\`) or sends back for rework (\`reopen\`).
78244
-
78245
- ### 3. Continuous Backlog Execution
78246
-
78247
- Only activate when the user explicitly instructs autonomous execution
78248
- (e.g. "work through the backlog", "autonomously implement backlog items").
78249
-
78250
- \`\`\`mermaid
78251
- flowchart TD
78252
- A([Start]) --> B[List all backlog items]
78253
- B --> C{Any unscored?}
78254
- C -->|Yes| D["Score only items missing complexity/value/priority\\n(skip already-scored items)"] --> E[Re-list]
78255
- C -->|No| E
78256
- E --> F["Select items: complexity=low AND value=high"]
78257
- F --> G{Qualifying items?}
78258
- G -->|No| H([Hand off — no high-ROI items found])
78259
- G -->|Yes| I[Take next item]
78260
- I --> J{Already implemented?\\nCheck codebase / recent commits}
78261
- J -->|Yes — stale| K["Mark for review\\n(note: already implemented)"]
78262
- J -->|No| L[Implement: code changes + PR]
78263
- L --> K
78264
- K --> M[Mark item for review]
78265
- M --> N{More items?}
78266
- N -->|Yes| I
78267
- N -->|No| O[Hand off to user with full summary]
78268
- O --> P([Done])
78269
- \`\`\`
78270
-
78271
- Stale item = backlog task already present in the codebase. Mark immediately; skip implementation.
78272
- ROI = low complexity × high value.
78273
-
78274
- ### 4. Backlog Cleanup
78275
-
78276
- Follow these steps to clean up the backlog by identifying and closing stale items.
78277
-
78278
- 1. List all backlog items:
78279
- \`\`\`
78280
- ${cliEnvPrefix}chatroom backlog list --chatroom-id=<id> --role=<role>
78281
- \`\`\`
78282
-
78283
- 2. For each item, assess staleness:
78284
- - Read the content carefully
78285
- - If the item is still valid but the **wording is wrong**, use \`backlog update\` to fix the description in place (do not add a duplicate item)
78286
- - Check if already implemented (look at recent commits, PRs, or existing code)
78287
- - Check if superseded by a newer backlog item
78288
-
78289
- 3. For stale items, mark for review:
78290
- \`\`\`
78291
- ${cliEnvPrefix}chatroom backlog mark-for-review --chatroom-id=<id> --role=<role> --backlog-item-id=<item-id>
78292
- \`\`\`
78293
- **Important:** Always mark for review — do NOT close directly. Let the user confirm.
78294
-
78295
- 4. If you are the coordinator, delegate assessment to workers:
78296
- - Builder checks codebase to determine if items are stale
78297
- - Builder marks stale items for review and reports back
78298
-
78299
- 5. Report summary: items reviewed, marked for review, kept, needs clarification
78300
-
78301
- ### 5. Export / Import Backlog
78302
-
78303
- Use export/import to transfer backlog items between workspaces or for backup.
78304
- Default path: \`<cwd>/.chatroom/exports/\` — omit \`--path\` to use this.
78305
-
78306
- **Export workflow:**
78307
- \`\`\`mermaid
78308
- flowchart TD
78309
- A([Start]) --> B["Export backlog"]
78310
- B --> C["chatroom backlog export\\n(writes to <cwd>/.chatroom/exports/ by default)"]
78311
- C --> D["File written: backlog-export.json"]
78312
- D --> E([Done — report file path to user])
78313
- \`\`\`
78314
-
78315
- **Import workflow:**
78316
- \`\`\`mermaid
78317
- flowchart TD
78318
- A([Start]) --> B["Import backlog"]
78319
- B --> C["chatroom backlog import\\n(reads from <cwd>/.chatroom/exports/ by default)"]
78320
- C --> D{Staleness warning?}
78321
- D -->|Yes — export > 7 days old| E["Warn user: export may be stale"]
78322
- D -->|No| F["Import items (skip duplicates)"]
78323
- E --> F
78324
- F --> G["Report: total / imported / skipped"]
78325
- G --> H([Done])
78326
- \`\`\`
78327
-
78328
- **Key points:**
78329
- - Default path is \`<cwd>/.chatroom/exports/\` — no \`--path\` needed for standard usage
78330
- - Use \`--path=<dir>\` to override with a custom directory
78331
- - Imports are idempotent — running import twice with the same file won't create duplicates
78332
- - Each item is identified by a SHA-256 hash of its content`
78333
- };
78334
77846
  });
78335
77847
 
78336
77848
  // ../../services/backend/src/domain/usecase/skills/modules/code-review/index.ts
78337
- var codeReviewSkill;
78338
- var init_code_review = __esm(() => {
78339
- codeReviewSkill = {
78340
- skillId: "code-review",
78341
- name: "Code Review",
78342
- description: "Use this skill when reviewing, auditing, or giving feedback on code. Covers ten pillars: simplification, type drift, duplication, design patterns, security, test quality, ownership/observability, dead code elimination, incomplete implementations, and hallucinated content.",
78343
- getPrompt: (_cliEnvPrefix) => `You have been activated with the "code-review" skill.
78344
-
78345
- # AI Code Review — Tech Debt Prevention
78346
-
78347
- You are reviewing code that was fully or partially generated by an AI tool. Your job is not
78348
- just to check if it works — working code is the floor, not the ceiling. Your job is to assess
78349
- whether it is maintainable, secure, and coherent with the broader codebase.
78350
-
78351
- AI code is highly functional but architecturally blind. It implements the prompt without
78352
- considering existing patterns, refactoring opportunities, or long-term cost. Research from
78353
- 2025–2026 shows AI code carries 1.75x more logic errors, 1.64x more maintainability issues,
78354
- and 1.57x more security findings than human-written code (CodeRabbit, 2025). 66% of developers
78355
- report spending more time fixing AI output than it saved (Stack Overflow, 2026).
78356
-
78357
- Apply the ten pillars below in priority order.
78358
-
78359
- ---
78360
-
78361
- ## How to run a review
78362
-
78363
- 1. Read the code in full before making any comments — do not flag issues as you scan
78364
- 2. Apply each pillar in order; stop and note findings as you go
78365
- 3. Classify each finding as BLOCK (must fix before merge) or FLAG (must be addressed by author)
78366
- 4. Summarise findings at the end using the output template below
78367
- 5. If the PR is over ~300 lines of net-new AI code, recommend decomposition before review
78368
-
78369
- ---
78370
-
78371
- ## Pillar 1 — Simplification (Highest Priority)
78372
-
78373
- AI generates more code than needed. The average developer checked in 75% more code in 2025
78374
- than in 2022 — volume that the team now has to maintain. AI agents never suggest refactoring,
78375
- so complexity accumulates silently.
78376
-
78377
- Look for:
78378
- - Functions over ~40 lines or classes over ~200 lines with no clear single responsibility
78379
- - Monolithic architecture: 40–50% of AI code defaults to tightly-coupled structures that
78380
- reverse a decade of modular progress (OX Security, 2025)
78381
- - Phantom Bugs: logic handling highly improbable edge cases, adding complexity with no benefit
78382
- (found in 20–30% of AI code)
78383
- - Dead code, unused imports, or leftover scaffolding from generation
78384
- - PRs that touch services, libraries, infrastructure, and tests in a single change
78385
-
78386
- Ask: Is there a simpler path to the same outcome? Would a new team member understand this
78387
- without help? Can this function be split without losing meaning?
78388
-
78389
- Action: Flag any function over ~40 lines. Require decomposition or written justification
78390
- before merge.
78391
-
78392
- ---
78393
-
78394
- ## Pillar 2 — Type Drift (High Priority)
78395
-
78396
- AI generates code in isolation from the broader type system. Type inconsistencies introduced
78397
- here surface later as null pointer exceptions, silent failures, and cross-service contract
78398
- mismatches. A University of Naples study of 500k+ samples (Aug 2025) confirmed these are the
78399
- most reliably catchable issues via static analysis — meaning they should never reach review.
78400
-
78401
- Look for:
78402
- - \`any\` usage: defeats TypeScript entirely; AI reaches for it when uncertain
78403
- - Unsafe \`as\` assertions: suppresses the compiler rather than satisfying it
78404
- - Missing \`strictNullChecks\` compliance — null/undefined slipping through unchecked
78405
- - Boundary drift: API endpoints returning different shapes across execution paths
78406
- - Configuration drift: divergent \`tsconfig\` settings or ESLint rules added incrementally
78407
- - Leaked internals: AI exposing implementation details that should be encapsulated
78408
-
78409
- Ask: Are all return types and parameters explicitly typed? Are API contract types shared and
78410
- stable? Does this match existing type conventions, or introduce a new pattern?
78411
-
78412
- Action: \`strict: true\` in \`tsconfig.json\` is a hard gate. Any PR disabling strict settings
78413
- requires explicit team sign-off.
78414
-
78415
- ---
78416
-
78417
- ## Pillar 3 — Duplication (High Priority)
78418
-
78419
- GitClear's 2025 analysis of 211 million changed lines found duplicated code blocks grew 8x
78420
- in one year, and copy/pasted code surpassed refactored code for the first time in history.
78421
- OX Security found "Bugs Déjà-Vu" in 70–80% of AI codebases: identical bugs recurring in
78422
- multiple locations because logic was never abstracted.
78423
-
78424
- Look for:
78425
- - Duplicate utility logic across files — each instance works, but no shared abstraction exists
78426
- - "Vanilla Style" rebuilds: AI reconstructing functionality from scratch instead of using
78427
- existing libraries, SDKs, or internal utilities (40–50% of AI code, OX Security)
78428
- - Duplicated validation, auth checks, and input sanitization
78429
- - Copy-pasted try/catch blocks instead of centralised error handling
78430
- - New dependencies that the existing codebase already covers
78431
-
78432
- Ask: Does an equivalent utility already exist? Is this logic duplicated anywhere else?
78433
- Use AST-level search, not just grep.
78434
-
78435
- Action: Require a codebase search before approving any new utility function. Run SonarQube,
78436
- CodeClimate, or Codacy as a PR gate for duplication thresholds.
78437
-
78438
- ---
78439
-
78440
- ## Pillar 4 — Design Pattern Compliance (Standard Priority)
78441
-
78442
- AI implements the prompt. It does not check the ADR log, existing service patterns, or
78443
- architectural conventions. OX Security identified "By-The-Book Fixation" in 80–90% of AI
78444
- code: rigid application of generic best practices, missing the better solution for this
78445
- specific context.
78446
-
78447
- Look for:
78448
- - Pattern violations: raw \`fetch\` where an API service layer exists; new state patterns where
78449
- a store convention is already established
78450
- - SOLID violations:
78451
- - Single Responsibility: see Pillar 1
78452
- - Open/Closed: code requiring modification rather than extension to add new behaviour
78453
- - Dependency Inversion: hard-coded dependencies instead of injection
78454
- - No refactoring suggestions — AI never proposes that a feature should trigger a refactor
78455
- - Context blindness: ignoring ADRs, versioning strategy, or team-level conventions
78456
-
78457
- Ask: Does this follow the patterns in this area of the codebase? Can this be extended without
78458
- modification? Are dependencies injected?
78459
-
78460
- Action: Maintain a living \`ARCHITECTURE.md\` or ADR log. Pass it as context to AI tools before
78461
- generation, not after.
78462
-
78463
- ---
78464
-
78465
- ## Pillar 5 — Security (Standard Priority)
78466
-
78467
- 45% of AI-generated code samples introduced OWASP Top 10 vulnerabilities in Veracode's 2025
78468
- test of 100+ LLMs. CodeRabbit found AI code is 2.74x more likely to introduce XSS, 1.88x more
78469
- likely to mishandle passwords, 1.82x more likely to implement insecure deserialization.
78470
- OX Security calls this "insecure by dumbness" — not malicious, but structurally blind to
78471
- security requirements that were not in the prompt.
78472
-
78473
- Look for:
78474
- - OWASP Top 10: injection (SQL, XSS, command), broken auth, insecure deserialization
78475
- - "Worked on My Machine" syndrome (60–70% of AI code): missing environment awareness,
78476
- hard-coded localhost references, assumed-present secrets
78477
- - Missing auth/ownership checks — AI assumes the happy path; role gates rarely appear unprompted
78478
- - Secrets, tokens, or credentials in source code
78479
- - Deprecated API patterns from the model's training data
78480
- - Excessive I/O (~8x human rate) and concurrency misuse (~2x human rate)
78481
-
78482
- Ask: Are all inputs validated before use? Are auth checks present at every trust boundary?
78483
- Does this code behave differently across environments?
78484
-
78485
- Action: Run SAST tooling (Snyk, Semgrep, SonarQube) on every AI-generated PR as a CI gate.
78486
- Manual review alone cannot keep pace with AI generation velocity.
78487
-
78488
- ---
78489
-
78490
- ## Pillar 6 — Test Quality (Standard Priority)
78491
-
78492
- AI generates tests that look comprehensive but frequently are not. OX Security found "Fake
78493
- Test Coverage" in 40–50% of AI codebases: inflated metrics, low signal. The failure mode is
78494
- precise: AI tests its own assumptions, not the developer's intent. University of Naples (2025)
78495
- confirmed that even code passing all functional benchmarks averaged 1.45–1.77 static issues
78496
- per task.
78497
-
78498
- Look for:
78499
- - Tests that verify AI output is stable, not that it is correct by domain rules
78500
- - Missing edge cases: empty inputs, boundary values, null handling, race conditions,
78501
- business-rule violations
78502
- - Coverage theater: tests that assert no exception was thrown and nothing more
78503
- - No integration or contract tests — AI generates unit tests almost exclusively
78504
- - Tests coupled to implementation: must be updated every time the code changes
78505
-
78506
- Ask: Do these tests verify the domain intent? Would they catch a logic regression in the
78507
- next PR? Are cross-service interactions tested?
78508
-
78509
- Action: Test review is a separate pass from code review. Use mutation testing (Stryker,
78510
- PITest) to validate whether tests catch real defects — coverage percentage is not sufficient.
78511
-
78512
- ---
78513
-
78514
- ## Pillar 7 — Ownership, Observability, Deployment (Standard Priority)
78515
-
78516
- The most consistently missed category. ISACA's 2026 incident review found that the biggest
78517
- AI failures of 2025 were organisational, not technical: weak controls and unclear ownership.
78518
- Bright Security (2026) identified unclear ownership as one of the most dangerous patterns:
78519
- code that works well enough that no one feels responsible for it. IBM's 2025 breach data found
78520
- shadow AI added $670,000 average to breach costs.
78521
-
78522
- Look for:
78523
- - No named human owner — every AI-generated module needs someone who can explain it in a
78524
- postmortem without reading it fresh
78525
- - Missing structured logs, metrics emission, or tracing hooks
78526
- - Swallowed exceptions: retry logic with no alerting; fallback paths invisible to operators
78527
- - No environment-specific configuration, secrets management, or health check endpoints
78528
- - Model versioning chaos: inconsistencies from team members using different AI tool versions
78529
- - Shadow AI: code with no record of which tool or prompt produced it
78530
-
78531
- Ask: Who owns this? Will production failures surface to operators? Does this behave
78532
- differently across environments?
78533
-
78534
- Action: Require every AI-generated module to have a named owner in CODEOWNERS. Add logging
78535
- requirements to the PR template. Establish a team AI governance policy that tracks tools
78536
- and model versions — treat this like any other dependency.
78537
-
78538
- ---
78539
-
78540
- ## Pillar 8 — Dead Code Elimination (Standard Priority)
78541
-
78542
- AI generates code speculatively. It adds helper functions "just in case", creates abstractions
78543
- for paths that never materialise, and leaves behind scaffolding from earlier generation
78544
- attempts. GitClear's 2025 data showed a 75% increase in total code volume, much of it never
78545
- executed. Dead code is not harmless — it misleads future readers, inflates bundle sizes, creates
78546
- false positive search results, and adds surface area for bugs and security vulnerabilities
78547
- in code that serves no purpose.
78548
-
78549
- Look for:
78550
- - Unreachable code: functions, methods, or branches that no call site ever invokes
78551
- - Unused imports: modules imported but never referenced — common in AI-generated files
78552
- - Commented-out code: old implementations left inline instead of being removed; version
78553
- control already preserves history
78554
- - Feature flags that are permanently off: conditional paths that were never enabled or have
78555
- been superseded but not cleaned up
78556
- - Orphaned configuration: environment variables, constants, or config entries with no consumer
78557
- - Stale types and interfaces: type definitions for data shapes that no longer exist in the
78558
- system
78559
- - Unused dependencies: packages listed in \`package.json\` (or equivalent) that no source file
78560
- imports
78561
- - Vestigial error handling: catch blocks or fallback paths for conditions that can no longer
78562
- occur due to upstream changes
78563
- - Test helpers and fixtures for tests that have been deleted
78564
-
78565
- Ask: Is every function called? Is every import used? Is every dependency exercised?
78566
- Would removing this code change any observable behaviour?
78567
-
78568
- Action: Run tree-shaking analysis and dead code detection tools (e.g., \`ts-prune\`,
78569
- \`knip\`, \`depcheck\`, IDE unused-symbol highlighting) as part of CI. Treat dead code
78570
- the same as duplication — it compounds over time and must be actively managed.
78571
-
78572
- ---
78573
-
78574
- ## Pillar 9 — Incomplete Implementations (Standard Priority)
78575
-
78576
- AI tools often leave TODOs, stubs, "throw new Error('not implemented')", or placeholder
78577
- returns when they hit uncertainty. The default assumption MUST be that these are bugs to fix,
78578
- not features — unless the human explicitly requested a stub (e.g., scaffolding a future module).
78579
-
78580
- Look for:
78581
- - \`TODO\`, \`FIXME\`, \`XXX\`, \`HACK\` comments — especially without an assignee or ticket reference
78582
- - Functions that throw "not implemented" / "unimplemented" errors
78583
- - Empty function bodies or bodies that only return null/undefined/empty object as a placeholder
78584
- - Switch/case branches with \`// handle later\` style comments
78585
- - Conditional branches that silently fall through without handling a real case
78586
- - Type definitions with fields marked \`any\` or \`unknown\` "to be refined later"
78587
- - Tests with \`it.skip\`, \`xit\`, \`it.todo\` left in committed code without justification
78588
-
78589
- Ask: Is every code path fully implemented? If a TODO exists, is there a tracked ticket and
78590
- explicit reason it wasn't done now?
78591
-
78592
- Action: Treat any TODO or stub as BLOCK unless the PR description or commit message explicitly
78593
- justifies it (e.g., "scaffolding for follow-up PR #N"). Generated code with unprompted TODOs
78594
- should be completed before merge, not after.
78595
-
78596
- ---
78597
-
78598
- ## Pillar 10 — Hallucinated Content & Magic Strings (Standard Priority)
78599
-
78600
- AI generation frequently invents plausible-looking but incorrect values — API endpoints,
78601
- env var names, library functions, config keys — and scatters magic strings/numbers across
78602
- the codebase instead of consolidating them as named constants. Both fail at runtime or rot
78603
- the codebase over time.
78604
-
78605
- Look for:
78606
- - Fabricated API endpoints, library functions, or package names that don't exist (verify against
78607
- actual SDK docs / \`package.json\`)
78608
- - Magic strings: status codes, role names, event types, feature flag keys appearing as inline
78609
- literals across multiple files
78610
- - Magic numbers: timeouts, limits, retry counts, port numbers without named constants
78611
- - Placeholder content left in production paths: "lorem ipsum", "foo/bar", "example.com",
78612
- "test@test.com"
78613
- - Hardcoded URLs, file paths, or table/collection names that should come from config
78614
- - Duplicated string literals that should be a single enum / const object
78615
- - Configuration keys invented by the AI that don't match the project's actual config schema
78616
-
78617
- Ask: Does every literal that carries domain meaning have a named home? Is every external
78618
- reference (API, package, env var) verified to exist? Where SHOULD this constant live (entity
78619
- enum, config module, shared constants file)?
78620
-
78621
- Action: Consolidate magic literals into the canonical location for the codebase (typically
78622
- enums alongside the relevant entity, or a dedicated constants module). For hallucinated
78623
- references, treat as BLOCK — code that compiles against fictional APIs will fail in production.
78624
-
78625
- ---
78626
-
78627
- ## Output template
78628
-
78629
- Use this format for every review. Do not skip sections.
78630
-
78631
- \`\`\`
78632
- ## AI Code Review — [filename or PR title]
78633
-
78634
- ### Summary
78635
- [2–3 sentences: overall quality signal, highest-risk area, recommended action]
78636
-
78637
- ### BLOCK — must fix before merge
78638
- [List findings. Format: PILLAR | finding | why it matters | suggested fix]
78639
-
78640
- ### FLAG — author must respond
78641
- [List findings. Same format.]
78642
-
78643
- ### Passed
78644
- [Pillars or areas with no significant findings]
78645
-
78646
- ### Recommendation
78647
- [ ] Approve [ ] Approve with flags addressed [ ] Decompose PR first [ ] Reject — rework required
78648
- \`\`\``
78649
- };
78650
- });
77849
+ var init_code_review = () => {};
78651
77850
 
78652
77851
  // ../../services/backend/src/domain/usecase/skills/registry.ts
78653
- var SKILLS_REGISTRY;
78654
77852
  var init_registry3 = __esm(() => {
78655
77853
  init_backlog();
78656
77854
  init_code_review();
78657
- SKILLS_REGISTRY = [backlogSkill, codeReviewSkill];
78658
77855
  });
78659
77856
 
78660
77857
  // ../../services/backend/prompts/sections/glossary.ts
78661
- function formatGlossaryEntry(entry) {
78662
- const skillNote = entry.linkedSkillId ? " (1 skill available)" : "";
78663
- return [`- \`${entry.term}\`${skillNote}`, ` - ${entry.definition}`, ""];
78664
- }
78665
- function buildSkillsSection(cliEnvPrefix) {
78666
- const lines = ["# Skills", ""];
78667
- lines.push(`Run \`${cliEnvPrefix}chatroom skill list --chatroom-id=<id> --role=<role>\` to list all available skills.`);
78668
- lines.push("");
78669
- lines.push("## When to Activate Skills");
78670
- lines.push("");
78671
- lines.push("**Proactively activate skills** when your task matches their purpose:");
78672
- for (const skill of SKILLS_REGISTRY) {
78673
- lines.push(`- **${skill.skillId}**: ${skill.description}`);
78674
- }
78675
- lines.push("");
78676
- lines.push("Don't wait for the user to ask — proactively activate the skill that matches the task.");
78677
- return lines;
78678
- }
78679
- function getGlossarySection(params) {
78680
- const cliEnvPrefix = getCliEnvPrefix(params.convexUrl);
78681
- const lines = ["# Glossary", ""];
78682
- const terms = params.nativeIntegration ? NATIVE_GLOSSARY_TERMS : GLOSSARY_TERMS;
78683
- for (const entry of terms) {
78684
- lines.push(...formatGlossaryEntry(entry));
78685
- }
78686
- if (params.compactSkills) {
78687
- lines.push("# Skills", "");
78688
- lines.push(`Run \`${cliEnvPrefix}chatroom skill list --chatroom-id=<id> --role=<role>\` to list available skills. Activate skills proactively when your task matches their purpose.`);
78689
- } else {
78690
- lines.push(...buildSkillsSection(cliEnvPrefix));
78691
- }
78692
- return createSection("glossary", "knowledge", lines.join(`
78693
- `));
78694
- }
78695
77858
  var GLOSSARY_TERMS, NATIVE_GLOSSARY_TERMS;
78696
77859
  var init_glossary = __esm(() => {
78697
77860
  init_registry3();
@@ -78742,257 +77905,10 @@ var init_glossary = __esm(() => {
78742
77905
  });
78743
77906
 
78744
77907
  // ../../services/backend/prompts/cli/roles/builder.ts
78745
- function getBuilderFlowMermaid(nativeIntegration, codeChangesTarget, questionTarget) {
78746
- const handoffNodes = ` D --> E[Commit work]
78747
- E --> F{Code changes?}
78748
- F -->|yes| G[Hand off to **${codeChangesTarget}**]
78749
- F -->|no| H[Hand off to **${questionTarget}**]`;
78750
- if (nativeIntegration) {
78751
- return `flowchart TD
78752
- A([Start]) --> B[Receive task]
78753
- B --> D[Implement changes]
78754
- ${handoffNodes}`;
78755
- }
78756
- return `flowchart TD
78757
- A([Start]) --> B[Receive chatroom task]
78758
- B --> D[Implement changes]
78759
- ${handoffNodes}`;
78760
- }
78761
- function getBuilderGuidance(params) {
78762
- const {
78763
- questionTarget: questionTargetParam,
78764
- codeChangesTarget: codeChangesTargetParam,
78765
- nativeIntegration
78766
- } = params;
78767
- const questionTarget = questionTargetParam ?? "user";
78768
- const codeChangesTarget = codeChangesTargetParam ?? "planner";
78769
- return `
78770
- ## Builder Operating Model
78771
-
78772
- ${getSessionContinuityLine(nativeIntegration)}
78773
-
78774
- You are responsible for implementing code changes based on requirements.
78775
-
78776
- **Typical Flow:**
78777
-
78778
- \`\`\`mermaid
78779
- ${getBuilderFlowMermaid(nativeIntegration, codeChangesTarget, questionTarget)}
78780
- \`\`\`
78781
-
78782
- **Handoff Rules:**
78783
- - **After code changes** → Hand off to \`${codeChangesTarget}\`
78784
- - **For simple questions** → Can hand off directly to \`${questionTarget}\`
78785
- ⚠️ If \`${questionTarget}\` is the user: the user can ONLY see the handoff-to-user message — progress reports and all other messages are invisible to them. Write the handoff as a complete, self-contained document: include all relevant context, results, and next steps without assuming the user read any prior conversation.
78786
-
78787
- **Implementation Guidelines:**
78788
- - Write clean, maintainable, well-documented code
78789
- - Follow established patterns and best practices from the codebase
78790
- - Handle edge cases and error scenarios
78791
- - Commit work with descriptive, atomic commit messages
78792
-
78793
- **Completion gates (before PR or handoff):**
78794
- - All **(Required)** files done; **verified end-to-end** (user-facing entry point works: CLI command runnable, API reachable, or UI action functional)
78795
- - If blocked → ## Blockers / questions to planner. No PR or \`mark-for-review\` until gates pass — unless the user explicitly requested a draft or incremental PR
78796
- `;
78797
- }
78798
77908
  var init_builder = () => {};
78799
-
78800
- // ../../services/backend/prompts/cli/sections/core-responsibilities.ts
78801
- function getCoreResponsibilitiesSection(config3) {
78802
- const qualityLine = config3.hasBuilder ? "If the user's requirements are not met, hand work back to the builder for rework." : "If the work doesn't meet requirements, revise it yourself before delivering.";
78803
- return `**Core Responsibilities:**
78804
- - **User Communication**: You are the ONLY role that communicates with the user. All responses to the user come through you.
78805
- - **Handoff completeness**: The user can ONLY see the final handoff-to-\`user\` message. Write it as a complete, standalone document — do not reference prior messages or assume the user has context from earlier session text.
78806
- - **Quality Accountability**: You are ultimately accountable for all work. ${qualityLine}`;
78807
- }
78808
-
78809
- // ../../services/backend/prompts/cli/sections/delegation-and-decomposition.ts
78810
- function getDelegationAndDecompositionSection(config3) {
78811
- if (!config3.hasBuilder) {
78812
- return "";
78813
- }
78814
- return `**Delegation & Decomposition:**
78815
-
78816
- Any task that requires code changes must be delegated to the builder — break it into small, focused slices and delegate them one at a time using a **Delegation Brief** (see **Delegation Guidelines** below).`;
78817
- }
78818
-
78819
- // ../../services/backend/prompts/cli/sections/delegation-guidelines.ts
78820
- function buildCmdHelper(cliEnvPrefix, chatroomIdArg, roleArg) {
78821
- return (subcommand) => `\`${cliEnvPrefix}chatroom ${subcommand} --chatroom-id=${chatroomIdArg} --role=${roleArg}\``;
78822
- }
78823
- function getDelegationBriefReference() {
78824
- return "Use the **Handoff to `builder`** template in the task delivery `<handoff-templates>` section — follow that structure in your handoff message.";
78825
- }
78826
- function getSoloImplementationGuidelines(cmd, feedingNote) {
78827
- return `**Implementation Guidelines:**
78828
-
78829
- Break complex features into small, focused slices. For code review guidance, activate the \`code-review\` skill: ${cmd("skill activate code-review")}.
78830
-
78831
- - Implement one slice at a time; each slice ≈ one focused review surface.
78832
- - Review your own work before moving on; re-validate after rework.
78833
- - ${feedingNote}.`;
78834
- }
78835
- function getBuilderDelegationGuidelines(cmd, feedingNote, delegationBriefRef) {
78836
- return `**Delegation Guidelines:**
78837
-
78838
- Break features into small, focused slices, then delegate them to the builder one at a time. For code review guidance, activate the \`code-review\` skill: ${cmd("skill activate code-review")}.
78839
-
78840
- **Delegation rule:** If the task requires **any code changes** (new files, edits, deletions), you **must delegate to the builder** — regardless of how small the change is.
78841
-
78842
- **Decision flow:**
78843
- \`\`\`mermaid
78844
- flowchart TD
78845
- A[Receive task] --> B{Code changes needed?}
78846
- B -->|Yes — any size| D[Write a Delegation Brief]
78847
- D --> E[Hand off ONE slice to builder]
78848
- E --> F[Review output]
78849
- F -->|Not acceptable| G[Hand back with feedback]
78850
- G --> E
78851
- F -->|Acceptable| H{More slices?}
78852
- H -->|Yes| E
78853
- H -->|No| I[Deliver to user]
78854
- B -->|No: question or clarification only| C[Answer directly → deliver to user]
78855
- \`\`\`
78856
-
78857
- **Default: delegate with a Delegation Brief.** ${delegationBriefRef}
78858
-
78859
- **How to slice the work** — think about the phases a human engineer would actually go through to ship the work, then make each phase a slice. Some heuristics:
78860
-
78861
- - **Each slice should name a concrete artifact** ("the X schema", "the Y entity", "the Z endpoint") — not a vague layer ("backend work", "implementation"). Weak builders fail when scope is unbounded.
78862
- - **File-level detail, zero ambiguity.** List every file (full paths) and paste snippets until the builder cannot guess wrong — not vague layers ("backend work", "the component").
78863
- - **You own technical design; the builder executes.** Per-file target code plus shared contracts in the brief — do not leave API shape for the builder to invent.
78864
- - **Spell out what to avoid** — anti-patterns and recurring mistakes you have seen from builders on similar work (scope creep, wrong abstractions, forbidden refactors).
78865
- - **One slice ≈ one focused review surface.** If you can't imagine reviewing it in one sitting, split it.
78866
- - **Order by dependency**, not by team convention. A slice should be runnable/testable when its dependencies are done.
78867
- - **A slice is shippable only when verified end-to-end** — infra/helper files alone are not a complete slice.
78868
- - **Skip phases that don't apply** (e.g., no frontend for a backend-only change, no schema for a pure refactor).
78869
-
78870
- **Code review:** For code-producing work, review before delivering. Activate the review framework with: ${cmd("skill activate code-review")}.
78871
-
78872
- **Backlog items:** When the task originates from a backlog item, activate the backlog skill: ${cmd("skill activate backlog")}.
78873
-
78874
- **If stuck:** After 2 failed rework attempts → replan or hand back to planner as blocked. No partial PR, \`mark-for-review\`, or user delivery.
78875
-
78876
- **Review loop:**
78877
- - Review completed work before moving to the next slice.
78878
- - Send back with specific feedback if requirements aren't met.
78879
- - ${feedingNote}.
78880
-
78881
- **When enhancement is enabled:** See \`<handoff-enhancer>\` in task delivery — one check-in per delegation before builder.`;
78882
- }
78883
- function getDelegationGuidelinesSection(config3, options) {
78884
- const feedingNote = config3.hasBuilder ? "Feed slices to the builder incrementally — one at a time, not all at once" : "When implementing yourself, tackle one layer at a time — avoid large monolithic changes";
78885
- const cliEnvPrefix = options?.cliEnvPrefix ?? "";
78886
- const chatroomIdArg = options?.chatroomId ? `"${options.chatroomId}"` : "<id>";
78887
- const roleArg = options?.role ? `"${options.role}"` : "<role>";
78888
- const cmd = buildCmdHelper(cliEnvPrefix, chatroomIdArg, roleArg);
78889
- if (!config3.hasBuilder) {
78890
- return getSoloImplementationGuidelines(cmd, feedingNote);
78891
- }
78892
- return getBuilderDelegationGuidelines(cmd, feedingNote, getDelegationBriefReference());
78893
- }
78894
-
78895
77909
  // ../../services/backend/prompts/cli/sections/handoff-rules.ts
78896
- function buildHandoffRuleLines(config3) {
78897
- return [
78898
- config3.hasBuilder ? "- **To delegate implementation** → Hand off to `builder` with clear requirements" : "- **To implement** → Work on the chatroom task directly (you are acting as implementer)",
78899
- config3.hasBuilder ? "- **When enhancement is enabled** → See `<handoff-enhancer>` in task delivery before each builder delegation" : null,
78900
- "- **To deliver to user** → Hand off to `user` with a complete, standalone summary\n ⚠️ The user can ONLY see the handoff-to-user message — progress reports and all other messages are invisible to them. Write the handoff as a self-contained document: include all relevant context, results, and next steps without assuming the user read any prior conversation.",
78901
- config3.hasBuilder ? "- **For rework** → Hand off back to `builder` with specific feedback on what needs to change" : "- **For rework** → Revise your implementation directly and re-validate"
78902
- ].filter((line) => line !== null).join(`
78903
- `);
78904
- }
78905
- function getHandoffRulesSection(config3, nativeIntegration) {
78906
- const continuityRule = getHandoffContinuityRule(nativeIntegration);
78907
- const continuityBlock = continuityRule ? `${continuityRule}
78908
-
78909
- ` : "";
78910
- return `**Handoff Rules:**
78911
-
78912
- ${continuityBlock}${buildHandoffRuleLines(config3)}`;
78913
- }
78914
77910
  var init_handoff_rules = () => {};
78915
-
78916
- // ../../services/backend/prompts/cli/sections/when-work-comes-back.ts
78917
- function getWhenWorkComesBackSection(config3) {
78918
- const reworkLine = config3.hasBuilder ? "3. If requirements are NOT met (including partial work) → hand back to `builder` for rework" : "3. If requirements are NOT met (including partial work) → revise and re-validate";
78919
- return `**When you receive work back from team members:**
78920
- 1. Review the completed work against the original user request
78921
- 2. If requirements are met → deliver to \`user\`
78922
- ${reworkLine}
78923
- 4. **No ceremonial handoffs** — never hand back just to acknowledge, thank, or echo receipt. A handback to the sender is only valid when it carries concrete rework feedback (step 3). Handoffs to \`user\` are reserved for the final deliverable from the entry-point role.`;
78924
- }
78925
-
78926
- // ../../services/backend/prompts/cli/sections/team-composition.ts
78927
- function getTeamCompositionSection(teamMembers) {
78928
- const isSoloRole = teamMembers.length === 1 && teamMembers[0]?.toLowerCase() === "solo";
78929
- const nonPlannerMembers = teamMembers.filter((r) => r.toLowerCase() !== "planner");
78930
- if (isSoloRole || nonPlannerMembers.length === 0) {
78931
- return `**Team composition:** Solo team — you handle planning and implementation yourself.`;
78932
- }
78933
- const roleList = nonPlannerMembers.map((r) => `\`${r}\``).join(", ");
78934
- return `**Team composition:** Duo team — you coordinate with ${roleList} for implementation.
78935
-
78936
- **Agent presence:** This prompt does **not** tell you who is online. Other agents may be offline. Delegate code-changing work by handing off when appropriate; do not infer availability from team configuration or prior chat history.`;
78937
- }
78938
-
78939
77911
  // ../../services/backend/prompts/cli/sections/operating-model.ts
78940
- function getTaskIntakeNodes(nativeIntegration) {
78941
- if (nativeIntegration) {
78942
- return ` A([Start]) --> B[Receive user message]
78943
- B --> E[Decompose into phases]`;
78944
- }
78945
- return ` A([Start]) --> B[Receive chatroom task from get-next-task]
78946
- B --> E[Decompose into phases]`;
78947
- }
78948
- function getOperatingModelSection(config3, nativeIntegration) {
78949
- if (config3.hasBuilder) {
78950
- return getPlannerPlusBuilderOperatingModel(nativeIntegration);
78951
- }
78952
- return getPlannerSoloOperatingModel(nativeIntegration);
78953
- }
78954
- function getPlannerPlusBuilderOperatingModel(nativeIntegration) {
78955
- const footer = getOperatingModelLoopFooter(nativeIntegration);
78956
- const delegationNote = nativeIntegration ? getNativePlannerDelegationWaitNote() : "After delegating to the builder, hand off and wait for work to return.";
78957
- return `**Operating model: Planner + Builder**
78958
-
78959
- ${delegationNote}
78960
-
78961
- \`\`\`mermaid
78962
- flowchart TD
78963
- ${getTaskIntakeNodes(nativeIntegration)}
78964
- E --> F[Delegate ONE phase to builder]
78965
- F --> G[Builder completes phase]
78966
- G --> H[Builder hands off to planner]
78967
- H --> I[Review builder output]
78968
- I --> J{phase acceptable?}
78969
- J -->|no| K[Hand back to builder with feedback]
78970
- K --> F
78971
- J -->|yes| L{more phases?}
78972
- L -->|yes| F
78973
- L -->|no| O[Deliver final result to user]
78974
- O --> P[${footer}] --> B
78975
- \`\`\``;
78976
- }
78977
- function getPlannerSoloOperatingModel(nativeIntegration) {
78978
- const continueStep = nativeIntegration ? "Hand off when complete" : "Run `get-next-task` to continue the session (Level A continues after Level B completes)";
78979
- const intakeSteps = nativeIntegration ? `1. Receive user message
78980
- 2. Plan and implement` : `1. Receive chatroom task from get-next-task
78981
- 2. Plan and implement`;
78982
- if (nativeIntegration) {
78983
- return `**Operating model: Planner Solo**
78984
-
78985
- ${intakeSteps}
78986
- 3. Deliver to **user**
78987
- 4. ${continueStep}`;
78988
- }
78989
- return `**Operating model: Planner Solo**
78990
-
78991
- ${intakeSteps}
78992
- 3. Review your own work for quality
78993
- 4. Deliver to **user**
78994
- 5. ${continueStep}`;
78995
- }
78996
77912
  var init_operating_model = () => {};
78997
77913
 
78998
77914
  // ../../services/backend/prompts/cli/sections/index.ts
@@ -79002,126 +77918,17 @@ var init_sections = __esm(() => {
79002
77918
  });
79003
77919
 
79004
77920
  // ../../services/backend/prompts/cli/roles/planner.ts
79005
- function getPlannerGuidance(params) {
79006
- const { convexUrl, teamRoles, chatroomId, role, nativeIntegration } = params;
79007
- const cliEnvPrefix = getCliEnvPrefix(convexUrl);
79008
- const members = teamRoles;
79009
- const hasBuilder = members.some((r) => r.toLowerCase() === "builder");
79010
- const teamConfig = { hasBuilder };
79011
- return `## Planner Operating Model
79012
-
79013
- ${getSessionContinuityLine(nativeIntegration)}
79014
-
79015
- You are the team coordinator and the **single point of contact** for the user.
79016
-
79017
- ${getTeamCompositionSection(members)}
79018
-
79019
- ${getOperatingModelSection(teamConfig, nativeIntegration)}
79020
-
79021
- ${getCoreResponsibilitiesSection(teamConfig)}
79022
-
79023
- ${getDelegationAndDecompositionSection(teamConfig)}
79024
-
79025
- ${getDelegationGuidelinesSection(teamConfig, { cliEnvPrefix, chatroomId, role })}
79026
-
79027
- ${getHandoffRulesSection(teamConfig, nativeIntegration)}
79028
-
79029
- ${getWhenWorkComesBackSection(teamConfig)}`;
79030
- }
79031
77921
  var init_planner = __esm(() => {
79032
77922
  init_env();
79033
77923
  init_sections();
79034
77924
  });
79035
77925
 
79036
77926
  // ../../services/backend/prompts/teams/solo/prompts/solo.ts
79037
- function getSoloGuidance(ctx) {
79038
- const { teamRoles, nativeIntegration } = ctx;
79039
- return `## Solo Operating Model
79040
-
79041
- ${getSessionContinuityLine(nativeIntegration)}
79042
-
79043
- You are an autonomous agent responsible for BOTH planning and implementing chatroom tasks independently.
79044
-
79045
- **Solo Team Context:**
79046
- - You are the ONLY team member — you plan, implement, and deliver
79047
- - You communicate directly with the user (single point of contact)
79048
- - There is no separate builder or planner — you fill all roles
79049
- - You hand off directly to the user when work is complete
79050
-
79051
- ${getTeamCompositionSection(teamRoles)}
79052
-
79053
- ${getPlannerSoloOperatingModel(nativeIntegration)}
79054
-
79055
- ${getCoreResponsibilitiesSection(SOLO_TEAM_CONFIG)}
79056
-
79057
- **Implementation Guidelines:**
79058
- - Write clean, maintainable, well-documented code
79059
- - Follow established patterns and best practices from the codebase
79060
- - Handle edge cases and error scenarios
79061
- - Commit work with descriptive, atomic commit messages
79062
-
79063
- ${getHandoffRulesSection(SOLO_TEAM_CONFIG, nativeIntegration)}
79064
-
79065
- ${getWhenWorkComesBackSection(SOLO_TEAM_CONFIG)}`;
79066
- }
79067
- var SOLO_TEAM_CONFIG;
79068
77927
  var init_solo = __esm(() => {
79069
77928
  init_sections();
79070
- SOLO_TEAM_CONFIG = { hasBuilder: false };
79071
77929
  });
79072
77930
 
79073
77931
  // ../../services/backend/prompts/cli/roles/fromContext.ts
79074
- function toBuilderParams(ctx) {
79075
- return {
79076
- role: ctx.role,
79077
- teamRoles: ctx.teamRoles,
79078
- isEntryPoint: ctx.isEntryPoint,
79079
- convexUrl: ctx.convexUrl,
79080
- nativeIntegration: ctx.nativeIntegration
79081
- };
79082
- }
79083
- function toPlannerParams(ctx) {
79084
- return {
79085
- role: ctx.role,
79086
- teamRoles: ctx.teamRoles,
79087
- isEntryPoint: ctx.isEntryPoint,
79088
- convexUrl: ctx.convexUrl,
79089
- chatroomId: ctx.chatroomId,
79090
- nativeIntegration: ctx.nativeIntegration
79091
- };
79092
- }
79093
- function getBaseBuilderGuidanceFromContext(ctx) {
79094
- return getBuilderGuidance(toBuilderParams(ctx));
79095
- }
79096
- function toSoloParams(ctx) {
79097
- return {
79098
- role: ctx.role,
79099
- teamRoles: ctx.teamRoles,
79100
- isEntryPoint: ctx.isEntryPoint,
79101
- convexUrl: ctx.convexUrl,
79102
- chatroomId: ctx.chatroomId,
79103
- nativeIntegration: ctx.nativeIntegration
79104
- };
79105
- }
79106
- function getSoloGuidanceFromContext(ctx) {
79107
- return getSoloGuidance(toSoloParams(ctx));
79108
- }
79109
- function getBasePlannerGuidanceFromContext(ctx) {
79110
- return getPlannerGuidance(toPlannerParams(ctx));
79111
- }
79112
- function getBaseRoleGuidanceFromContext(ctx) {
79113
- const normalizedRole = ctx.role.toLowerCase();
79114
- if (normalizedRole === "planner") {
79115
- return getBasePlannerGuidanceFromContext(ctx);
79116
- }
79117
- if (normalizedRole === "builder") {
79118
- return getBaseBuilderGuidanceFromContext(ctx);
79119
- }
79120
- if (normalizedRole === "solo") {
79121
- return getSoloGuidanceFromContext(ctx);
79122
- }
79123
- return "";
79124
- }
79125
77932
  var init_fromContext = __esm(() => {
79126
77933
  init_builder();
79127
77934
  init_planner();
@@ -79129,229 +77936,32 @@ var init_fromContext = __esm(() => {
79129
77936
  });
79130
77937
 
79131
77938
  // ../../services/backend/prompts/teams/duo/prompts/builder.ts
79132
- function getBuilderGuidance2(ctx) {
79133
- return `
79134
- **Duo Team Context:**
79135
- - You work with a planner who coordinates work and communicates with the user
79136
- - You do NOT communicate directly with the user — hand off to the planner instead
79137
- - Focus on implementation; the planner handles user communication and delivery
79138
- - After completing work, hand off back to planner
79139
- - **NEVER hand off directly to \`user\`** — always go through the planner
79140
-
79141
- ${getBuilderGuidance({ ...ctx, questionTarget: "planner", codeChangesTarget: "planner" })}
79142
- `;
79143
- }
79144
77939
  var init_builder2 = __esm(() => {
79145
77940
  init_builder();
79146
77941
  });
79147
77942
 
79148
77943
  // ../../services/backend/prompts/cli/roles/planner-guidance-context.ts
79149
- function getPlannerGuidanceContext(ctx) {
79150
- const { convexUrl, teamRoles, chatroomId, role } = ctx;
79151
- const cliEnvPrefix = getCliEnvPrefix(convexUrl);
79152
- const members = teamRoles;
79153
- return {
79154
- ...ctx,
79155
- cliEnvPrefix,
79156
- members,
79157
- chatroomId,
79158
- role
79159
- };
79160
- }
79161
77944
  var init_planner_guidance_context = __esm(() => {
79162
77945
  init_env();
79163
77946
  });
79164
77947
 
79165
77948
  // ../../services/backend/prompts/teams/duo/prompts/planner.ts
79166
- function getPlannerGuidance2(ctx) {
79167
- const { nativeIntegration, members, cliEnvPrefix, chatroomId, role } = getPlannerGuidanceContext(ctx);
79168
- const operatingModelGuidance = getPlannerPlusBuilderOperatingModel(nativeIntegration);
79169
- return `## Planner Operating Model
79170
-
79171
- ${getSessionContinuityLine(nativeIntegration)}
79172
-
79173
- You are the team coordinator and the **single point of contact** for the user.
79174
-
79175
- **Duo Team Context:**
79176
- - You are the entry point — you communicate directly with the user
79177
- - You coordinate with the builder for implementation tasks
79178
- - You are ultimately accountable for all work quality
79179
- - After reviewing builder output, deliver results to the user
79180
- - **Only you can hand off to \`user\`**
79181
-
79182
- ${getTeamCompositionSection(members)}
79183
-
79184
- ${operatingModelGuidance}
79185
-
79186
- ${getCoreResponsibilitiesSection(DUO_TEAM_CONFIG)}
79187
-
79188
- ${getDelegationAndDecompositionSection(DUO_TEAM_CONFIG)}
79189
-
79190
- ${getDelegationGuidelinesSection(DUO_TEAM_CONFIG, {
79191
- cliEnvPrefix,
79192
- chatroomId,
79193
- role
79194
- })}
79195
-
79196
- ${getHandoffRulesSection(DUO_TEAM_CONFIG, nativeIntegration)}
79197
-
79198
- ${getWhenWorkComesBackSection(DUO_TEAM_CONFIG)}`;
79199
- }
79200
- var DUO_TEAM_CONFIG;
79201
77949
  var init_planner2 = __esm(() => {
79202
77950
  init_planner_guidance_context();
79203
77951
  init_sections();
79204
- DUO_TEAM_CONFIG = { hasBuilder: true };
79205
77952
  });
79206
77953
 
79207
77954
  // ../../services/backend/prompts/teams/duo/prompts/fromContext.ts
79208
- function toDuoBuilderParams(ctx) {
79209
- return {
79210
- role: ctx.role,
79211
- teamRoles: ctx.teamRoles,
79212
- isEntryPoint: ctx.isEntryPoint,
79213
- convexUrl: ctx.convexUrl,
79214
- nativeIntegration: ctx.nativeIntegration
79215
- };
79216
- }
79217
- function toDuoPlannerParams(ctx) {
79218
- return {
79219
- role: ctx.role,
79220
- teamRoles: ctx.teamRoles,
79221
- isEntryPoint: ctx.isEntryPoint,
79222
- convexUrl: ctx.convexUrl,
79223
- chatroomId: ctx.chatroomId,
79224
- nativeIntegration: ctx.nativeIntegration
79225
- };
79226
- }
79227
- function getDuoBuilderGuidanceFromContext(ctx) {
79228
- return getBuilderGuidance2(toDuoBuilderParams(ctx));
79229
- }
79230
- function getDuoPlannerGuidanceFromContext(ctx) {
79231
- return getPlannerGuidance2(toDuoPlannerParams(ctx));
79232
- }
79233
- function getDuoRoleGuidanceFromContext(ctx) {
79234
- const normalizedRole = ctx.role.toLowerCase();
79235
- if (normalizedRole === "planner") {
79236
- return getDuoPlannerGuidanceFromContext(ctx);
79237
- }
79238
- if (normalizedRole === "builder") {
79239
- return getDuoBuilderGuidanceFromContext(ctx);
79240
- }
79241
- return null;
79242
- }
79243
77955
  var init_fromContext2 = __esm(() => {
79244
77956
  init_builder2();
79245
77957
  init_planner2();
79246
77958
  });
79247
77959
 
79248
77960
  // ../../services/backend/prompts/teams/solo/prompts/fromContext.ts
79249
- function toSoloParams2(ctx) {
79250
- return {
79251
- role: ctx.role,
79252
- teamRoles: ctx.teamRoles,
79253
- isEntryPoint: ctx.isEntryPoint,
79254
- convexUrl: ctx.convexUrl,
79255
- chatroomId: ctx.chatroomId,
79256
- nativeIntegration: ctx.nativeIntegration
79257
- };
79258
- }
79259
- function getSoloGuidanceFromContext2(ctx) {
79260
- return getSoloGuidance(toSoloParams2(ctx));
79261
- }
79262
- function getSoloRoleGuidanceFromContext(ctx) {
79263
- const normalizedRole = ctx.role.toLowerCase();
79264
- if (normalizedRole === "solo") {
79265
- return getSoloGuidanceFromContext2(ctx);
79266
- }
79267
- return null;
79268
- }
79269
77961
  var init_fromContext3 = __esm(() => {
79270
77962
  init_solo();
79271
77963
  });
79272
-
79273
- // ../../services/backend/src/domain/entities/team.ts
79274
- function toTeam(chatroom) {
79275
- if (!chatroom.teamId || !chatroom.teamRoles || chatroom.teamRoles.length === 0) {
79276
- return null;
79277
- }
79278
- const entryPoint = chatroom.teamEntryPoint ?? chatroom.teamRoles[0];
79279
- if (!entryPoint)
79280
- return null;
79281
- return {
79282
- id: chatroom.teamId,
79283
- name: chatroom.teamName ?? chatroom.teamId,
79284
- roles: chatroom.teamRoles,
79285
- entryPoint
79286
- };
79287
- }
79288
- function getTeamEntryPoint(team) {
79289
- return team.teamEntryPoint ?? team.teamRoles?.[0] ?? null;
79290
- }
79291
-
79292
77964
  // ../../services/backend/prompts/selector-context.ts
79293
- function detectTeamTypeByName(teamName) {
79294
- const normalizedName = (teamName || "").toLowerCase();
79295
- if (normalizedName.includes("solo"))
79296
- return "solo";
79297
- if (normalizedName.includes("duo"))
79298
- return "duo";
79299
- return null;
79300
- }
79301
- function isSoloTeamByRoles(teamRoles) {
79302
- return teamRoles.some((r) => r.toLowerCase() === "solo") && teamRoles.length === 1;
79303
- }
79304
- function isDuoTeamByRoles(teamRoles) {
79305
- const hasPlanner = teamRoles.some((r) => r.toLowerCase() === "planner");
79306
- const hasBuilder = teamRoles.some((r) => r.toLowerCase() === "builder");
79307
- return hasPlanner && hasBuilder && teamRoles.length === 2;
79308
- }
79309
- function detectTeamType(teamRoles, teamName) {
79310
- const byName = detectTeamTypeByName(teamName);
79311
- if (byName)
79312
- return byName;
79313
- if (isSoloTeamByRoles(teamRoles))
79314
- return "solo";
79315
- if (isDuoTeamByRoles(teamRoles))
79316
- return "duo";
79317
- return "unknown";
79318
- }
79319
- function buildSelectorContext(params) {
79320
- const entryPoint = getTeamEntryPoint({ teamEntryPoint: params.teamEntryPoint, teamRoles: params.teamRoles }) ?? "builder";
79321
- const teamConfig = toTeam({
79322
- teamId: params.teamId,
79323
- teamName: params.teamName,
79324
- teamRoles: params.teamRoles,
79325
- teamEntryPoint: params.teamEntryPoint
79326
- }) ?? undefined;
79327
- return {
79328
- role: params.role,
79329
- team: detectTeamType(params.teamRoles, params.teamName),
79330
- teamConfig,
79331
- workflow: params.workflow,
79332
- teamRoles: params.teamRoles,
79333
- isEntryPoint: params.role.toLowerCase() === entryPoint.toLowerCase(),
79334
- convexUrl: params.convexUrl,
79335
- chatroomId: params.chatroomId,
79336
- agentType: params.agentType ?? "unset",
79337
- nativeIntegration: params.nativeIntegration
79338
- };
79339
- }
79340
- function getRoleGuidanceFromContext(ctx) {
79341
- try {
79342
- if (ctx.team === "solo") {
79343
- const result = getSoloRoleGuidanceFromContext(ctx);
79344
- if (result !== null)
79345
- return result;
79346
- }
79347
- if (ctx.team === "duo") {
79348
- const result = getDuoRoleGuidanceFromContext(ctx);
79349
- if (result !== null)
79350
- return result;
79351
- }
79352
- } catch {}
79353
- return getBaseRoleGuidanceFromContext(ctx);
79354
- }
79355
77965
  var init_selector_context = __esm(() => {
79356
77966
  init_fromContext();
79357
77967
  init_fromContext2();
@@ -79359,151 +77969,19 @@ var init_selector_context = __esm(() => {
79359
77969
  });
79360
77970
 
79361
77971
  // ../../services/backend/prompts/sections/role-guidance.ts
79362
- function getRoleGuidanceSection(ctx) {
79363
- const content = getRoleGuidanceFromContext(ctx);
79364
- return createSection("role-guidance", "knowledge", content);
79365
- }
79366
77972
  var init_role_guidance = __esm(() => {
79367
77973
  init_selector_context();
79368
77974
  });
79369
77975
 
79370
77976
  // ../../services/backend/prompts/templates.ts
79371
- function getRoleTemplate(role) {
79372
- const normalizedRole = role.toLowerCase();
79373
- const template = ROLE_TEMPLATES[normalizedRole];
79374
- if (template) {
79375
- return template;
79376
- }
79377
- return {
79378
- role,
79379
- title: role.charAt(0).toUpperCase() + role.slice(1),
79380
- description: `You are participating as the ${role} in this collaborative workflow.`,
79381
- responsibilities: [
79382
- "Complete tasks assigned to your role",
79383
- "Communicate clearly with other participants",
79384
- "Hand off to the next appropriate role when done"
79385
- ],
79386
- defaultHandoffTarget: "user"
79387
- };
79388
- }
79389
- var ROLE_TEMPLATES;
79390
- var init_templates = __esm(() => {
79391
- ROLE_TEMPLATES = {
79392
- builder: {
79393
- role: "builder",
79394
- title: "Builder",
79395
- description: "You are the implementer responsible for writing code and building solutions.",
79396
- responsibilities: [
79397
- "Implement solutions based on requirements",
79398
- "Write clean, maintainable, well-documented code",
79399
- "Follow established patterns and best practices",
79400
- "Handle edge cases and error scenarios",
79401
- "Provide clear summaries of what was built"
79402
- ],
79403
- defaultHandoffTarget: "planner"
79404
- },
79405
- planner: {
79406
- role: "planner",
79407
- title: "Planner",
79408
- description: "You are the team coordinator responsible for user communication, task decomposition, and team management.",
79409
- responsibilities: [
79410
- "Communicate with the user as the single point of contact",
79411
- "Decompose complex tasks into actionable work items",
79412
- "Delegate work to available team members",
79413
- "Review completed work against user requirements",
79414
- "Manage the backlog and prioritize tasks",
79415
- "Hand back work for rework if requirements are not met"
79416
- ],
79417
- defaultHandoffTarget: "builder"
79418
- },
79419
- architect: {
79420
- role: "architect",
79421
- title: "Architect",
79422
- description: "You are the system designer responsible for planning and high-level architecture.",
79423
- responsibilities: [
79424
- "Analyze requirements and break down complex tasks",
79425
- "Design system architecture and component structure",
79426
- "Make technology and pattern decisions",
79427
- "Create clear specifications for the builder",
79428
- "Consider scalability, maintainability, and best practices"
79429
- ],
79430
- defaultHandoffTarget: "builder"
79431
- },
79432
- tester: {
79433
- role: "tester",
79434
- title: "Tester",
79435
- description: "You are the QA specialist responsible for testing and validation.",
79436
- responsibilities: [
79437
- "Write and execute test cases",
79438
- "Verify functionality works as expected",
79439
- "Test edge cases and error handling",
79440
- "Report bugs and issues clearly",
79441
- "Confirm quality standards are met"
79442
- ],
79443
- defaultHandoffTarget: "user"
79444
- },
79445
- solo: {
79446
- role: "solo",
79447
- title: "Solo",
79448
- description: "You are the autonomous agent responsible for both planning and executing tasks independently.",
79449
- responsibilities: [
79450
- "Communicate directly with the user as the single point of contact",
79451
- "Decompose complex tasks into actionable work items",
79452
- "Implement solutions: write clean, maintainable code",
79453
- "Follow established patterns and best practices",
79454
- "Handle edge cases and error scenarios",
79455
- "Review and validate your own work for quality",
79456
- "Deliver completed results to the user"
79457
- ],
79458
- defaultHandoffTarget: "user"
79459
- }
79460
- };
79461
- });
77977
+ var init_templates = () => {};
79462
77978
 
79463
77979
  // ../../services/backend/prompts/sections/role-identity.ts
79464
- function getTeamHeaderSection(teamName) {
79465
- return createSection("team-header", "knowledge", `# ${teamName}`);
79466
- }
79467
- function getRoleTitleSection(ctx) {
79468
- const template = getRoleTemplate(ctx.role);
79469
- return createSection("role-title", "knowledge", `## Your Role: ${template.title.toUpperCase()}`);
79470
- }
79471
- function getRoleDescriptionSection(ctx) {
79472
- const template = getRoleTemplate(ctx.role);
79473
- return createSection("role-description", "knowledge", template.description);
79474
- }
79475
77980
  var init_role_identity = __esm(() => {
79476
77981
  init_templates();
79477
77982
  });
79478
77983
 
79479
77984
  // ../../services/backend/prompts/native/system-prompt.ts
79480
- function composeNativeSystemPrompt(input) {
79481
- const { chatroomId, role, teamId, teamName, teamRoles, teamEntryPoint, convexUrl } = input;
79482
- const selectorCtx = buildSelectorContext({
79483
- role,
79484
- teamRoles,
79485
- teamId,
79486
- teamName,
79487
- teamEntryPoint,
79488
- convexUrl,
79489
- chatroomId,
79490
- agentType: input.agentType,
79491
- nativeIntegration: true
79492
- });
79493
- const sections = [
79494
- getRoleTitleSection(selectorCtx),
79495
- getGlossarySection({
79496
- convexUrl,
79497
- chatroomId,
79498
- role,
79499
- nativeIntegration: true,
79500
- compactSkills: true
79501
- }),
79502
- getRoleGuidanceSection(selectorCtx),
79503
- getNativeCommandsReferenceSection({ chatroomId, role, convexUrl })
79504
- ];
79505
- return composeSections(sections);
79506
- }
79507
77985
  var init_system_prompt = __esm(() => {
79508
77986
  init_commands_reference();
79509
77987
  init_glossary();
@@ -79513,46 +77991,11 @@ var init_system_prompt = __esm(() => {
79513
77991
  });
79514
77992
 
79515
77993
  // ../../services/backend/prompts/native/task-started-content.ts
79516
- function getNativeTaskStartedPrompt(ctx) {
79517
- const contextNewCmd = contextNewCommand({
79518
- chatroomId: ctx.chatroomId,
79519
- role: ctx.role,
79520
- cliEnvPrefix: ctx.cliEnvPrefix,
79521
- triggerMessageId: ctx.triggerMessageId
79522
- });
79523
- return `### Start working
79524
-
79525
- Entry-point roles receive user messages directly. ${getNativeTokenActivityInProgressNote()}
79526
-
79527
- ${getContextRuleBlock(contextNewCmd, contextNewHint({ cliEnvPrefix: ctx.cliEnvPrefix }))}`;
79528
- }
79529
- function getNativeTaskStartedPromptForHandoffRecipient() {
79530
- return `### Start Working
79531
-
79532
- The task body contains your work description. Begin immediately.`;
79533
- }
79534
77994
  var init_task_started_content = __esm(() => {
79535
77995
  init_new();
79536
77996
  });
79537
77997
 
79538
77998
  // ../../services/backend/prompts/sections/classification-guide.ts
79539
- function getTaskIntakeContent(ctx) {
79540
- const cliEnvPrefix = getCliEnvPrefix(ctx.convexUrl);
79541
- const chatroomId = ctx.chatroomId ?? "";
79542
- if (ctx.isEntryPoint) {
79543
- return ctx.nativeIntegration ? getNativeTaskStartedPrompt({ chatroomId, role: ctx.role, cliEnvPrefix }) : getTaskStartedPrompt2({ chatroomId, role: ctx.role, cliEnvPrefix });
79544
- }
79545
- return ctx.nativeIntegration ? getNativeTaskStartedPromptForHandoffRecipient() : getTaskStartedPromptForHandoffRecipient2({
79546
- chatroomId,
79547
- role: ctx.role,
79548
- cliEnvPrefix
79549
- });
79550
- }
79551
- function getClassificationGuideSection(ctx) {
79552
- const content = getTaskIntakeContent(ctx);
79553
- const sectionId = ctx.isEntryPoint ? "task-intake-guide" : "handoff-recipient-guide";
79554
- return createSection(sectionId, "knowledge", content);
79555
- }
79556
77999
  var init_classification_guide = __esm(() => {
79557
78000
  init_cli();
79558
78001
  init_task_started_content();
@@ -79560,118 +78003,23 @@ var init_classification_guide = __esm(() => {
79560
78003
  });
79561
78004
 
79562
78005
  // ../../services/backend/prompts/sections/current-classification.ts
79563
- function getCurrentClassificationSection(classification) {
79564
- const info = {
79565
- question: {
79566
- label: "QUESTION",
79567
- description: "User is asking a question. Can respond directly after answering."
79568
- },
79569
- new_feature: {
79570
- label: "NEW FEATURE",
79571
- description: "New functionality request."
79572
- },
79573
- follow_up: {
79574
- label: "FOLLOW-UP",
79575
- description: "Follow-up to previous task. Same rules as the original apply."
79576
- }
79577
- };
79578
- const { label, description } = info[classification];
79579
- const content = `### Current Task: ${label}
79580
- ${description}`;
79581
- return createSection("current-classification", "guidance", content);
79582
- }
79583
78006
  var init_current_classification = () => {};
79584
78007
 
79585
78008
  // ../../services/backend/prompts/sections/getting-started.ts
79586
- function getGettingStartedSection(ctx) {
79587
- const content = getContextGainingGuidance({
79588
- chatroomId: ctx.chatroomId ?? "",
79589
- role: ctx.role,
79590
- convexUrl: ctx.convexUrl,
79591
- agentType: ctx.agentType
79592
- });
79593
- return createSection("getting-started", "knowledge", content);
79594
- }
79595
78009
  var init_getting_started = __esm(() => {
79596
78010
  init_getting_started_content();
79597
78011
  });
79598
78012
 
79599
78013
  // ../../services/backend/prompts/sections/handoff-options.ts
79600
- function getHandoffOptionsSection(params) {
79601
- const roles = params.availableHandoffRoles.join(", ");
79602
- const content = `### Handoff Options
79603
- Available targets: ${roles}`;
79604
- return createSection("handoff-options", "guidance", content);
79605
- }
79606
78014
  var init_handoff_options = () => {};
79607
78015
 
79608
78016
  // ../../services/backend/prompts/sections/next-step.ts
79609
- function getNextStepSection(params) {
79610
- const cliEnvPrefix = getCliEnvPrefix(params.convexUrl);
79611
- const waitCmd = getNextTaskCommand({
79612
- chatroomId: params.chatroomId,
79613
- role: params.role,
79614
- cliEnvPrefix
79615
- });
79616
- const content = `### Next
79617
-
79618
- Run:
79619
-
79620
- \`\`\`bash
79621
- ${waitCmd}
79622
- \`\`\``;
79623
- return createSection("next-step", "guidance", content);
79624
- }
79625
78017
  var init_next_step = __esm(() => {
79626
78018
  init_command();
79627
78019
  init_utils3();
79628
78020
  });
79629
78021
 
79630
78022
  // ../../services/backend/prompts/sections/session-vs-chatroom-task.ts
79631
- function getTwoLevelsTableSection() {
79632
- return `## Two-Level Model: Session vs Chatroom Task
79633
-
79634
- | Level | Name | Scope | Ends when |
79635
- |-------|------|-------|-----------|
79636
- | **A** | **Session** (harness turn) | The entire agent invocation — from startup to shutdown | You deliberately shut down or the harness exits |
79637
- | **B** | **Chatroom task** | One discrete unit of work delivered by \`get-next-task\` | You run \`handoff\` to pass work to the next role |
79638
-
79639
- **Completing Level B does NOT end Level A.**
79640
- After every \`handoff\`, you must run \`get-next-task\` again to stay in the session and receive the next chatroom task.`;
79641
- }
79642
- function getSessionLifecycleSection() {
79643
- return `### Session Lifecycle
79644
-
79645
- A session starts when your harness launches you and ends only when the harness shuts down (or you explicitly stop).
79646
- Within a session, you process many chatroom tasks sequentially:
79647
-
79648
- \`get-next-task\` → do work → \`handoff\` → \`get-next-task\` → do work → \`handoff\` → …
79649
-
79650
- Never exit or stop after a handoff — that closes the session (Level A) before the user is done with you.`;
79651
- }
79652
- function getSessionAntiPatternsSection() {
79653
- return `### Common Mistakes
79654
-
79655
- ❌ **Wrong:** Run \`handoff\`, then stop or wait for the user to re-invoke you.
79656
- ✅ **Right:** Run \`handoff\`, then immediately run \`get-next-task\` in the foreground.
79657
-
79658
- ❌ **Wrong:** Think "I finished the task, I'm done."
79659
- ✅ **Right:** Think "I finished this chatroom task (Level B). The session (Level A) continues — run \`get-next-task\`."
79660
-
79661
- ❌ **Wrong:** Run \`get-next-task\` in the background or skip it.
79662
- ✅ **Right:** \`get-next-task\` must run in the **foreground** so the harness can deliver the next chatroom task.`;
79663
- }
79664
- function getSessionVsChatroomTaskSection() {
79665
- const content = [
79666
- getTwoLevelsTableSection(),
79667
- "",
79668
- getSessionLifecycleSection(),
79669
- "",
79670
- getSessionAntiPatternsSection()
79671
- ].join(`
79672
- `);
79673
- return createSection("session-vs-chatroom-task", "guidance", content);
79674
- }
79675
78023
  var init_session_vs_chatroom_task = () => {};
79676
78024
 
79677
78025
  // ../../services/backend/src/domain/entities/harness/claude-sdk.config.ts
@@ -79876,571 +78224,9 @@ var init_types = __esm(() => {
79876
78224
  "pi-sdk": piSdkCapabilities
79877
78225
  };
79878
78226
  });
79879
-
79880
- // ../../services/backend/prompts/review-guidelines/review.ts
79881
- function getReviewGuidelines() {
79882
- return [REVIEW_PRINCIPLES, REVIEW_PROCESS, GUIDELINE_FILE_LOCATIONS, REJECTION_GUIDANCE].join(`
79883
-
79884
- `);
79885
- }
79886
- var REVIEW_PRINCIPLES = `
79887
- ## Review Principles
79888
-
79889
- When reviewing completed work, you serve as the quality guardian between implementation and delivery.
79890
-
79891
- ### Primary Goal: Maintainability & Extensibility
79892
-
79893
- **The ultimate purpose of code review is to ensure the changes make it possible to continue building on the application.**
79894
-
79895
- Every piece of code must be:
79896
- - Easy to understand and modify later
79897
- - Following patterns that scale
79898
- - Not creating technical debt that slows future development
79899
-
79900
- If code is hard to extend, hard to understand, or creates mess - it should be rejected or refactored, regardless of whether it "works."
79901
-
79902
- ### Core Values
79903
-
79904
- 1. **User Goal Alignment**
79905
- The implementation must accomplish what the user originally requested.
79906
- Compare the work against the ORIGINAL user request, not just the handoff summary.
79907
-
79908
- 2. **Code Quality Over Speed**
79909
- Maintain code quality: Use \`handoff\` to reject messy code that creates technical debt and slows future development.
79910
-
79911
- 3. **Codebase Consistency**
79912
- New code should follow existing patterns and conventions.
79913
- Check guideline files for project-specific rules.
79914
- Inconsistent code creates confusion and bugs.
79915
-
79916
- 4. **Verification Over Trust**
79917
- Check the actual changes, not just the summary.
79918
- If something seems off, investigate. Trust but verify.
79919
-
79920
- 5. **Be Direct and Specific**
79921
- Be specific and clear in your \`handoff\` message: Vague feedback leads to confusion and rework. If something is wrong, say exactly what and why.
79922
- If a refactor is needed, propose the exact approach.
79923
- `, REVIEW_PROCESS = `
79924
- ## Review Process
79925
-
79926
- ### Phase 1: Context Review
79927
-
79928
- Before looking at code, understand what was requested:
79929
-
79930
- 1. Read the **original user request** in the context window
79931
- 2. Note all requirements, constraints, and acceptance criteria
79932
- 3. If a feature has metadata (title, description, tech-specs), review each point
79933
- 4. If there are attached tasks, read their content
79934
-
79935
- ### Phase 2: Change Inspection
79936
-
79937
- Run these commands to inspect the implementation:
79938
-
79939
- \`\`\`bash
79940
- # Check for linting issues
79941
- pnpm lint:fix
79942
-
79943
- # View uncommitted changes
79944
- git status
79945
- git diff
79946
-
79947
- # View recent commits
79948
- git log --oneline -5
79949
- git show HEAD
79950
- \`\`\`
79951
-
79952
- ### Phase 3: Code Review Checklist
79953
-
79954
- **Functional Requirements:**
79955
- - [ ] All requirements from original request are addressed
79956
- - [ ] Edge cases are handled
79957
- - [ ] Error handling is appropriate
79958
-
79959
- **Code Quality:**
79960
- - [ ] No \`any\` types - proper TypeScript typing required
79961
- - [ ] No type assertions (\`as\`) hiding real type issues
79962
- - [ ] React hooks used correctly (deps arrays, memoization)
79963
- - [ ] No inline workarounds or hacks
79964
-
79965
- **Codebase Consistency:**
79966
- - [ ] Follows existing patterns in the codebase
79967
- - [ ] Uses existing components/utilities where applicable
79968
- - [ ] Styling follows design system (semantic tokens, not hardcoded colors)
79969
-
79970
- **Guidelines Compliance:**
79971
- - [ ] Check relevant guideline files were followed (see list below)
79972
-
79973
- ### Phase 4: Decision
79974
-
79975
- **Your feedback must be SPECIFIC and ACTIONABLE. Include clear guidance in your \`handoff\` message to help the builder make the right changes.**
79976
-
79977
- **If changes are needed:**
79978
- - State EXACTLY what is wrong (file, line, code snippet)
79979
- - Explain WHY it's a problem (not just that it's wrong)
79980
- - Provide the EXACT fix or approach you want to see
79981
- - If multiple issues, number them clearly
79982
-
79983
- Example of BAD feedback:
79984
- > "The code could be cleaner"
79985
-
79986
- Example of GOOD feedback:
79987
- > "In \`TaskQueue.tsx\` line 45, you're using \`any\` type for the task parameter.
79988
- > This hides type errors. Change to: \`task: Task\` using the imported Task type."
79989
-
79990
- **If the code is a mess - REJECT IT:**
79991
- - Use \`handoff\` to reject messy code that "works"
79992
- - Propose the refactor approach explicitly in your \`handoff\` message
79993
- - Large refactors are acceptable if they improve maintainability
79994
- - The goal is code that can be built upon, not just code that runs
79995
-
79996
- **If approved:**
79997
- - Confirm ALL requirements from original request are met
79998
- - Briefly summarize what was verified
79999
- - Hand off to user
80000
- `, GUIDELINE_FILE_LOCATIONS = `
80001
- ## Guideline Files to Check
80002
-
80003
- Different AI tools use different guideline file locations. Check any that exist:
80004
-
80005
- ### Cursor IDE
80006
- - \`.cursor/rules/*.md\` - Cursor rules files
80007
- - \`.cursorrules\` - Root cursor rules
80008
-
80009
- ### GitHub Copilot
80010
- - \`.github/copilot-instructions.md\` - Copilot instructions
80011
- - \`.github/copilot/*.md\` - Additional Copilot files
80012
-
80013
- ### Claude / Anthropic
80014
- - \`CLAUDE.md\` - Claude-specific instructions
80015
- - \`.claude/*.md\` - Claude rules directory
80016
-
80017
- ### OpenAI / Codex
80018
- - \`.openai/guidelines.md\` - OpenAI guidelines
80019
- - \`CODEX.md\` - Codex instructions
80020
-
80021
- ### Generic Agent Files
80022
- - \`AGENTS.md\` - Generic agent guidelines
80023
- - \`.ai/*.md\` - AI-related instructions
80024
- - \`DEVELOPMENT.md\` - Development guidelines
80025
- - \`CONTRIBUTING.md\` - Contribution guidelines
80026
-
80027
- ### Project-Specific
80028
- - \`docs/design/*.md\` - Design guidelines
80029
- - \`docs/style-guide.md\` - Style guides
80030
- - \`guides/*.md\` - Project guides
80031
-
80032
- **Important:** Adapt to what exists in THIS codebase. Not all projects have all files.
80033
- `, REJECTION_GUIDANCE = `
80034
- ## When to Reject or Request Refactors
80035
-
80036
- **Use \`handoff\` to maintain code quality:** The goal is a maintainable codebase.
80037
-
80038
- ### Reject When:
80039
-
80040
- 1. **Requirements Not Met**
80041
- - The original user request is not fully addressed
80042
- - Key features are missing or only partially implemented
80043
-
80044
- 2. **Significant Technical Debt**
80045
- - Hacks or workarounds that will cause problems later
80046
- - Code that is hard to understand or modify
80047
- - Patterns that don't scale or won't work with future features
80048
-
80049
- 3. **Type Safety Violations**
80050
- - Widespread use of \`any\` or type assertions
80051
- - Missing proper error types or return types
80052
- - Type errors being suppressed rather than fixed
80053
-
80054
- 4. **Architectural Issues**
80055
- - Code in wrong location (logic in UI, UI in logic)
80056
- - Duplication of existing functionality
80057
- - Tight coupling that prevents testing/reuse
80058
-
80059
- ### Propose Refactors When:
80060
-
80061
- 1. **The fix is bigger than the feature**
80062
- If cleaning up the code would take more effort than the original change,
80063
- but the mess will compound over time - propose the refactor.
80064
-
80065
- 2. **Patterns are inconsistent**
80066
- If new code follows different patterns than existing code,
80067
- propose alignment to the established pattern.
80068
-
80069
- 3. **Abstractions are wrong**
80070
- If the code is solving the problem at the wrong level of abstraction,
80071
- propose the right approach even if it means starting over.
80072
-
80073
- ### How to Propose Refactors:
80074
-
80075
- 1. Explain the problem clearly
80076
- 2. Describe the desired end state
80077
- 3. Suggest whether to:
80078
- - Fix now before merging
80079
- - Create a follow-up task for later
80080
- - Block on the refactor
80081
-
80082
- **Remember:** Approving bad code costs more than rejecting it.
80083
- `;
80084
-
80085
78227
  // ../../services/backend/prompts/review-guidelines/index.ts
80086
78228
  var init_review_guidelines = () => {};
80087
-
80088
- // ../../services/backend/prompts/policies/security.ts
80089
- function getSecurityPolicy() {
80090
- return SECURITY_POLICY;
80091
- }
80092
- var SECURITY_POLICY = `
80093
- ## Security Review Policy
80094
-
80095
- These are general security principles. Adapt to your codebase's specific security requirements.
80096
-
80097
- ### Authentication & Authorization
80098
-
80099
- - [ ] Authentication checks are in place where required
80100
- - [ ] Authorization verifies user has permission for the action
80101
- - [ ] Session handling follows established patterns
80102
- - [ ] No hardcoded credentials or secrets
80103
-
80104
- ### Input Validation
80105
-
80106
- - [ ] User input is validated before use
80107
- - [ ] Input sanitization for database queries (SQL injection prevention)
80108
- - [ ] Path traversal protection for file operations
80109
- - [ ] Proper escaping for output contexts (XSS prevention)
80110
-
80111
- ### Data Handling
80112
-
80113
- - [ ] Sensitive data is not logged
80114
- - [ ] PII is handled according to privacy requirements
80115
- - [ ] Secrets use environment variables, not hardcoded values
80116
- - [ ] .env files are not committed
80117
-
80118
- ### API Security
80119
-
80120
- - [ ] Rate limiting considerations for public endpoints
80121
- - [ ] CORS configuration is appropriate
80122
- - [ ] API responses don't leak sensitive information
80123
- - [ ] Error messages don't expose internal details
80124
-
80125
- ### Common Vulnerabilities to Check
80126
-
80127
- 1. **Injection Attacks**
80128
- - SQL/NoSQL injection
80129
- - Command injection
80130
- - Template injection
80131
-
80132
- 2. **Broken Access Control**
80133
- - Missing authorization checks
80134
- - IDOR (Insecure Direct Object Reference)
80135
- - Privilege escalation
80136
-
80137
- 3. **Security Misconfiguration**
80138
- - Debug mode in production
80139
- - Exposed admin interfaces
80140
- - Default credentials
80141
-
80142
- 4. **Cryptographic Issues**
80143
- - Weak hashing algorithms
80144
- - Insecure random number generation
80145
- - Improper key management
80146
-
80147
- ### Codebase-Specific Security
80148
-
80149
- Check these locations for security-related guidelines:
80150
- - Security documentation in \`docs/security*.md\`
80151
- - Authentication patterns in existing auth code
80152
- - Existing security middleware/helpers
80153
- - Security comments in sensitive code areas
80154
-
80155
- **Important:** These are general guidelines. Always verify against your project's specific security requirements and compliance needs.
80156
- `;
80157
-
80158
- // ../../services/backend/prompts/policies/design.ts
80159
- function getDesignPolicy() {
80160
- return DESIGN_POLICY;
80161
- }
80162
- var DESIGN_POLICY = `
80163
- ## Design Review Policy
80164
-
80165
- These are general design principles. Adapt to your codebase's specific design system.
80166
-
80167
- ### Design System Compliance
80168
-
80169
- - [ ] Uses existing design tokens (colors, spacing, typography)
80170
- - [ ] Follows established component patterns
80171
- - [ ] Reuses existing components instead of creating duplicates
80172
- - [ ] Styling uses semantic values, not hardcoded ones
80173
-
80174
- ### Color Usage
80175
-
80176
- **Semantic colors should be preferred:**
80177
- - Use \`text-foreground\` not \`text-black\`
80178
- - Use \`bg-card\` not \`bg-white\`
80179
- - Use \`border-border\` not \`border-gray-200\`
80180
-
80181
- **Dark mode support:**
80182
- - All UI should work in both light and dark mode
80183
- - Brand/status colors need dark variants (e.g., \`bg-red-50 dark:bg-red-950/20\`)
80184
-
80185
- ### Component Patterns
80186
-
80187
- - [ ] Components follow existing file structure conventions
80188
- - [ ] Props are typed properly
80189
- - [ ] Components are accessible (keyboard navigation, ARIA)
80190
- - [ ] Responsive design is considered
80191
-
80192
- ### Typography
80193
-
80194
- - [ ] Uses established font sizes from the design system
80195
- - [ ] Heading hierarchy is semantic (h1, h2, etc.)
80196
- - [ ] Text is readable at all sizes
80197
- - [ ] Font weights follow conventions
80198
-
80199
- ### Spacing & Layout
80200
-
80201
- - [ ] Uses design system spacing tokens
80202
- - [ ] Layout is responsive
80203
- - [ ] Alignment is consistent
80204
- - [ ] Proper use of flexbox/grid patterns
80205
-
80206
- ### UX Considerations
80207
-
80208
- - [ ] Loading states are handled
80209
- - [ ] Error states have clear messaging
80210
- - [ ] Empty states are designed
80211
- - [ ] Interactive elements have hover/focus states
80212
-
80213
- ### Common Design Issues to Catch
80214
-
80215
- 1. **Inconsistent Styling**
80216
- - Different button styles for similar actions
80217
- - Inconsistent spacing between elements
80218
- - Mixed font sizes within components
80219
-
80220
- 2. **Accessibility Gaps**
80221
- - Missing keyboard navigation
80222
- - Low color contrast
80223
- - Missing ARIA labels
80224
- - Focus states not visible
80225
-
80226
- 3. **Hardcoded Values**
80227
- - Magic numbers for spacing (use tokens)
80228
- - Hardcoded colors (use semantic colors)
80229
- - Fixed widths that break responsive
80230
-
80231
- 4. **Component Duplication**
80232
- - Recreating existing components
80233
- - Copy-paste instead of abstraction
80234
- - Similar patterns implemented differently
80235
-
80236
- ### Codebase-Specific Design
80237
-
80238
- Check these locations for design guidelines:
80239
- - \`docs/design/*.md\` - Design documentation
80240
- - \`components/ui/\` - Existing UI component library
80241
- - \`tailwind.config.*\` - Theme configuration
80242
- - \`globals.css\` or theme files - CSS custom properties
80243
- - \`AGENTS.md\` or \`CLAUDE.md\` - May contain UI guidelines
80244
-
80245
- **Important:** These are general guidelines. Always verify against your project's specific design system.
80246
- `;
80247
-
80248
- // ../../services/backend/prompts/policies/performance.ts
80249
- function getPerformancePolicy() {
80250
- return PERFORMANCE_POLICY;
80251
- }
80252
- var PERFORMANCE_POLICY = `
80253
- ## Performance Review Policy
80254
-
80255
- These are general performance principles. Adapt to your codebase's specific requirements.
80256
-
80257
- ### Frontend Performance
80258
-
80259
- **React/Component Performance:**
80260
- - [ ] \`useMemo\` used for expensive computations
80261
- - [ ] \`useCallback\` used for callback props passed to child components
80262
- - [ ] \`React.memo\` considered for components receiving stable props
80263
- - [ ] No unnecessary re-renders (check dependency arrays)
80264
- - [ ] Large lists use virtualization where appropriate
80265
-
80266
- **Bundle Size:**
80267
- - [ ] No large dependencies added for simple functionality
80268
- - [ ] Dynamic imports (\`lazy\`) used for route-level code splitting
80269
- - [ ] Tree-shaking friendly imports (avoid \`import * as\`)
80270
- - [ ] Images/assets are appropriately sized and optimized
80271
-
80272
- **Rendering:**
80273
- - [ ] No layout thrashing (reading and writing DOM in loops)
80274
- - [ ] CSS animations use \`transform\` and \`opacity\` where possible
80275
- - [ ] Avoid inline styles that change frequently
80276
- - [ ] Consider \`will-change\` for animated elements
80277
-
80278
- ### Backend Performance
80279
-
80280
- **Database Queries:**
80281
- - [ ] Queries use appropriate indexes
80282
- - [ ] N+1 query patterns are avoided or justified
80283
- - [ ] Pagination used for large result sets
80284
- - [ ] Expensive queries are cached where appropriate
80285
-
80286
- **API Design:**
80287
- - [ ] Responses don't include unnecessary data
80288
- - [ ] Batch endpoints available for bulk operations
80289
- - [ ] Expensive operations are async/background where possible
80290
- - [ ] Rate limiting considered for resource-intensive endpoints
80291
-
80292
- **Memory & Resources:**
80293
- - [ ] No memory leaks (event listeners cleaned up, subscriptions closed)
80294
- - [ ] Large data structures are streamed, not loaded entirely
80295
- - [ ] Connection pooling used for database/external services
80296
- - [ ] Temporary files/resources are cleaned up
80297
-
80298
- ### Common Performance Issues to Catch
80299
-
80300
- 1. **Unnecessary Computation**
80301
- - Computing values on every render
80302
- - Recalculating derived data without memoization
80303
- - Expensive operations in hot paths
80304
-
80305
- 2. **Over-fetching**
80306
- - Requesting more data than needed
80307
- - Missing pagination on large datasets
80308
- - Not using projection/select for specific fields
80309
-
80310
- 3. **Under-caching**
80311
- - Repeated identical API calls
80312
- - Not caching expensive computations
80313
- - Missing server-side caching for static data
80314
-
80315
- 4. **Blocking Operations**
80316
- - Synchronous operations blocking the event loop
80317
- - Not using async patterns for I/O
80318
- - Long-running operations without progress feedback
80319
-
80320
- 5. **React-Specific Issues**
80321
- - Missing dependency arrays causing infinite loops
80322
- - Creating new objects/functions in render
80323
- - Not using \`key\` prop properly in lists
80324
- - State updates in useEffect without proper deps
80325
-
80326
- ### Platform-Specific Considerations
80327
-
80328
- **Next.js:**
80329
- - Server Components for static content
80330
- - Client Components for interactive elements
80331
- - Image optimization with next/image
80332
- - Route segment config for caching
80333
-
80334
- **Convex:**
80335
- - Query indexing for filtered/sorted data
80336
- - Pagination for large result sets
80337
- - Optimistic updates for better UX
80338
- - Reactive queries vs. one-time fetches
80339
-
80340
- **General Web:**
80341
- - Core Web Vitals (LCP, FID, CLS)
80342
- - Time to Interactive (TTI)
80343
- - First Contentful Paint (FCP)
80344
-
80345
- ### Questions to Ask
80346
-
80347
- 1. "Will this scale with 10x/100x more data?"
80348
- 2. "What happens with slow network conditions?"
80349
- 3. "Are there any O(n²) or worse algorithms?"
80350
- 4. "Could this operation be batched or debounced?"
80351
- 5. "Is this computation necessary on every render?"
80352
-
80353
- **Important:** These are general guidelines. Performance requirements vary by application.
80354
- Focus on user-facing performance impact rather than micro-optimizations.
80355
- `;
80356
-
80357
78229
  // ../../services/backend/prompts/generator.ts
80358
- var exports_generator = {};
80359
- __export(exports_generator, {
80360
- getSecurityPolicy: () => getSecurityPolicy,
80361
- getReviewGuidelines: () => getReviewGuidelines,
80362
- getPerformancePolicy: () => getPerformancePolicy,
80363
- getDesignPolicy: () => getDesignPolicy,
80364
- generateRolePrompt: () => generateRolePrompt,
80365
- generateHandoffOutput: () => generateHandoffOutput,
80366
- generateGeneralInstructions: () => generateGeneralInstructions,
80367
- composeSystemPrompt: () => composeSystemPrompt2,
80368
- composeInitPrompt: () => composeInitPrompt,
80369
- composeInitMessage: () => composeInitMessage
80370
- });
80371
- function generateGeneralInstructions(_input) {
80372
- const sections = [];
80373
- sections.push(getNextTaskGuidance());
80374
- return sections.join(`
80375
-
80376
- `);
80377
- }
80378
- function generateRolePrompt(ctx) {
80379
- const selectorCtx = buildSelectorContext({
80380
- role: ctx.role,
80381
- teamRoles: ctx.teamRoles,
80382
- teamId: ctx.teamId,
80383
- teamName: ctx.teamName,
80384
- teamEntryPoint: ctx.teamEntryPoint,
80385
- convexUrl: ctx.convexUrl,
80386
- chatroomId: ctx.chatroomId,
80387
- workflow: ctx.currentClassification
80388
- });
80389
- const sections = [];
80390
- sections.push(getRoleTitleSection(selectorCtx));
80391
- sections.push(getRoleDescriptionSection(selectorCtx));
80392
- sections.push(getGlossarySection({ convexUrl: ctx.convexUrl ?? "", chatroomId: ctx.chatroomId }));
80393
- sections.push(getRoleGuidanceSection(selectorCtx));
80394
- if (ctx.currentClassification) {
80395
- sections.push(getCurrentClassificationSection(ctx.currentClassification));
80396
- }
80397
- sections.push(getHandoffOptionsSection({
80398
- availableHandoffRoles: ctx.availableHandoffRoles
80399
- }));
80400
- sections.push(getCommandsReferenceSection({
80401
- chatroomId: ctx.chatroomId,
80402
- role: ctx.role,
80403
- convexUrl: ctx.convexUrl
80404
- }));
80405
- return composeSections(sections);
80406
- }
80407
- function buildInitPromptSections(input, selectorCtx) {
80408
- const { chatroomId, role, teamRoles, convexUrl } = input;
80409
- const otherRoles = teamRoles.filter((r) => r.toLowerCase() !== role.toLowerCase());
80410
- const handoffTargets = [...new Set([...otherRoles, "user"])];
80411
- const sections = [
80412
- getTeamHeaderSection(input.teamName),
80413
- getRoleTitleSection(selectorCtx),
80414
- getRoleDescriptionSection(selectorCtx),
80415
- getGlossarySection({ convexUrl: convexUrl ?? "", chatroomId }),
80416
- getSessionVsChatroomTaskSection(),
80417
- getGettingStartedSection(selectorCtx),
80418
- getClassificationGuideSection(selectorCtx),
80419
- getRoleGuidanceSection(selectorCtx),
80420
- getHandoffOptionsSection({ availableHandoffRoles: handoffTargets }),
80421
- getCommandsReferenceSection({ chatroomId, role, convexUrl }),
80422
- getNextStepSection({ chatroomId, role, convexUrl })
80423
- ];
80424
- return sections;
80425
- }
80426
- function composeSystemPrompt2(input) {
80427
- if (isNativeHarness(input.agentHarness)) {
80428
- return composeNativeSystemPrompt(input);
80429
- }
80430
- const { chatroomId, role, teamId, teamName, teamRoles, teamEntryPoint, convexUrl } = input;
80431
- const selectorCtx = buildSelectorContext({
80432
- role,
80433
- teamRoles,
80434
- teamId,
80435
- teamName,
80436
- teamEntryPoint,
80437
- convexUrl,
80438
- chatroomId,
80439
- agentType: input.agentType,
80440
- nativeIntegration: false
80441
- });
80442
- return composeSections(buildInitPromptSections(input, selectorCtx));
80443
- }
80444
78230
  function isEnhancerCheckInQueuedHandoff(params) {
80445
78231
  return params.enhancerCheckInQueued === true && params.role.toLowerCase() === "planner" && params.nextRole.toLowerCase() === "enhancer";
80446
78232
  }
@@ -80480,17 +78266,6 @@ function generateHandoffOutput(params) {
80480
78266
  return lines.join(`
80481
78267
  `);
80482
78268
  }
80483
- function composeInitMessage(_input) {
80484
- return "";
80485
- }
80486
- function composeInitPrompt(input) {
80487
- const systemPrompt = composeSystemPrompt2(input);
80488
- const initMessage = composeInitMessage(input);
80489
- const initPrompt = initMessage ? `${systemPrompt}
80490
-
80491
- ${initMessage}` : systemPrompt;
80492
- return { systemPrompt, initMessage, initPrompt };
80493
- }
80494
78269
  var init_generator = __esm(() => {
80495
78270
  init_command();
80496
78271
  init_reminder();
@@ -99284,6 +97059,30 @@ var init_assigned_task_snapshot_store = __esm(() => {
99284
97059
  rows = [];
99285
97060
  });
99286
97061
 
97062
+ // src/commands/machine/daemon-start/restart-orchestrator-in-flight.ts
97063
+ function roleKey2(chatroomId, role) {
97064
+ return `${chatroomId}:${role.toLowerCase()}`;
97065
+ }
97066
+ function markRestartOrchestratorInFlight(chatroomId, role, correlationId) {
97067
+ inFlight.set(roleKey2(chatroomId, role), correlationId);
97068
+ }
97069
+ function clearRestartOrchestratorInFlight(chatroomId, role, correlationId) {
97070
+ const key = roleKey2(chatroomId, role);
97071
+ if (correlationId !== undefined && inFlight.get(key) !== correlationId)
97072
+ return;
97073
+ inFlight.delete(key);
97074
+ }
97075
+ function isRestartOrchestratorInFlight(chatroomId, role) {
97076
+ return inFlight.has(roleKey2(chatroomId, role));
97077
+ }
97078
+ function filterSnapshotsExcludingRestartInFlight(snapshots) {
97079
+ return snapshots.filter((row) => !isRestartOrchestratorInFlight(row.chatroomId, row.agentConfig.role));
97080
+ }
97081
+ var inFlight;
97082
+ var init_restart_orchestrator_in_flight = __esm(() => {
97083
+ inFlight = new Map;
97084
+ });
97085
+
99287
97086
  // src/commands/machine/daemon-start/native-task-delivery-coordinator.ts
99288
97087
  class NativeTaskDeliveryCoordinator {
99289
97088
  onSessionLost(params) {
@@ -99296,6 +97095,8 @@ class NativeTaskDeliveryCoordinator {
99296
97095
  getRoleDeliveryState().resetDeliveryState(chatroomId, role);
99297
97096
  }
99298
97097
  tryInjectNextForRole(chatroomId, role) {
97098
+ if (isRestartOrchestratorInFlight(chatroomId, role))
97099
+ return;
99299
97100
  const session2 = getNativeDeliverySession();
99300
97101
  if (!session2)
99301
97102
  return;
@@ -99315,7 +97116,10 @@ class NativeTaskDeliveryCoordinator {
99315
97116
  });
99316
97117
  }
99317
97118
  reconcileAssignedTasks(params) {
99318
- const { tasks, runtime: runtime4, effectContext: effectContext2, agentMgr, sessionDeps, machineId } = params;
97119
+ const tasks = filterSnapshotsExcludingRestartInFlight(params.tasks);
97120
+ if (tasks.length === 0)
97121
+ return;
97122
+ const { runtime: runtime4, effectContext: effectContext2, agentMgr, sessionDeps, machineId } = params;
99319
97123
  const deliveryState = getRoleDeliveryState();
99320
97124
  const ledger = getNativeDeliveryLedger();
99321
97125
  const pendingFirst = [...tasks].sort((a, b) => {
@@ -99404,6 +97208,8 @@ function resetRoleDeliveryState(chatroomId, role) {
99404
97208
  getRoleDeliveryState().resetDeliveryState(chatroomId, role);
99405
97209
  }
99406
97210
  function notifyNativeTurnIdle(params) {
97211
+ if (isRestartOrchestratorInFlight(params.chatroomId, params.role))
97212
+ return;
99407
97213
  logNativeDeliveryPrimary(params.role, params.chatroomId);
99408
97214
  getNativeTaskDeliveryCoordinator().tryInjectNextForRole(params.chatroomId, params.role);
99409
97215
  }
@@ -99416,6 +97222,7 @@ var init_native_task_delivery_coordinator = __esm(() => {
99416
97222
  init_api3();
99417
97223
  init_assigned_task_snapshot_store();
99418
97224
  init_convex_error();
97225
+ init_restart_orchestrator_in_flight();
99419
97226
  });
99420
97227
 
99421
97228
  // src/commands/machine/daemon-start/restart-orchestrator.ts
@@ -99438,14 +97245,6 @@ async function waitForHarnessSessionId(deps, event, pid) {
99438
97245
  if (initial?.harnessSessionId) {
99439
97246
  return initial.harnessSessionId;
99440
97247
  }
99441
- await deps.session.backend.mutation(api.machines.emitHarnessSessionAwaiting, {
99442
- sessionId: deps.session.sessionId,
99443
- machineId: deps.session.machineId,
99444
- chatroomId: event.chatroomId,
99445
- role: event.role,
99446
- pid,
99447
- timeoutMs: HARNESS_SESSION_READY_TIMEOUT_MS
99448
- });
99449
97248
  const deadline = Date.now() + HARNESS_SESSION_READY_TIMEOUT_MS;
99450
97249
  while (Date.now() < deadline) {
99451
97250
  const slot = deps.agentMgr.getSlot(event.chatroomId, event.role);
@@ -99454,14 +97253,6 @@ async function waitForHarnessSessionId(deps, event, pid) {
99454
97253
  }
99455
97254
  await sleep5(100);
99456
97255
  }
99457
- await deps.session.backend.mutation(api.machines.emitHarnessSessionTimeout, {
99458
- sessionId: deps.session.sessionId,
99459
- machineId: deps.session.machineId,
99460
- chatroomId: event.chatroomId,
99461
- role: event.role,
99462
- pid,
99463
- timeoutMs: HARNESS_SESSION_READY_TIMEOUT_MS
99464
- });
99465
97256
  await deps.agentMgr.stop({
99466
97257
  chatroomId: event.chatroomId,
99467
97258
  role: event.role,
@@ -99556,15 +97347,14 @@ async function deliverPendingTasks(deps, event) {
99556
97347
  }
99557
97348
  async function runRestartOrchestrator(deps, event) {
99558
97349
  const { chatroomId, role } = event;
97350
+ markRestartOrchestratorInFlight(chatroomId, role, event.correlationId);
99559
97351
  try {
99560
- await emitPhase(deps, event, "reset");
99561
97352
  resetRoleDeliveryState(chatroomId, role);
99562
97353
  await deps.agentMgr.stop({
99563
97354
  chatroomId,
99564
97355
  role,
99565
97356
  reason: "user.restart"
99566
97357
  });
99567
- await emitPhase(deps, event, "spawn");
99568
97358
  const spawnResult = await exports_Effect.runPromise(deps.agentMgr.ensureRunning({
99569
97359
  chatroomId,
99570
97360
  role,
@@ -99578,23 +97368,12 @@ async function runRestartOrchestrator(deps, event) {
99578
97368
  await emitPhase(deps, event, "failed", spawnResult.error ?? "spawn failed");
99579
97369
  return;
99580
97370
  }
99581
- await emitPhase(deps, event, "await_session");
99582
97371
  const harnessSessionId = await waitForHarnessSessionId(deps, event, spawnResult.pid);
99583
97372
  if (!harnessSessionId) {
99584
97373
  await emitPhase(deps, event, "failed", "harnessSessionId timeout");
99585
97374
  return;
99586
97375
  }
99587
- await deps.session.backend.mutation(api.machines.emitHarnessSessionReady, {
99588
- sessionId: deps.session.sessionId,
99589
- machineId: deps.session.machineId,
99590
- chatroomId,
99591
- role,
99592
- harnessSessionId,
99593
- pid: spawnResult.pid
99594
- });
99595
97376
  await forceNativeWaiting(deps, event);
99596
- await emitPhase(deps, event, "ready");
99597
- await emitPhase(deps, event, "deliver");
99598
97377
  const deliveredTaskIds = await deliverPendingTasks(deps, event);
99599
97378
  await deps.session.backend.mutation(api.machines.emitRestartCompleted, {
99600
97379
  sessionId: deps.session.sessionId,
@@ -99604,10 +97383,11 @@ async function runRestartOrchestrator(deps, event) {
99604
97383
  correlationId: event.correlationId,
99605
97384
  deliveredTaskIds
99606
97385
  });
99607
- await emitPhase(deps, event, "completed");
99608
97386
  } catch (err) {
99609
97387
  console.warn(`[RestartOrchestrator] failed for ${role}@${chatroomId}: ${getErrorMessage(err)}`);
99610
97388
  await emitPhase(deps, event, "failed", getErrorMessage(err));
97389
+ } finally {
97390
+ clearRestartOrchestratorInFlight(chatroomId, role, event.correlationId);
99611
97391
  }
99612
97392
  }
99613
97393
  var init_restart_orchestrator = __esm(() => {
@@ -99621,6 +97401,7 @@ var init_restart_orchestrator = __esm(() => {
99621
97401
  init_native_task_injector();
99622
97402
  init_api3();
99623
97403
  init_convex_error();
97404
+ init_restart_orchestrator_in_flight();
99624
97405
  });
99625
97406
 
99626
97407
  // src/events/daemon/agent/on-request-restart-agent.ts
@@ -100742,6 +98523,17 @@ async function openFinder(workingDir) {
100742
98523
  execFireAndForget(`${cmd} ${escapeShellArg(workingDir)}`, "open-finder");
100743
98524
  return { success: true };
100744
98525
  }
98526
+ async function openCursor(workingDir) {
98527
+ const available = await isCliAvailable("cursor");
98528
+ if (!available) {
98529
+ return {
98530
+ success: false,
98531
+ error: "Cursor CLI (cursor) not found. Install via: Cursor → Cmd+Shift+P → 'Shell Command: Install cursor in PATH'"
98532
+ };
98533
+ }
98534
+ execFireAndForget(`cursor ${escapeShellArg(workingDir)}`, "open-cursor");
98535
+ return { success: true };
98536
+ }
100745
98537
  async function openGithubDesktop(workingDir) {
100746
98538
  const available = await isCliAvailable("github");
100747
98539
  if (!available) {
@@ -100816,6 +98608,7 @@ var init_execute_local_action = __esm(() => {
100816
98608
  actionHandlers = {
100817
98609
  "open-vscode": openVscode,
100818
98610
  "open-finder": openFinder,
98611
+ "open-cursor": openCursor,
100819
98612
  "open-github-desktop": openGithubDesktop,
100820
98613
  "git-discard-file": gitDiscardFileAction,
100821
98614
  "git-discard-all": gitDiscardAllAction,
@@ -103236,7 +101029,7 @@ var init_open_pending_session = __esm(() => {
103236
101029
 
103237
101030
  // src/commands/machine/daemon-start/direct-harness/session-subscriber.ts
103238
101031
  function startSessionSubscriber(daemonSession, wsClient2, deps) {
103239
- const inFlight = new Set;
101032
+ const inFlight2 = new Set;
103240
101033
  const unsub = wsClient2.onUpdate(api.daemon.directHarness.sessions.listPendingSessionsForMachine, {
103241
101034
  sessionId: daemonSession.sessionId,
103242
101035
  machineId: daemonSession.machineId
@@ -103245,9 +101038,9 @@ function startSessionSubscriber(daemonSession, wsClient2, deps) {
103245
101038
  return;
103246
101039
  for (const session2 of pendingSessions) {
103247
101040
  const rowId = session2._id;
103248
- if (inFlight.has(rowId))
101041
+ if (inFlight2.has(rowId))
103249
101042
  continue;
103250
- inFlight.add(rowId);
101043
+ inFlight2.add(rowId);
103251
101044
  (async () => {
103252
101045
  const harnessName = session2.opencode?.harnessName ?? "opencode-sdk";
103253
101046
  const agent = session2.opencode?.lastUsedConfig?.agent ?? "build";
@@ -103258,7 +101051,7 @@ function startSessionSubscriber(daemonSession, wsClient2, deps) {
103258
101051
  harnessName,
103259
101052
  lastUsedConfig: { agent, ...model ? { model } : {} }
103260
101053
  }, { logPrefix: "[direct-harness]", handleProviderIdEvents: true });
103261
- })().finally(() => inFlight.delete(rowId));
101054
+ })().finally(() => inFlight2.delete(rowId));
103262
101055
  }
103263
101056
  }, (err) => {
103264
101057
  console.warn("[direct-harness] Session subscription error:", err instanceof Error ? err.message : String(err));
@@ -103793,21 +101586,21 @@ var init_prompt_subscriber2 = __esm(() => {
103793
101586
 
103794
101587
  // src/commands/machine/daemon-start/agentic-query/session-subscriber.ts
103795
101588
  function startSessionSubscriber2(daemonSession, wsClient2, deps) {
103796
- const inFlight = new Set;
101589
+ const inFlight2 = new Set;
103797
101590
  const unsub = wsClient2.onUpdate(api.daemon.agenticQuery.runs.pendingForMachine, { sessionId: daemonSession.sessionId, machineId: daemonSession.machineId }, (pendingSessions) => {
103798
101591
  if (!pendingSessions || pendingSessions.length === 0)
103799
101592
  return;
103800
101593
  for (const session2 of pendingSessions) {
103801
101594
  const rowId = session2.runId;
103802
- if (inFlight.has(rowId))
101595
+ if (inFlight2.has(rowId))
103803
101596
  continue;
103804
- inFlight.add(rowId);
101597
+ inFlight2.add(rowId);
103805
101598
  openPendingHarnessSession(daemonSession, deps, {
103806
101599
  rowId: session2.runId,
103807
101600
  workspaceId: session2.workspaceId,
103808
101601
  harnessName: session2.harnessName,
103809
101602
  lastUsedConfig: session2.lastUsedConfig
103810
- }, { logPrefix: "[agentic-query]", handleProviderIdEvents: false }).finally(() => inFlight.delete(rowId));
101603
+ }, { logPrefix: "[agentic-query]", handleProviderIdEvents: false }).finally(() => inFlight2.delete(rowId));
103811
101604
  }
103812
101605
  }, (err) => {
103813
101606
  console.warn("[agentic-query] Session subscription error:", err instanceof Error ? err.message : String(err));
@@ -104100,12 +101893,12 @@ var init_wait_for_enhancer_job = __esm(() => {
104100
101893
 
104101
101894
  // src/commands/machine/daemon-start/enhancer/job-subscriber.ts
104102
101895
  function startEnhancerJobSubscriber(sessionId, machineId, convexUrl, backend2, wsClient2, agentServices) {
104103
- const inFlight = new Set;
101896
+ const inFlight2 = new Set;
104104
101897
  const unsub = wsClient2.onUpdate(api.daemon.enhancer.index.pendingForMachine, { sessionId, machineId }, (jobs) => {
104105
101898
  for (const job of jobs ?? []) {
104106
- if (inFlight.has(job.jobId))
101899
+ if (inFlight2.has(job.jobId))
104107
101900
  continue;
104108
- inFlight.add(job.jobId);
101901
+ inFlight2.add(job.jobId);
104109
101902
  (async () => {
104110
101903
  let claimed = false;
104111
101904
  let chatroomId = job.chatroomId;
@@ -104139,7 +101932,7 @@ function startEnhancerJobSubscriber(sessionId, machineId, convexUrl, backend2, w
104139
101932
  });
104140
101933
  return;
104141
101934
  }
104142
- spawnResult = await service3.spawn({
101935
+ const spawned = await service3.spawn({
104143
101936
  workingDir: payload.workingDir,
104144
101937
  prompt: createSpawnPrompt(payload.taskEnvelope),
104145
101938
  systemPrompt: payload.systemPrompt,
@@ -104151,18 +101944,18 @@ function startEnhancerJobSubscriber(sessionId, machineId, convexUrl, backend2, w
104151
101944
  },
104152
101945
  resolvedConvexUrl: convexUrl
104153
101946
  });
104154
- spawnResult.onLogLine?.((line) => {
101947
+ spawnResult = spawned;
101948
+ spawned.onLogLine?.((line) => {
104155
101949
  writeEnhancerLog(line);
104156
101950
  });
104157
- const sr = spawnResult;
104158
- const outcome = await waitForEnhancerJobResolution({
101951
+ await waitForEnhancerJobResolution({
104159
101952
  sessionId,
104160
101953
  chatroomId: payload.chatroomId,
104161
101954
  jobId: payload.jobId,
104162
101955
  backend: backend2,
104163
- onAssistantText: sr.onAssistantText ? (cb) => sr.onAssistantText(cb) : undefined,
104164
- onAgentEnd: sr.onAgentEnd ? (cb) => sr.onAgentEnd(cb) : undefined,
104165
- onExit: (cb) => sr.onExit(() => cb()),
101956
+ onAssistantText: spawned.onAssistantText ? (cb) => spawned.onAssistantText?.(cb) : undefined,
101957
+ onAgentEnd: spawned.onAgentEnd ? (cb) => spawned.onAgentEnd?.(cb) : undefined,
101958
+ onExit: (cb) => spawned.onExit(() => cb()),
104166
101959
  onSalvageComplete: async (content) => {
104167
101960
  await backend2.mutation(api.web.enhancer.index.complete, {
104168
101961
  sessionId,
@@ -104193,7 +101986,7 @@ function startEnhancerJobSubscriber(sessionId, machineId, convexUrl, backend2, w
104193
101986
  });
104194
101987
  }
104195
101988
  } finally {
104196
- inFlight.delete(job.jobId);
101989
+ inFlight2.delete(job.jobId);
104197
101990
  if (spawnResult && service3) {
104198
101991
  try {
104199
101992
  await service3.stop(spawnResult.pid);
@@ -109435,6 +107228,53 @@ var init_crash_loop_tracker = __esm(() => {
109435
107228
  ];
109436
107229
  });
109437
107230
 
107231
+ // src/infrastructure/services/remote-agents/native-spawn-presence.ts
107232
+ async function emitNativeWaitingAfterSpawn(ctx, harness, opts) {
107233
+ if (!getHarnessCapabilities(harness).supportsNativeIntegration) {
107234
+ return false;
107235
+ }
107236
+ try {
107237
+ await ctx.backend.mutation(api.participants.join, {
107238
+ sessionId: ctx.sessionId,
107239
+ chatroomId: ctx.chatroomId,
107240
+ role: ctx.role,
107241
+ action: NATIVE_WAITING_ACTION
107242
+ });
107243
+ return true;
107244
+ } catch (err) {
107245
+ const error51 = err instanceof Error ? err : new Error(String(err));
107246
+ if (opts?.onError) {
107247
+ opts.onError(error51);
107248
+ }
107249
+ return false;
107250
+ }
107251
+ }
107252
+ function wireThrottledTokenActivityOnOutput(opts) {
107253
+ const now = opts.now ?? (() => Date.now());
107254
+ const throttleMs = opts.throttleMs ?? NATIVE_TOKEN_ACTIVITY_THROTTLE_MS;
107255
+ let lastReportedTokenAt = 0;
107256
+ const register = opts.spawnResult.onOutput;
107257
+ if (!register)
107258
+ return;
107259
+ register(() => {
107260
+ const t = now();
107261
+ if (lastReportedTokenAt === 0 || t - lastReportedTokenAt >= throttleMs) {
107262
+ lastReportedTokenAt = t;
107263
+ opts.backend.mutation(api.participants.updateTokenActivity, {
107264
+ sessionId: opts.sessionId,
107265
+ chatroomId: opts.chatroomId,
107266
+ role: opts.role
107267
+ }).catch(() => {});
107268
+ }
107269
+ });
107270
+ }
107271
+ var NATIVE_TOKEN_ACTIVITY_THROTTLE_MS = 30000;
107272
+ var init_native_spawn_presence = __esm(() => {
107273
+ init_participant();
107274
+ init_types();
107275
+ init_api3();
107276
+ });
107277
+
109438
107278
  // src/infrastructure/services/agent-process-manager/turn-completed-backend.ts
109439
107279
  function createTurnCompletedBackend(deps) {
109440
107280
  return {
@@ -111275,17 +109115,13 @@ class AgentProcessManager {
111275
109115
  this.applyHarnessSessionIdUpdate(slotKey, slot, opts.chatroomId, opts.role, info);
111276
109116
  });
111277
109117
  }
111278
- let lastReportedTokenAt = 0;
111279
- spawnResult.onOutput(() => {
111280
- const now = this.deps.clock.now();
111281
- if (lastReportedTokenAt === 0 || now - lastReportedTokenAt >= 30000) {
111282
- lastReportedTokenAt = now;
111283
- this.deps.backend.mutation(api.participants.updateTokenActivity, {
111284
- sessionId: this.deps.sessionId,
111285
- chatroomId: opts.chatroomId,
111286
- role: opts.role
111287
- }).catch(() => {});
111288
- }
109118
+ wireThrottledTokenActivityOnOutput({
109119
+ backend: this.deps.backend,
109120
+ sessionId: this.deps.sessionId,
109121
+ chatroomId: opts.chatroomId,
109122
+ role: opts.role,
109123
+ spawnResult,
109124
+ now: () => this.deps.clock.now()
111289
109125
  });
111290
109126
  }
111291
109127
  async finalizeRunningSlot(key, slot, opts, spawnResult, wantResume) {
@@ -111302,20 +109138,16 @@ class AgentProcessManager {
111302
109138
  await this.emitNativeWaiting(opts.chatroomId, opts.role, opts.agentHarness);
111303
109139
  }
111304
109140
  async emitNativeWaiting(chatroomId, role, harness) {
111305
- if (!getHarnessCapabilities(harness).supportsNativeIntegration)
111306
- return false;
111307
- try {
111308
- await this.deps.backend.mutation(api.participants.join, {
111309
- sessionId: this.deps.sessionId,
111310
- chatroomId,
111311
- role,
111312
- action: NATIVE_WAITING_ACTION
111313
- });
111314
- return true;
111315
- } catch (err) {
111316
- console.log(` ⚠️ Failed to emit native:waiting for ${role}: ${err.message}`);
111317
- return false;
111318
- }
109141
+ return emitNativeWaitingAfterSpawn({
109142
+ backend: this.deps.backend,
109143
+ sessionId: this.deps.sessionId,
109144
+ chatroomId,
109145
+ role
109146
+ }, harness, {
109147
+ onError: (err) => {
109148
+ console.log(` ⚠️ Failed to emit native:waiting for ${role}: ${err.message}`);
109149
+ }
109150
+ });
111319
109151
  }
111320
109152
  async doEnsureRunning(key, slot, opts) {
111321
109153
  slot.state = "spawning";
@@ -111503,6 +109335,7 @@ var AGENT_EXIT_RETRY_INTERVAL_MS = 1e4, STOPPING_TIMEOUT_MS = 30000;
111503
109335
  var init_agent_process_manager = __esm(() => {
111504
109336
  init_types();
111505
109337
  init_participant();
109338
+ init_native_spawn_presence();
111506
109339
  init_esm();
111507
109340
  init_turn_completed_backend();
111508
109341
  init_api3();
@@ -114513,6 +112346,8 @@ async function nudgeStuckTasks(tasks, now, cooldown, runtime4, effectContext2, a
114513
112346
  }
114514
112347
  async function reviveNativeTasks(tasks, localHealth, now, cooldown, runtime4, effectContext2, agentMgr, sessionDeps, machineId) {
114515
112348
  for (const row of listNativeTasksNeedingRevive(tasks, localHealth, now, cooldown)) {
112349
+ if (isRestartOrchestratorInFlight(row.chatroomId, row.agentConfig.role))
112350
+ continue;
114516
112351
  await clearStuckStoppingSlotIfNeeded(agentMgr, row.chatroomId, row.agentConfig.role);
114517
112352
  const full = await fetchTaskForAction(sessionDeps, machineId, row);
114518
112353
  if (!full)
@@ -114521,6 +112356,7 @@ async function reviveNativeTasks(tasks, localHealth, now, cooldown, runtime4, ef
114521
112356
  }
114522
112357
  }
114523
112358
  async function processTasksUpdate(tasks, runtime4, effectContext2, cooldown, agentMgr, sessionDeps, machineId, _pass) {
112359
+ tasks = filterSnapshotsExcludingRestartInFlight(tasks);
114524
112360
  if (tasks.length === 0)
114525
112361
  return;
114526
112362
  const now = Date.now();
@@ -114557,7 +112393,7 @@ function runLocalStoreReconcilePass(params) {
114557
112393
  const { stopped, monitorPassInFlight, agentMgr, runtime: runtime4, effectContext: effectContext2, sessionDeps, machineId } = params;
114558
112394
  if (stopped || monitorPassInFlight)
114559
112395
  return;
114560
- const deliverable = listDeliverablePendingFromStore(agentMgr);
112396
+ const deliverable = filterSnapshotsExcludingRestartInFlight(listDeliverablePendingFromStore(agentMgr));
114561
112397
  if (deliverable.length === 0)
114562
112398
  return;
114563
112399
  const first = deliverable[0];
@@ -114700,6 +112536,7 @@ var init_task_monitor = __esm(() => {
114700
112536
  init_esm();
114701
112537
  init_daemon_services();
114702
112538
  init_native_ready_invariant();
112539
+ init_restart_orchestrator_in_flight();
114703
112540
  init_native_task_delivery_coordinator();
114704
112541
  init_native_task_injector_logic();
114705
112542
  init_task_monitor_logic();
@@ -115973,51 +113810,6 @@ handoffCommandGroup.requiredOption("--chatroom-id <id>", "Chatroom identifier").
115973
113810
  console.error("❌ Message is empty");
115974
113811
  process.exit(1);
115975
113812
  }
115976
- const shouldEnhance = options.role.toLowerCase() === "planner" && options.nextRole.toLowerCase() === "enhancer";
115977
- if (shouldEnhance) {
115978
- const { api: api3 } = await Promise.resolve().then(() => (init_api3(), exports_api));
115979
- const { getConvexClient: getConvexClient2 } = await Promise.resolve().then(() => (init_client2(), exports_client));
115980
- const { getSessionId: getSessionId2 } = await Promise.resolve().then(() => (init_storage(), exports_storage));
115981
- const client4 = await getConvexClient2();
115982
- const sessionId = await getSessionId2();
115983
- if (sessionId) {
115984
- try {
115985
- const config4 = await client4.query(api3.web.enhancer.index.getConfig, {
115986
- sessionId,
115987
- chatroomId: options.chatroomId
115988
- });
115989
- if (config4 && config4.enabled) {
115990
- await client4.mutation(api3.web.enhancer.index.enqueueHandoff, {
115991
- sessionId,
115992
- chatroomId: options.chatroomId,
115993
- senderRole: options.role,
115994
- targetRole: options.nextRole,
115995
- content: message
115996
- });
115997
- const { generateHandoffOutput: generateHandoffOutput2 } = await Promise.resolve().then(() => (init_generator(), exports_generator));
115998
- const { getConvexUrl: getConvexUrl2 } = await Promise.resolve().then(() => (init_client2(), exports_client));
115999
- const convexUrl = await getConvexUrl2();
116000
- console.log(generateHandoffOutput2({
116001
- role: options.role,
116002
- nextRole: options.nextRole,
116003
- chatroomId: options.chatroomId,
116004
- convexUrl,
116005
- enhancerCheckInQueued: true
116006
- }));
116007
- return;
116008
- }
116009
- } catch (err) {
116010
- const error51 = err;
116011
- if (error51?.data?.code !== "ENHANCER_NOT_ENABLED") {
116012
- console.error(`
116013
- ❌ ERROR: Enhancer check-in failed`);
116014
- console.error(`
116015
- ${error51?.data?.message ?? err.message}`);
116016
- process.exit(1);
116017
- }
116018
- }
116019
- }
116020
- }
116021
113813
  const { handoff: handoff2 } = await Promise.resolve().then(() => (init_handoff(), exports_handoff));
116022
113814
  await handoff2(options.chatroomId, {
116023
113815
  role: options.role,
@@ -116359,4 +114151,4 @@ program2.hook("preAction", async (_thisCommand, actionCommand) => {
116359
114151
  });
116360
114152
  program2.parse();
116361
114153
 
116362
- //# debugId=139534CD91C868F464756E2164756E21
114154
+ //# debugId=8401A70A2CD118D564756E2164756E21