chatroom-cli 1.107.2 → 1.108.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -79451,21 +79451,7 @@ function getNextTaskCommand(params) {
79451
79451
  var init_command = () => {};
79452
79452
 
79453
79453
  // ../../services/backend/src/domain/entities/participant.ts
79454
- var NATIVE_WAITING_ACTION = "native:waiting", NATIVE_TASK_INJECTED_ACTION = "native:task-injected", GET_NEXT_TASK_STARTED_ACTION = "get-next-task:started", NATIVE_HANDOFF_REMINDER = "Reminder: Use the handoff command to send your response to the team.", ONLINE_OR_STARTING_STATUSES;
79455
- var init_participant = __esm(() => {
79456
- ONLINE_OR_STARTING_STATUSES = new Set([
79457
- "agent.waiting",
79458
- "agent.requestStart",
79459
- "agent.restart",
79460
- "agent.started",
79461
- "task.acknowledged",
79462
- "task.inProgress",
79463
- "task.completed",
79464
- "agent.requestStop",
79465
- "agent.awaitingHandoff",
79466
- "agent.enhancing"
79467
- ]);
79468
- });
79454
+ var NATIVE_WAITING_ACTION = "native:waiting", NATIVE_TASK_INJECTED_ACTION = "native:task-injected", GET_NEXT_TASK_STARTED_ACTION = "get-next-task:started", NATIVE_HANDOFF_REMINDER = "Reminder: Use the handoff command to send your response to the team.";
79469
79455
 
79470
79456
  // src/commands/get-next-task/session.ts
79471
79457
  class GetNextTaskSession {
@@ -79725,7 +79711,6 @@ To reconnect, run:`);
79725
79711
  var init_session2 = __esm(() => {
79726
79712
  init_errorCodes();
79727
79713
  init_command();
79728
- init_participant();
79729
79714
  init_values();
79730
79715
  init_api3();
79731
79716
  init_client2();
@@ -80309,6 +80294,24 @@ var init_builder_to_planner = __esm(() => {
80309
80294
  init_role_guidance_disclosure();
80310
80295
  });
80311
80296
 
80297
+ // ../../services/backend/prompts/teams/duo/handoff-templates/builder.ts
80298
+ var duoBuilderHandoffContract;
80299
+ var init_builder = __esm(() => {
80300
+ init_builder_to_planner();
80301
+ duoBuilderHandoffContract = {
80302
+ role: "builder",
80303
+ receivesFrom: ["planner"],
80304
+ returnsTo: ["planner"],
80305
+ outboundTemplates: {
80306
+ planner: (query) => getBuilderToPlannerHandoffTemplate({
80307
+ chatroomId: query.chatroomId,
80308
+ role: query.role,
80309
+ cliEnvPrefix: query.cliEnvPrefix
80310
+ })
80311
+ }
80312
+ };
80313
+ });
80314
+
80312
80315
  // ../../services/backend/src/domain/usecase/enhancer/enhancer-handoff-content.ts
80313
80316
  var ENHANCER_USER_MESSAGE_PLACEHOLDER = "{{USER_MESSAGE}}";
80314
80317
 
@@ -80503,6 +80506,20 @@ var init_enhancer_to_planner = __esm(() => {
80503
80506
  init_handoff_templates();
80504
80507
  });
80505
80508
 
80509
+ // ../../services/backend/prompts/teams/duo/handoff-templates/enhancer.ts
80510
+ var duoEnhancerHandoffContract;
80511
+ var init_enhancer = __esm(() => {
80512
+ init_enhancer_to_planner();
80513
+ duoEnhancerHandoffContract = {
80514
+ role: "enhancer",
80515
+ receivesFrom: ["planner"],
80516
+ returnsTo: ["planner"],
80517
+ outboundTemplates: {
80518
+ planner: () => getEnhancerToPlannerHandoffTemplate()
80519
+ }
80520
+ };
80521
+ });
80522
+
80506
80523
  // ../../services/backend/prompts/teams/duo/handoff-templates/planner-to-builder.ts
80507
80524
  function getPlannerToBuilderHandoffTemplate() {
80508
80525
  return `${getHandoffRecipientVisibilityCallout("builder")}
@@ -80758,32 +80775,107 @@ var init_planner_to_user = __esm(() => {
80758
80775
  init_handoff_report_template_body();
80759
80776
  });
80760
80777
 
80778
+ // ../../services/backend/prompts/utils/chat-handoff-template.ts
80779
+ function getChatToUserHandoffTemplate() {
80780
+ return `${getHandoffRecipientVisibilityCallout("user")}
80781
+
80782
+ **Chat Response Template**
80783
+
80784
+ \`\`\`markdown
80785
+ <write only the concise response the user should see; do not add handoff XML sections, proofs, context evidence, or placeholder text>
80786
+ \`\`\``;
80787
+ }
80788
+ var init_chat_handoff_template = () => {};
80789
+
80790
+ // ../../services/backend/prompts/teams/duo/handoff-templates/planner.ts
80791
+ var duoPlannerHandoffContract;
80792
+ var init_planner = __esm(() => {
80793
+ init_planner_to_builder();
80794
+ init_planner_to_enhancer();
80795
+ init_planner_to_user();
80796
+ init_chat_handoff_template();
80797
+ duoPlannerHandoffContract = {
80798
+ role: "planner",
80799
+ receivesFrom: ["user", "builder", "enhancer"],
80800
+ returnsTo: ["builder", "enhancer", "user"],
80801
+ outboundTemplates: {
80802
+ builder: () => getPlannerToBuilderHandoffTemplate(),
80803
+ enhancer: () => getPlannerToEnhancerHandoffTemplate(),
80804
+ user: (query) => query.conversationMode === "chat" ? getChatToUserHandoffTemplate() : getPlannerToUserReportTemplate({
80805
+ chatroomId: query.chatroomId,
80806
+ role: query.role,
80807
+ cliEnvPrefix: query.cliEnvPrefix
80808
+ })
80809
+ }
80810
+ };
80811
+ });
80812
+
80813
+ // ../../services/backend/prompts/cli/handoff-templates/contracts.ts
80814
+ function validateRoleHandoffContracts(contracts) {
80815
+ const byRole = new Map;
80816
+ for (const contract of contracts) {
80817
+ const key = contract.role.toLowerCase();
80818
+ if (byRole.has(key)) {
80819
+ throw new Error(`Duplicate role handoff contract: "${contract.role}"`);
80820
+ }
80821
+ byRole.set(key, contract);
80822
+ }
80823
+ for (const contract of contracts) {
80824
+ const ownerKey = contract.role.toLowerCase();
80825
+ for (const target of Object.keys(contract.outboundTemplates)) {
80826
+ const targetKey = target.toLowerCase();
80827
+ if (targetKey === "user")
80828
+ continue;
80829
+ const targetContract = byRole.get(targetKey);
80830
+ if (!targetContract) {
80831
+ throw new Error(`Role "${contract.role}" declares an outbound template to "${target}", which is neither 'user' nor a role listed in the catalogue`);
80832
+ }
80833
+ const declaresOwner = (targetContract.receivesFrom ?? []).some((from) => from.toLowerCase() === ownerKey);
80834
+ if (!declaresOwner) {
80835
+ throw new Error(`Reciprocity failure: role "${targetContract.role}" receives from "${contract.role}" (via the ${contract.role} → ${target} template) but does not declare "${contract.role}" in receivesFrom`);
80836
+ }
80837
+ }
80838
+ }
80839
+ }
80840
+
80761
80841
  // ../../services/backend/prompts/teams/duo/handoff-templates/index.ts
80842
+ function listDuoRoleHandoffContracts() {
80843
+ return validatedDuoRoleHandoffContracts;
80844
+ }
80762
80845
  function getDuoHandoffTemplate(query) {
80763
- const getter = DUO_HANDOFF_TEMPLATES[`${query.fromRole.toLowerCase()}:${query.toRole.toLowerCase()}`];
80846
+ const fromRole = query.fromRole.toLowerCase();
80847
+ const toRole = query.toRole.toLowerCase();
80848
+ const contract = validatedDuoRoleHandoffContracts.find((candidate) => candidate.role.toLowerCase() === fromRole);
80849
+ const getter = contract?.outboundTemplates[toRole];
80764
80850
  return getter?.(query) ?? null;
80765
80851
  }
80766
- var DUO_HANDOFF_TEMPLATES;
80852
+ var DUO_ROLE_HANDOFF_CONTRACTS, validatedDuoRoleHandoffContracts;
80767
80853
  var init_handoff_templates2 = __esm(() => {
80768
- init_builder_to_planner();
80769
- init_enhancer_to_planner();
80770
- init_planner_to_builder();
80771
- init_planner_to_enhancer();
80772
- init_planner_to_user();
80773
- DUO_HANDOFF_TEMPLATES = {
80774
- "planner:builder": () => getPlannerToBuilderHandoffTemplate(),
80775
- "planner:enhancer": () => getPlannerToEnhancerHandoffTemplate(),
80776
- "enhancer:planner": () => getEnhancerToPlannerHandoffTemplate(),
80777
- "planner:user": (query) => getPlannerToUserReportTemplate({
80778
- chatroomId: query.chatroomId,
80779
- role: query.role,
80780
- cliEnvPrefix: query.cliEnvPrefix
80781
- }),
80782
- "builder:planner": (query) => getBuilderToPlannerHandoffTemplate({
80783
- chatroomId: query.chatroomId,
80784
- role: query.role,
80785
- cliEnvPrefix: query.cliEnvPrefix
80786
- })
80854
+ init_builder();
80855
+ init_enhancer();
80856
+ init_planner();
80857
+ DUO_ROLE_HANDOFF_CONTRACTS = [
80858
+ duoPlannerHandoffContract,
80859
+ duoBuilderHandoffContract,
80860
+ duoEnhancerHandoffContract
80861
+ ];
80862
+ validatedDuoRoleHandoffContracts = (() => {
80863
+ validateRoleHandoffContracts(DUO_ROLE_HANDOFF_CONTRACTS);
80864
+ return DUO_ROLE_HANDOFF_CONTRACTS;
80865
+ })();
80866
+ });
80867
+
80868
+ // ../../services/backend/prompts/teams/solo/handoff-templates/enhancer.ts
80869
+ var soloEnhancerHandoffContract;
80870
+ var init_enhancer2 = __esm(() => {
80871
+ init_handoff_templates();
80872
+ soloEnhancerHandoffContract = {
80873
+ role: "enhancer",
80874
+ receivesFrom: ["solo"],
80875
+ returnsTo: ["solo"],
80876
+ outboundTemplates: {
80877
+ solo: () => getEnhancerToEntryPointHandoffTemplate("solo")
80878
+ }
80787
80879
  };
80788
80880
  });
80789
80881
 
@@ -80801,27 +80893,94 @@ var init_solo_to_user = __esm(() => {
80801
80893
  init_handoff_report_template_body();
80802
80894
  });
80803
80895
 
80896
+ // ../../services/backend/prompts/teams/solo/handoff-templates/solo.ts
80897
+ var soloHandoffContract;
80898
+ var init_solo = __esm(() => {
80899
+ init_solo_to_user();
80900
+ init_handoff_templates();
80901
+ init_chat_handoff_template();
80902
+ soloHandoffContract = {
80903
+ role: "solo",
80904
+ receivesFrom: ["user", "enhancer"],
80905
+ returnsTo: ["user", "enhancer"],
80906
+ outboundTemplates: {
80907
+ enhancer: () => getEntryPointToEnhancerHandoffTemplate("solo"),
80908
+ user: (query) => query.conversationMode === "chat" ? getChatToUserHandoffTemplate() : getSoloToUserReportTemplate({
80909
+ chatroomId: query.chatroomId,
80910
+ role: query.role,
80911
+ cliEnvPrefix: query.cliEnvPrefix
80912
+ })
80913
+ }
80914
+ };
80915
+ });
80916
+
80804
80917
  // ../../services/backend/prompts/teams/solo/handoff-templates/index.ts
80918
+ function listSoloRoleHandoffContracts() {
80919
+ return validatedSoloRoleHandoffContracts;
80920
+ }
80805
80921
  function getSoloHandoffTemplate(query) {
80806
- const getter = SOLO_HANDOFF_TEMPLATES[`${query.fromRole.toLowerCase()}:${query.toRole.toLowerCase()}`];
80922
+ const fromRole = query.fromRole.toLowerCase();
80923
+ const toRole = query.toRole.toLowerCase();
80924
+ const contract = validatedSoloRoleHandoffContracts.find((candidate) => candidate.role.toLowerCase() === fromRole);
80925
+ const getter = contract?.outboundTemplates[toRole];
80807
80926
  return getter?.(query) ?? null;
80808
80927
  }
80809
- var SOLO_HANDOFF_TEMPLATES;
80928
+ var SOLO_ROLE_HANDOFF_CONTRACTS, validatedSoloRoleHandoffContracts;
80810
80929
  var init_handoff_templates3 = __esm(() => {
80811
- init_solo_to_user();
80812
- init_handoff_templates();
80813
- SOLO_HANDOFF_TEMPLATES = {
80814
- "solo:enhancer": () => getEntryPointToEnhancerHandoffTemplate("solo"),
80815
- "enhancer:solo": () => getEnhancerToEntryPointHandoffTemplate("solo"),
80816
- "solo:user": (query) => getSoloToUserReportTemplate({
80817
- chatroomId: query.chatroomId,
80818
- role: query.role,
80819
- cliEnvPrefix: query.cliEnvPrefix
80820
- })
80821
- };
80930
+ init_enhancer2();
80931
+ init_solo();
80932
+ SOLO_ROLE_HANDOFF_CONTRACTS = [
80933
+ soloHandoffContract,
80934
+ soloEnhancerHandoffContract
80935
+ ];
80936
+ validatedSoloRoleHandoffContracts = (() => {
80937
+ validateRoleHandoffContracts(SOLO_ROLE_HANDOFF_CONTRACTS);
80938
+ return SOLO_ROLE_HANDOFF_CONTRACTS;
80939
+ })();
80822
80940
  });
80823
80941
 
80824
80942
  // ../../services/backend/prompts/cli/handoff-templates/index.ts
80943
+ function resolveTeamContracts(teamId) {
80944
+ const team = (teamId ?? "duo").toLowerCase();
80945
+ if (team === "duo")
80946
+ return listDuoRoleHandoffContracts();
80947
+ if (team === "solo")
80948
+ return listSoloRoleHandoffContracts();
80949
+ return null;
80950
+ }
80951
+ function listHandoffTemplates(query) {
80952
+ const teamId = (query.teamId ?? "duo").toLowerCase();
80953
+ const contracts = resolveTeamContracts(teamId);
80954
+ if (!contracts)
80955
+ return null;
80956
+ const contract = contracts.find((candidate) => candidate.role.toLowerCase() === query.role.toLowerCase());
80957
+ if (!contract)
80958
+ return null;
80959
+ const templates = [];
80960
+ for (const toRole of Object.keys(contract.outboundTemplates).sort()) {
80961
+ const getter = contract.outboundTemplates[toRole];
80962
+ const template = getter({
80963
+ fromRole: contract.role,
80964
+ toRole,
80965
+ teamId,
80966
+ nativeIntegration: query.nativeIntegration,
80967
+ chatroomId: query.chatroomId,
80968
+ role: contract.role,
80969
+ cliEnvPrefix: query.cliEnvPrefix,
80970
+ conversationMode: query.conversationMode
80971
+ });
80972
+ if (!template)
80973
+ continue;
80974
+ templates.push({ fromRole: contract.role, toRole, template });
80975
+ }
80976
+ return {
80977
+ teamId,
80978
+ role: contract.role,
80979
+ receivesFrom: [...contract.receivesFrom],
80980
+ returnsTo: [...contract.returnsTo],
80981
+ templates
80982
+ };
80983
+ }
80825
80984
  function getHandoffTemplate(query) {
80826
80985
  const team = (query.teamId ?? "duo").toLowerCase();
80827
80986
  if (team === "duo")
@@ -80870,6 +81029,60 @@ var init_view_template3 = __esm(() => {
80870
81029
  init_view_template2();
80871
81030
  });
80872
81031
 
81032
+ // ../../services/backend/prompts/cli/handoff-templates/list-templates.ts
81033
+ function formatHandoffTemplateListing(listing) {
81034
+ const receives = listing.receivesFrom.length ? listing.receivesFrom.map((role) => `\`${role}\``).join(", ") : "(none)";
81035
+ const returns = listing.returnsTo.length ? listing.returnsTo.map((role) => `\`${role}\``).join(", ") : "(none)";
81036
+ const lines = [
81037
+ `Handoff contract for \`${listing.role}\` (team: \`${listing.teamId}\`)`,
81038
+ "",
81039
+ `Receives from: ${receives}`,
81040
+ `Returns to: ${returns}`,
81041
+ "",
81042
+ "Renderable outbound templates:",
81043
+ ...listing.templates.map((template) => `- \`${template.fromRole}\` → \`${template.toRole}\``)
81044
+ ];
81045
+ return lines.join(`
81046
+ `);
81047
+ }
81048
+ function listHandoffTemplatesCommand(params) {
81049
+ const listing = listHandoffTemplates({
81050
+ role: params.role,
81051
+ teamId: params.teamId,
81052
+ cliEnvPrefix: params.cliEnvPrefix
81053
+ });
81054
+ if (!listing) {
81055
+ const teamId = params.teamId ?? "duo";
81056
+ throw new Error(`No handoff contract for role "${params.role}" in team "${teamId}". Known roles: planner, builder, enhancer (duo) or solo, enhancer (solo).`);
81057
+ }
81058
+ return formatHandoffTemplateListing(listing);
81059
+ }
81060
+ var init_list_templates = __esm(() => {
81061
+ init_handoff_templates4();
81062
+ });
81063
+
81064
+ // src/commands/handoff/list-templates.ts
81065
+ var exports_list_templates = {};
81066
+ __export(exports_list_templates, {
81067
+ printHandoffListTemplates: () => printHandoffListTemplates
81068
+ });
81069
+ function printHandoffListTemplates(options) {
81070
+ try {
81071
+ const output = listHandoffTemplatesCommand({
81072
+ role: options.role,
81073
+ teamId: options.teamId,
81074
+ cliEnvPrefix: options.cliEnvPrefix
81075
+ });
81076
+ console.log(output);
81077
+ } catch (err) {
81078
+ console.error(`❌ ${err.message}`);
81079
+ process.exit(1);
81080
+ }
81081
+ }
81082
+ var init_list_templates2 = __esm(() => {
81083
+ init_list_templates();
81084
+ });
81085
+
80873
81086
  // src/utils/serialization/decode/index.ts
80874
81087
  var exports_decode = {};
80875
81088
  __export(exports_decode, {
@@ -81160,20 +81373,8 @@ var init_commands_reference = __esm(() => {
81160
81373
  init_command3();
81161
81374
  init_utils3();
81162
81375
  });
81163
-
81164
- // ../../services/backend/prompts/cli/roles/builder.ts
81165
- var init_builder = () => {};
81166
-
81167
- // ../../services/backend/prompts/enhancer/history-retrieval.ts
81168
- var init_history_retrieval = __esm(() => {
81169
- init_guidance();
81170
- });
81171
-
81172
- // ../../services/backend/prompts/cli/roles/enhancer.ts
81173
- var init_enhancer = __esm(() => {
81174
- init_history_retrieval();
81175
- init_env();
81176
- });
81376
+ // ../../services/backend/prompts/cli/sections/core-responsibilities.ts
81377
+ var init_core_responsibilities = () => {};
81177
81378
  // ../../services/backend/prompts/cli/sections/handoff-rules.ts
81178
81379
  var init_handoff_rules = () => {};
81179
81380
  // ../../services/backend/prompts/cli/sections/proof-of-verification.ts
@@ -81184,13 +81385,31 @@ var init_operating_model = () => {};
81184
81385
 
81185
81386
  // ../../services/backend/prompts/cli/sections/index.ts
81186
81387
  var init_sections = __esm(() => {
81388
+ init_core_responsibilities();
81187
81389
  init_handoff_rules();
81188
81390
  init_proof_of_verification();
81189
81391
  init_operating_model();
81190
81392
  });
81191
81393
 
81394
+ // ../../services/backend/prompts/cli/roles/builder.ts
81395
+ var init_builder2 = __esm(() => {
81396
+ init_sections();
81397
+ });
81398
+
81399
+ // ../../services/backend/prompts/enhancer/history-retrieval.ts
81400
+ var init_history_retrieval = __esm(() => {
81401
+ init_guidance();
81402
+ });
81403
+
81404
+ // ../../services/backend/prompts/cli/roles/enhancer.ts
81405
+ var init_enhancer3 = __esm(() => {
81406
+ init_history_retrieval();
81407
+ init_env();
81408
+ init_sections();
81409
+ });
81410
+
81192
81411
  // ../../services/backend/prompts/cli/roles/planner.ts
81193
- var init_planner = __esm(() => {
81412
+ var init_planner2 = __esm(() => {
81194
81413
  init_env();
81195
81414
  init_sections();
81196
81415
  });
@@ -81201,39 +81420,39 @@ var init_planner_guidance_context = __esm(() => {
81201
81420
  });
81202
81421
 
81203
81422
  // ../../services/backend/prompts/teams/solo/prompts/solo.ts
81204
- var init_solo = __esm(() => {
81423
+ var init_solo2 = __esm(() => {
81205
81424
  init_planner_guidance_context();
81206
81425
  init_sections();
81207
81426
  });
81208
81427
 
81209
81428
  // ../../services/backend/prompts/cli/roles/fromContext.ts
81210
81429
  var init_fromContext = __esm(() => {
81211
- init_builder();
81212
- init_enhancer();
81213
- init_planner();
81214
- init_solo();
81430
+ init_builder2();
81431
+ init_enhancer3();
81432
+ init_planner2();
81433
+ init_solo2();
81215
81434
  });
81216
81435
 
81217
81436
  // ../../services/backend/prompts/teams/duo/prompts/builder.ts
81218
- var init_builder2 = __esm(() => {
81219
- init_builder();
81437
+ var init_builder3 = __esm(() => {
81438
+ init_builder2();
81220
81439
  });
81221
81440
 
81222
81441
  // ../../services/backend/prompts/teams/duo/prompts/planner.ts
81223
- var init_planner2 = __esm(() => {
81442
+ var init_planner3 = __esm(() => {
81224
81443
  init_planner_guidance_context();
81225
81444
  init_sections();
81226
81445
  });
81227
81446
 
81228
81447
  // ../../services/backend/prompts/teams/duo/prompts/fromContext.ts
81229
81448
  var init_fromContext2 = __esm(() => {
81230
- init_builder2();
81231
- init_planner2();
81449
+ init_builder3();
81450
+ init_planner3();
81232
81451
  });
81233
81452
 
81234
81453
  // ../../services/backend/prompts/teams/solo/prompts/fromContext.ts
81235
81454
  var init_fromContext3 = __esm(() => {
81236
- init_solo();
81455
+ init_solo2();
81237
81456
  });
81238
81457
  // ../../services/backend/prompts/selector-context.ts
81239
81458
  var init_selector_context = __esm(() => {
@@ -85582,7 +85801,6 @@ var init_agent2 = __esm(() => {
85582
85801
  "platform.pending_task_wake",
85583
85802
  "platform.crash_recovery",
85584
85803
  "platform.auto_restart_on_new_context",
85585
- "platform.restart_offline_on_user_message",
85586
85804
  "platform.team_switch",
85587
85805
  "test"
85588
85806
  ];
@@ -85699,7 +85917,7 @@ var AgentLifecycleOutboxService, AgentLifecycleOutboxServiceLive = (registry2, m
85699
85917
  recover: () => exports_Effect.promise(() => mgr.recover()),
85700
85918
  getSlot: (chatroomId, role) => mgr.getSlot(chatroomId, role),
85701
85919
  listActive: () => mgr.listActive(),
85702
- clearStuckStoppingSlot: (chatroomId, role) => exports_Effect.promise(() => mgr.clearStuckStoppingSlot(chatroomId, role)),
85920
+ clearStuckStoppingSlot: (chatroomId, role, options) => exports_Effect.promise(() => mgr.clearStuckStoppingSlot(chatroomId, role, options)),
85703
85921
  whenTurnEndsIdle: () => exports_Effect.promise(() => mgr.whenTurnEndsIdle()),
85704
85922
  resumeTurnForSlot: (args2) => exports_Effect.promise(() => mgr.resumeTurnForSlot(args2)),
85705
85923
  setLastInFlightTask: (chatroomId, role, taskId) => exports_Effect.sync(() => mgr.setLastInFlightTask(chatroomId, role, taskId)),
@@ -100874,7 +101092,8 @@ var init_assigned_task_snapshot_contract = __esm(() => {
100874
101092
  createdAt: exports_external.number(),
100875
101093
  workingDir: exports_external.string().optional(),
100876
101094
  assignedTo: exports_external.string().optional(),
100877
- sessionAugmentation: sessionAugmentationSchema.optional()
101095
+ sessionAugmentation: sessionAugmentationSchema.optional(),
101096
+ requestsNativeColdSession: exports_external.boolean().optional()
100878
101097
  };
100879
101098
  assignedTaskSignalSchema = exports_external.object(assignedTaskSignalBootstrapFields);
100880
101099
  assignedTaskPresenceSignalSchema = exports_external.object({
@@ -100899,7 +101118,8 @@ var init_assigned_task_snapshot_contract = __esm(() => {
100899
101118
  updatedAt: exports_external.number(),
100900
101119
  createdAt: exports_external.number(),
100901
101120
  agentConfig: assignedTaskAgentConfigSchema,
100902
- participant: assignedTaskParticipantSchema.optional()
101121
+ participant: assignedTaskParticipantSchema.optional(),
101122
+ requestsNativeColdSession: exports_external.boolean().optional()
100903
101123
  }).transform((row) => ({
100904
101124
  ...row,
100905
101125
  assignedTo: row.assignedTo
@@ -100916,30 +101136,44 @@ class NativeDeliveryLedger {
100916
101136
  isDelivered(taskId, harnessSessionId) {
100917
101137
  return this.delivered.has(this.deliveryKey(taskId, harnessSessionId));
100918
101138
  }
100919
- tryAcquire(taskId, harnessSessionId) {
100920
- const key = this.deliveryKey(taskId, harnessSessionId);
100921
- if (this.delivered.has(key) || this.inFlight.has(key)) {
101139
+ isAttemptInFlight(taskId) {
101140
+ return this.inFlight.has(taskId);
101141
+ }
101142
+ tryAcquire(taskId, existingSessionId) {
101143
+ if (this.inFlight.has(taskId)) {
100922
101144
  return false;
100923
101145
  }
100924
- this.inFlight.add(key);
101146
+ if (existingSessionId && this.delivered.has(this.deliveryKey(taskId, existingSessionId))) {
101147
+ return false;
101148
+ }
101149
+ this.inFlight.add(taskId);
100925
101150
  return true;
100926
101151
  }
101152
+ releaseAttempt(taskId) {
101153
+ this.inFlight.delete(taskId);
101154
+ }
100927
101155
  markDelivered(taskId, harnessSessionId) {
100928
- const key = this.deliveryKey(taskId, harnessSessionId);
100929
- this.inFlight.delete(key);
100930
- this.delivered.add(key);
101156
+ this.inFlight.delete(taskId);
101157
+ this.delivered.add(this.deliveryKey(taskId, harnessSessionId));
100931
101158
  }
100932
101159
  clearDelivery(taskId, harnessSessionId) {
100933
- const key = this.deliveryKey(taskId, harnessSessionId);
100934
- this.inFlight.delete(key);
100935
- this.delivered.delete(key);
101160
+ this.inFlight.delete(taskId);
101161
+ if (harnessSessionId) {
101162
+ this.delivered.delete(this.deliveryKey(taskId, harnessSessionId));
101163
+ } else {
101164
+ const prefix = `${taskId}\x00`;
101165
+ for (const key of [...this.delivered]) {
101166
+ if (key.startsWith(prefix)) {
101167
+ this.delivered.delete(key);
101168
+ }
101169
+ }
101170
+ }
100936
101171
  }
100937
101172
  clearSession(harnessSessionId) {
100938
101173
  const suffix = `\x00${harnessSessionId}`;
100939
- for (const key of [...this.delivered, ...this.inFlight]) {
101174
+ for (const key of [...this.delivered]) {
100940
101175
  if (key.endsWith(suffix)) {
100941
101176
  this.delivered.delete(key);
100942
- this.inFlight.delete(key);
100943
101177
  }
100944
101178
  }
100945
101179
  }
@@ -100950,10 +101184,31 @@ function getNativeDeliveryLedger() {
100950
101184
  }
100951
101185
  var sharedLedger;
100952
101186
 
101187
+ // src/daemon/domain/usecase/check-agent-slot.ts
101188
+ function isSlotIdle(state) {
101189
+ return state === "idle";
101190
+ }
101191
+ function isSlotSpawning(state) {
101192
+ return state === "spawning";
101193
+ }
101194
+ function isSlotRunning(state) {
101195
+ return state === "running";
101196
+ }
101197
+ function isSlotStopping(state) {
101198
+ return state === "stopping";
101199
+ }
101200
+ function isTurnPhaseIdle(phase) {
101201
+ return phase === "idle";
101202
+ }
101203
+ var init_check_agent_slot = () => {};
101204
+
100953
101205
  // src/daemon/infrastructure/agent-operational/agent-operational-read-model.ts
100954
101206
  function isOperationalDesiredRunning(row) {
100955
101207
  return row?.operationalState === "running" || row?.operationalState === "starting";
100956
101208
  }
101209
+ function isOperationalCircuitOpen(row) {
101210
+ return row?.operationalState === "circuit_open";
101211
+ }
100957
101212
  function isOperationalStopIntentActive(row) {
100958
101213
  return row?.stopState === "stopped" || row?.stopState === "stopping" || row?.stopState === "pending";
100959
101214
  }
@@ -101003,6 +101258,43 @@ class AgentOperationalReadModel {
101003
101258
  }
101004
101259
  var roleKey = (chatroomId, role) => `${chatroomId}:${role.toLowerCase()}`;
101005
101260
 
101261
+ // src/daemon/entry/native-delivery/native-cold-session-delivery.ts
101262
+ function snapshotRequestsNativeColdSession(task) {
101263
+ return task.requestsNativeColdSession === true;
101264
+ }
101265
+ function isColdStartEligibleSlotState(slot) {
101266
+ if (!slot)
101267
+ return true;
101268
+ return isSlotIdle(slot.state);
101269
+ }
101270
+ function isNativeColdSessionDeliveryOwnedSpawn(task, slot) {
101271
+ return snapshotRequestsNativeColdSession(task) && isColdStartEligibleSlotState(slot);
101272
+ }
101273
+ function explainColdSessionDeliveryBlock(task, slot, operational) {
101274
+ if (!snapshotRequestsNativeColdSession(task))
101275
+ return null;
101276
+ if (isChatroomStopScopeActive(task.chatroomId)) {
101277
+ return "chatroom_stop_scope_active";
101278
+ }
101279
+ if (isOperationalStopIntentActive(operational)) {
101280
+ return "operational_stop_intent_active";
101281
+ }
101282
+ if (isOperationalCircuitOpen(operational)) {
101283
+ return "operational_circuit_open";
101284
+ }
101285
+ if (slot && isSlotSpawning(slot.state)) {
101286
+ return `slot_spawning (slotState=${slot.state})`;
101287
+ }
101288
+ if (slot && isSlotStopping(slot.state)) {
101289
+ return `slot_stopping (slotState=${slot.state})`;
101290
+ }
101291
+ return null;
101292
+ }
101293
+ var init_native_cold_session_delivery = __esm(() => {
101294
+ init_check_agent_slot();
101295
+ init_execute_stop_targets_adapter();
101296
+ });
101297
+
101006
101298
  // src/daemon/infrastructure/inbox/task-snapshot-state.ts
101007
101299
  function snapshotKey(taskId, role) {
101008
101300
  return `${taskId}:${role.toLowerCase()}`;
@@ -101075,24 +101367,6 @@ function isDeliverableTaskStatus(status3) {
101075
101367
  }
101076
101368
  var init_assigned_task = () => {};
101077
101369
 
101078
- // src/daemon/domain/usecase/check-agent-slot.ts
101079
- function isSlotIdle(state) {
101080
- return state === "idle";
101081
- }
101082
- function isSlotSpawning(state) {
101083
- return state === "spawning";
101084
- }
101085
- function isSlotRunning(state) {
101086
- return state === "running";
101087
- }
101088
- function isSlotStopping(state) {
101089
- return state === "stopping";
101090
- }
101091
- function isTurnPhaseIdle(phase) {
101092
- return phase === "idle";
101093
- }
101094
- var init_check_agent_slot = () => {};
101095
-
101096
101370
  // src/daemon/entry/native-delivery/native-ready-invariant.ts
101097
101371
  function isAgentReadyForNativeDelivery(task, slot) {
101098
101372
  return explainAgentReadyForNativeDeliveryBlock(task, slot) === null;
@@ -101103,6 +101377,13 @@ function explainAgentReadyForNativeDeliveryBlock(task, slot) {
101103
101377
  return `not_native_harness (harness=${agentConfig.agentHarness})`;
101104
101378
  }
101105
101379
  const operational = getNativeDeliverySession()?.agentOperationalReadModel?.get(task.chatroomId, agentConfig.role);
101380
+ const coldBlock = explainColdSessionDeliveryBlock(task, slot, operational);
101381
+ if (coldBlock) {
101382
+ return coldBlock;
101383
+ }
101384
+ if (isNativeColdSessionDeliveryOwnedSpawn(task, slot)) {
101385
+ return null;
101386
+ }
101106
101387
  if (!isOperationalDesiredRunning(operational)) {
101107
101388
  return `operational_state_not_running (state=${operational?.operationalState ?? "missing"})`;
101108
101389
  }
@@ -101132,6 +101413,7 @@ function isDeliverableNativeTaskStatus(status3) {
101132
101413
  }
101133
101414
  var init_native_ready_invariant = __esm(() => {
101134
101415
  init_types();
101416
+ init_native_cold_session_delivery();
101135
101417
  init_native_delivery_session_registry();
101136
101418
  init_assigned_task();
101137
101419
  init_check_agent_slot();
@@ -101226,7 +101508,10 @@ function explainInFlightDeliveryBlock(task, slot) {
101226
101508
  return null;
101227
101509
  }
101228
101510
  function explainLedgerDeliveryBlock(taskId, harnessSessionId, ledger) {
101229
- if (ledger.isDelivered(taskId, harnessSessionId)) {
101511
+ if (ledger.isAttemptInFlight(taskId)) {
101512
+ return "delivery_ledger_busy (duplicate inject in flight)";
101513
+ }
101514
+ if (harnessSessionId && ledger.isDelivered(taskId, harnessSessionId)) {
101230
101515
  return "already_delivered_this_session";
101231
101516
  }
101232
101517
  return null;
@@ -101247,6 +101532,120 @@ var init_native_task_injector_logic = __esm(() => {
101247
101532
  };
101248
101533
  });
101249
101534
 
101535
+ // ../shared/src/domain/conversation-mode.ts
101536
+ function legacyConversationMode(plannerEnhancerEnabled) {
101537
+ return plannerEnhancerEnabled ? "code:enhanced" : "code";
101538
+ }
101539
+ var CONVERSATION_MODES;
101540
+ var init_conversation_mode = __esm(() => {
101541
+ CONVERSATION_MODES = ["chat", "code", "code:enhanced"];
101542
+ });
101543
+
101544
+ // ../shared/src/domain/task-envelope.ts
101545
+ function isRecord(value) {
101546
+ return typeof value === "object" && value !== null && !Array.isArray(value);
101547
+ }
101548
+ function isConversationMode(value) {
101549
+ return CONVERSATION_MODES.includes(value);
101550
+ }
101551
+ function isSessionPolicy(value) {
101552
+ return TASK_SESSION_POLICIES.includes(value);
101553
+ }
101554
+ function isHandoffPreset(value) {
101555
+ return HANDOFF_WORKFLOW_PRESETS.includes(value);
101556
+ }
101557
+ function isHandoffPhase(value) {
101558
+ return HANDOFF_WORKFLOW_PHASES.includes(value);
101559
+ }
101560
+ function assertConversationMode(value, origin2) {
101561
+ if (!isConversationMode(value)) {
101562
+ throw new TypeError(`taskEnvelope: invalid conversationMode ${JSON.stringify(value)} in ${origin2}`);
101563
+ }
101564
+ }
101565
+ function workflowPresetForMode(mode) {
101566
+ return MODE_DEFAULT_PRESET[mode];
101567
+ }
101568
+ function buildTaskEnvelope(conversationMode, sessionPolicy) {
101569
+ return {
101570
+ version: TASK_ENVELOPE_VERSION,
101571
+ conversationMode,
101572
+ sessionPolicy,
101573
+ handoffWorkflow: {
101574
+ preset: workflowPresetForMode(conversationMode),
101575
+ phase: "entry"
101576
+ }
101577
+ };
101578
+ }
101579
+ function copyTaskEnvelope(envelope) {
101580
+ return {
101581
+ version: TASK_ENVELOPE_VERSION,
101582
+ conversationMode: envelope.conversationMode,
101583
+ sessionPolicy: envelope.sessionPolicy,
101584
+ handoffWorkflow: {
101585
+ preset: envelope.handoffWorkflow.preset,
101586
+ phase: envelope.handoffWorkflow.phase
101587
+ }
101588
+ };
101589
+ }
101590
+ function isEnvelopeRecordAndVersion(value) {
101591
+ return isRecord(value) && value.version === TASK_ENVELOPE_VERSION;
101592
+ }
101593
+ function isWorkflowShape(workflow) {
101594
+ return isRecord(workflow) && isHandoffPreset(workflow.preset) && isHandoffPhase(workflow.phase);
101595
+ }
101596
+ function isPresetChoice(workflow, mode) {
101597
+ return workflow.preset === workflowPresetForMode(mode);
101598
+ }
101599
+ function isEnvelopeWorkflowValid(value, mode) {
101600
+ return isWorkflowShape(value.handoffWorkflow) && isPresetChoice(value.handoffWorkflow, mode);
101601
+ }
101602
+ function isTaskEnvelopeV1(value) {
101603
+ if (!isEnvelopeRecordAndVersion(value))
101604
+ return false;
101605
+ if (!isConversationMode(value.conversationMode))
101606
+ return false;
101607
+ if (!isSessionPolicy(value.sessionPolicy))
101608
+ return false;
101609
+ return isEnvelopeWorkflowValid(value, value.conversationMode);
101610
+ }
101611
+ function deriveLegacyMode(input) {
101612
+ const rawMode = input.conversationMode;
101613
+ if (rawMode !== undefined) {
101614
+ assertConversationMode(rawMode, "normalizeTaskEnvelope");
101615
+ return rawMode;
101616
+ }
101617
+ return legacyConversationMode(input.plannerEnhancerEnabled);
101618
+ }
101619
+ function deriveLegacySession(startInNewSession) {
101620
+ return startInNewSession === true ? "new" : "continue";
101621
+ }
101622
+ function normalizeTaskEnvelope(input) {
101623
+ if (input.taskEnvelope !== undefined) {
101624
+ if (!isTaskEnvelopeV1(input.taskEnvelope)) {
101625
+ throw new TypeError("taskEnvelope: invalid explicit TaskEnvelopeV1 value");
101626
+ }
101627
+ return copyTaskEnvelope(input.taskEnvelope);
101628
+ }
101629
+ return buildTaskEnvelope(deriveLegacyMode(input), deriveLegacySession(input.startInNewSession));
101630
+ }
101631
+ var TASK_ENVELOPE_VERSION = 1, HANDOFF_WORKFLOW_PRESETS, HANDOFF_WORKFLOW_PHASES, TASK_SESSION_POLICIES, MODE_DEFAULT_PRESET;
101632
+ var init_task_envelope = __esm(() => {
101633
+ init_conversation_mode();
101634
+ HANDOFF_WORKFLOW_PRESETS = ["direct", "team", "enhanced-team"];
101635
+ HANDOFF_WORKFLOW_PHASES = [
101636
+ "entry",
101637
+ "enhancement",
101638
+ "implementation",
101639
+ "delivery"
101640
+ ];
101641
+ TASK_SESSION_POLICIES = ["continue", "new"];
101642
+ MODE_DEFAULT_PRESET = {
101643
+ chat: "direct",
101644
+ code: "team",
101645
+ "code:enhanced": "enhanced-team"
101646
+ };
101647
+ });
101648
+
101250
101649
  // ../../services/backend/src/domain/entities/team-agent-settings.ts
101251
101650
  function roleSupportsSessionAugmentation(role) {
101252
101651
  const normalized = role.toLowerCase();
@@ -101259,10 +101658,21 @@ var init_team_agent_settings = __esm(() => {
101259
101658
 
101260
101659
  // ../../services/backend/src/domain/handoff/parse-session-augmentation.ts
101261
101660
  function resolveSessionAugmentationForTask(task, role) {
101262
- if (task.startInNewSession !== undefined)
101661
+ if (task.taskEnvelope !== undefined) {
101662
+ const envelope = normalizeTaskEnvelope({ taskEnvelope: task.taskEnvelope });
101663
+ return envelope.sessionPolicy === "new" ? "new_session" : "none";
101664
+ }
101665
+ if (task.startInNewSession !== undefined) {
101263
101666
  return task.startInNewSession ? "new_session" : "none";
101667
+ }
101264
101668
  return resolveSessionAugmentationForRole(role);
101265
101669
  }
101670
+ function taskRequestsNativeColdSession(task) {
101671
+ if (task.taskEnvelope !== undefined) {
101672
+ return normalizeTaskEnvelope({ taskEnvelope: task.taskEnvelope }).sessionPolicy === "new";
101673
+ }
101674
+ return task.startInNewSession === true;
101675
+ }
101266
101676
  function shouldEmitSessionAugmentation(role, mode) {
101267
101677
  return roleSupportsSessionAugmentation(role) || mode === "new_session";
101268
101678
  }
@@ -101278,6 +101688,7 @@ function sessionAugmentationNewSessionStarted(mode) {
101278
101688
  return mode === "new_session";
101279
101689
  }
101280
101690
  var init_parse_session_augmentation = __esm(() => {
101691
+ init_task_envelope();
101281
101692
  init_team_agent_settings();
101282
101693
  });
101283
101694
 
@@ -101296,17 +101707,31 @@ async function waitForHarnessSessionId(agentMgr, chatroomId, role) {
101296
101707
  return null;
101297
101708
  }
101298
101709
  async function ensureColdSessionBeforeNativeInject(task, deps) {
101299
- if (!task.startInNewSession)
101710
+ if (!taskRequestsNativeColdSession({
101711
+ content: task.taskContent ?? "",
101712
+ taskEnvelope: task.taskEnvelope,
101713
+ startInNewSession: task.startInNewSession
101714
+ })) {
101300
101715
  return null;
101716
+ }
101301
101717
  const { chatroomId, agentConfig, taskId } = task;
101302
101718
  const { role, agentHarness, model, workingDir } = agentConfig;
101303
101719
  if (!workingDir || !model)
101304
101720
  return null;
101305
- await deps.agentMgr.stop({
101306
- chatroomId,
101307
- role,
101308
- reason: AgentStopReasonEnum["platform.task_start_in_new_session"]
101309
- });
101721
+ const slot = deps.agentMgr.getSlot(chatroomId, role);
101722
+ const slotState = slot?.state;
101723
+ if (slotState === "spawning" || slotState === "stopping") {
101724
+ return null;
101725
+ }
101726
+ if (slotState === "running") {
101727
+ const stopped = await deps.agentMgr.stop({
101728
+ chatroomId,
101729
+ role,
101730
+ reason: AgentStopReasonEnum["platform.task_start_in_new_session"]
101731
+ });
101732
+ if (!stopped?.success)
101733
+ return null;
101734
+ }
101310
101735
  const spawn3 = await deps.agentMgr.ensureRunning({
101311
101736
  chatroomId,
101312
101737
  role,
@@ -101355,7 +101780,7 @@ async function ensureColdSessionBeforeNativeInject(task, deps) {
101355
101780
  var init_native_cold_session_before_inject = __esm(() => {
101356
101781
  init_reliability();
101357
101782
  init_agent2();
101358
- init_participant();
101783
+ init_parse_session_augmentation();
101359
101784
  init_api3();
101360
101785
  });
101361
101786
 
@@ -101427,12 +101852,28 @@ function claimPendingTaskIfNeeded(task, deps) {
101427
101852
  }
101428
101853
  });
101429
101854
  }
101855
+ function resolveHarnessSessionPolicy(task, initialHarnessSessionId) {
101856
+ if (!taskRequestsNativeColdSession({
101857
+ content: task.taskContent ?? "",
101858
+ taskEnvelope: task.taskEnvelope,
101859
+ startInNewSession: task.startInNewSession
101860
+ })) {
101861
+ if (!initialHarnessSessionId)
101862
+ return { kind: "missing" };
101863
+ return { kind: "use-existing", harnessSessionId: initialHarnessSessionId };
101864
+ }
101865
+ return { kind: "cold-start" };
101866
+ }
101430
101867
  function resolveHarnessSessionForInject(task, deps, initialHarnessSessionId) {
101431
101868
  return exports_Effect.gen(function* () {
101432
101869
  const { chatroomId, taskId, agentConfig } = task;
101433
101870
  const { role } = agentConfig;
101434
- if (!task.startInNewSession) {
101435
- return { harnessSessionId: initialHarnessSessionId, sessionAugmentationEmitted: false };
101871
+ const policy = resolveHarnessSessionPolicy(task, initialHarnessSessionId);
101872
+ if (policy.kind === "missing") {
101873
+ return yield* exports_Effect.fail(new Error("harness session missing for continue inject"));
101874
+ }
101875
+ if (policy.kind === "use-existing") {
101876
+ return { harnessSessionId: policy.harnessSessionId, sessionAugmentationEmitted: false };
101436
101877
  }
101437
101878
  const coldSession = yield* applyColdSessionIfRequested(task, deps, chatroomId, role, taskId);
101438
101879
  if ("failed" in coldSession) {
@@ -101478,7 +101919,7 @@ function emitSessionAugmentationIfNeeded(task, deps, harnessSessionId, sessionAu
101478
101919
  catch: (err) => err
101479
101920
  }).pipe(exports_Effect.catchAll(() => exports_Effect.void));
101480
101921
  }
101481
- function resumeHarnessWithPrompt(task, deps, prompt) {
101922
+ function resumeHarnessWithPrompt(task, deps, prompt, harnessSessionId) {
101482
101923
  return exports_Effect.gen(function* () {
101483
101924
  const { chatroomId, taskId, agentConfig } = task;
101484
101925
  const { role } = agentConfig;
@@ -101509,7 +101950,12 @@ function resumeHarnessWithPrompt(task, deps, prompt) {
101509
101950
  }),
101510
101951
  catch: (err) => err
101511
101952
  }).pipe(exports_Effect.catchAll(() => exports_Effect.void));
101512
- deps.onTaskDelivered?.({ chatroomId, role, taskId });
101953
+ deps.onTaskDelivered?.({
101954
+ chatroomId,
101955
+ role,
101956
+ taskId,
101957
+ harnessSessionId
101958
+ });
101513
101959
  });
101514
101960
  }
101515
101961
  function loadNativeInjectionPrompt(task, deps) {
@@ -101535,7 +101981,11 @@ function loadNativeInjectionPrompt(task, deps) {
101535
101981
  });
101536
101982
  return yield* exports_Effect.fail(deliveryResult.left);
101537
101983
  }
101538
- const augmentationMode = resolveSessionAugmentationForTask({ content: taskContent, startInNewSession: task.startInNewSession }, role);
101984
+ const augmentationMode = resolveSessionAugmentationForTask({
101985
+ content: taskContent,
101986
+ taskEnvelope: task.taskEnvelope,
101987
+ startInNewSession: task.startInNewSession
101988
+ }, role);
101539
101989
  return {
101540
101990
  augmentationMode,
101541
101991
  prompt: buildNativeInjectionPrompt({
@@ -101551,7 +102001,12 @@ function injectNativeTaskPrompt(task, deps, harnessSessionId, sessionAugmentatio
101551
102001
  const { role } = agentConfig;
101552
102002
  const { prompt, augmentationMode } = yield* loadNativeInjectionPrompt(task, deps);
101553
102003
  yield* exports_Effect.tryPromise({
101554
- try: () => deps.lifecycleOutbox ? deps.lifecycleOutbox.enqueue(buildActivityLifecycleFact({ chatroomId, role, action: NATIVE_TASK_INJECTED_ACTION, taskId })) : Promise.reject(new Error("lifecycle outbox missing")),
102004
+ try: () => deps.lifecycleOutbox ? deps.lifecycleOutbox.enqueue(buildActivityLifecycleFact({
102005
+ chatroomId,
102006
+ role,
102007
+ action: NATIVE_TASK_INJECTED_ACTION,
102008
+ taskId
102009
+ })) : Promise.reject(new Error("lifecycle outbox missing")),
101555
102010
  catch: (err) => err
101556
102011
  });
101557
102012
  yield* exports_Effect.tryPromise({
@@ -101566,7 +102021,7 @@ function injectNativeTaskPrompt(task, deps, harnessSessionId, sessionAugmentatio
101566
102021
  catch: (err) => err
101567
102022
  });
101568
102023
  yield* emitSessionAugmentationIfNeeded(task, deps, harnessSessionId, sessionAugmentationEmitted, augmentationMode);
101569
- yield* resumeHarnessWithPrompt(task, deps, prompt);
102024
+ yield* resumeHarnessWithPrompt(task, deps, prompt, harnessSessionId);
101570
102025
  });
101571
102026
  }
101572
102027
  function runNativeInjectionEffect(task, initialHarnessSessionId, deps) {
@@ -101577,7 +102032,6 @@ function runNativeInjectionEffect(task, initialHarnessSessionId, deps) {
101577
102032
  });
101578
102033
  }
101579
102034
  var init_native_task_injector = __esm(() => {
101580
- init_participant();
101581
102035
  init_parse_session_augmentation();
101582
102036
  init_esm();
101583
102037
  init_native_cold_session_before_inject();
@@ -101606,13 +102060,15 @@ function mapAssignedTaskSnapshot(row) {
101606
102060
  circuitState: row.agentConfig.circuitState,
101607
102061
  configLifecycleRevision: row.agentConfig.configLifecycleRevision
101608
102062
  },
101609
- participant: row.participant
102063
+ participant: row.participant,
102064
+ requestsNativeColdSession: row.requestsNativeColdSession
101610
102065
  };
101611
102066
  }
101612
102067
  function mapAssignedTaskView(row) {
101613
102068
  return {
101614
102069
  ...mapAssignedTaskSnapshot(row),
101615
102070
  taskContent: row.taskContent,
102071
+ taskEnvelope: row.taskEnvelope,
101616
102072
  startInNewSession: row.startInNewSession
101617
102073
  };
101618
102074
  }
@@ -101744,10 +102200,6 @@ class NativeTaskDeliveryCoordinator {
101744
102200
  continue;
101745
102201
  }
101746
102202
  const harnessSessionId = slot?.harnessSessionId;
101747
- if (!harnessSessionId) {
101748
- logNativeDeliverySkip(role, row.chatroomId, row.taskId, "harness_session_missing (pre-gate)");
101749
- continue;
101750
- }
101751
102203
  const ledgerBlock = explainLedgerDeliveryBlock(row.taskId, harnessSessionId, ledger);
101752
102204
  if (ledgerBlock) {
101753
102205
  logNativeDeliverySkip(role, row.chatroomId, row.taskId, ledgerBlock);
@@ -101758,7 +102210,7 @@ class NativeTaskDeliveryCoordinator {
101758
102210
  continue;
101759
102211
  }
101760
102212
  if (!deliveryState.tryAcquireDelivery(row.chatroomId, role)) {
101761
- ledger.clearDelivery(row.taskId, harnessSessionId);
102213
+ ledger.releaseAttempt(row.taskId);
101762
102214
  logNativeDeliveryMutexSkip(role, row.chatroomId, row.taskId);
101763
102215
  continue;
101764
102216
  }
@@ -101793,9 +102245,14 @@ class NativeTaskDeliveryCoordinator {
101793
102245
  getSlot: (chatroomId, role2) => agentMgr.getSlot(chatroomId, role2)
101794
102246
  },
101795
102247
  convexUrl: sessionDeps.convexUrl,
101796
- onTaskDelivered: ({ chatroomId, role: role2, taskId: deliveredTaskId }) => {
102248
+ onTaskDelivered: ({
102249
+ chatroomId,
102250
+ role: role2,
102251
+ taskId: deliveredTaskId,
102252
+ harnessSessionId: resolvedSessionId
102253
+ }) => {
101797
102254
  deliveredToHarness = true;
101798
- ledger.markDelivered(deliveredTaskId, harnessSessionId);
102255
+ ledger.markDelivered(deliveredTaskId, resolvedSessionId);
101799
102256
  exports_Effect.runSync(agentMgr.setLastInFlightTask(chatroomId, role2, deliveredTaskId));
101800
102257
  deliveryState.clearNativeNudgeFailures(chatroomId, role2);
101801
102258
  }
@@ -101803,7 +102260,7 @@ class NativeTaskDeliveryCoordinator {
101803
102260
  }).pipe(exports_Effect.provide(effectContext2), exports_Effect.catchAll((err) => exports_Effect.sync(() => console.warn(`[NativeTaskDelivery] delivery failed for ${row.agentConfig.role}@${row.chatroomId}: ${getErrorMessage(err)}`))), exports_Effect.ensuring(exports_Effect.sync(() => {
101804
102261
  deliveryState.releaseDelivery(row.chatroomId, row.agentConfig.role);
101805
102262
  if (!deliveredToHarness) {
101806
- ledger.clearDelivery(taskId, harnessSessionId);
102263
+ ledger.releaseAttempt(taskId);
101807
102264
  }
101808
102265
  }))));
101809
102266
  break;
@@ -101976,9 +102433,9 @@ async function deliverOneTask(deps, event, snapshot) {
101976
102433
  ensureRunning: (opts) => exports_Effect.runPromise(deps.agentMgr.ensureRunning(opts)),
101977
102434
  getSlot: (chatroomId, role) => deps.agentMgr.getSlot(chatroomId, role)
101978
102435
  },
101979
- onTaskDelivered: ({ chatroomId, role, taskId }) => {
102436
+ onTaskDelivered: ({ chatroomId, role, taskId, harnessSessionId: resolvedSessionId }) => {
101980
102437
  deliveredToHarness = true;
101981
- ledger.markDelivered(taskId, harnessSessionId);
102438
+ ledger.markDelivered(taskId, resolvedSessionId);
101982
102439
  deps.agentMgr.setLastInFlightTask(chatroomId, role, taskId);
101983
102440
  }
101984
102441
  }));
@@ -101988,7 +102445,7 @@ async function deliverOneTask(deps, event, snapshot) {
101988
102445
  return false;
101989
102446
  } finally {
101990
102447
  if (!deliveredToHarness) {
101991
- ledger.clearDelivery(snapshot.taskId, harnessSessionId);
102448
+ ledger.releaseAttempt(snapshot.taskId);
101992
102449
  }
101993
102450
  }
101994
102451
  }
@@ -102057,7 +102514,6 @@ async function runRestartOrchestrator(deps, event) {
102057
102514
  }
102058
102515
  var init_restart_orchestrator = __esm(() => {
102059
102516
  init_reliability();
102060
- init_participant();
102061
102517
  init_build_agent_restart_event();
102062
102518
  init_assigned_task_snapshot_contract();
102063
102519
  init_esm();
@@ -103499,7 +103955,6 @@ function wireTokenActivityReporting(opts) {
103499
103955
  var NATIVE_TOKEN_ACTIVITY_THROTTLE_MS = 30000;
103500
103956
  var init_native_spawn_presence = __esm(() => {
103501
103957
  init_types();
103502
- init_participant();
103503
103958
  init_api3();
103504
103959
  init_execution_kind();
103505
103960
  });
@@ -104322,7 +104777,7 @@ class AgentProcessManager {
104322
104777
  }
104323
104778
  return result;
104324
104779
  }
104325
- async clearStuckStoppingSlot(chatroomId, role) {
104780
+ async clearStuckStoppingSlot(chatroomId, role, options) {
104326
104781
  const key = agentKey3(chatroomId, role);
104327
104782
  const slot = this.slots.get(key);
104328
104783
  if (!slot || slot.state !== "stopping") {
@@ -104332,7 +104787,7 @@ class AgentProcessManager {
104332
104787
  if (elapsed3 < STOPPING_TIMEOUT_MS) {
104333
104788
  return false;
104334
104789
  }
104335
- await this.forceClearStuckStoppingSlot(key, slot, chatroomId, role, "daemon.stop_timeout");
104790
+ await this.forceClearStuckStoppingSlot(key, slot, chatroomId, role, "daemon.stop_timeout", options?.clearStopIntent);
104336
104791
  console.warn(`[AgentProcessManager] ⚠️ Cleared stuck stopping slot for ${role}@${chatroomId}`);
104337
104792
  return true;
104338
104793
  }
@@ -105160,7 +105615,7 @@ class AgentProcessManager {
105160
105615
  slot.pendingOperation = undefined;
105161
105616
  slot.stoppingSince = undefined;
105162
105617
  }
105163
- async forceClearStuckStoppingSlot(key, slot, chatroomId, role, reason) {
105618
+ async forceClearStuckStoppingSlot(key, slot, chatroomId, role, reason, clearStopIntent = false) {
105164
105619
  const pid = slot.pid;
105165
105620
  const harness = slot.harness;
105166
105621
  const stopCommandId = slot.stopCommandId;
@@ -105168,6 +105623,9 @@ class AgentProcessManager {
105168
105623
  const durationMs = slot.stoppingSince ? this.deps.clock.now() - slot.stoppingSince : STOPPING_TIMEOUT_MS;
105169
105624
  this.bumpStopGeneration(slot);
105170
105625
  this.clearSlotRuntimeState(slot);
105626
+ if (clearStopIntent) {
105627
+ this.clearStopIntent(slot);
105628
+ }
105171
105629
  logDaemonAuditEvent(this.deps.logEvent, {
105172
105630
  type: "agent.stopTimeout",
105173
105631
  chatroomId,
@@ -105276,7 +105734,6 @@ var AGENT_EXIT_RETRY_INTERVAL_MS = 1e4, STOPPING_TIMEOUT_MS = 30000;
105276
105734
  var init_agent_process_manager = __esm(() => {
105277
105735
  init_agent2();
105278
105736
  init_types();
105279
- init_participant();
105280
105737
  init_esm();
105281
105738
  init_execute_stop_targets_adapter();
105282
105739
  init_stop_agent_confirmed_adapter();
@@ -117581,9 +118038,57 @@ function isNativeAgentSlotDown(task, health, now = Date.now()) {
117581
118038
  }
117582
118039
  return isSlotUnavailableForPid(slot, pid, health.isPidAlive, now);
117583
118040
  }
117584
- function isNativeActiveTaskAgentDown(task, health, now) {
118041
+ function roleKey4(chatroomId, role) {
118042
+ return `${chatroomId}:${role.toLowerCase()}`;
118043
+ }
118044
+ function isCandidateDeliverableForOwnership(task) {
118045
+ if (!isDeliverableTaskStatus(task.status))
118046
+ return false;
118047
+ if (task.status === "acknowledged") {
118048
+ return task.assignedTo?.toLowerCase() === task.agentConfig.role.toLowerCase();
118049
+ }
118050
+ return true;
118051
+ }
118052
+ function comparePendingFirst(a, b) {
118053
+ const pendingDelta = (a.status === "pending" ? 0 : 1) - (b.status === "pending" ? 0 : 1);
118054
+ return pendingDelta !== 0 ? pendingDelta : a.createdAt - b.createdAt;
118055
+ }
118056
+ function selectNextCandidatePerRole(tasks) {
118057
+ const byRole = new Map;
118058
+ for (const task of tasks) {
118059
+ if (!isCandidateDeliverableForOwnership(task))
118060
+ continue;
118061
+ const key = roleKey4(task.chatroomId, task.agentConfig.role);
118062
+ const list = byRole.get(key) ?? [];
118063
+ list.push(task);
118064
+ byRole.set(key, list);
118065
+ }
118066
+ const selected = new Map;
118067
+ for (const [key, list] of byRole) {
118068
+ const first = [...list].sort(comparePendingFirst)[0];
118069
+ if (first)
118070
+ selected.set(key, first);
118071
+ }
118072
+ return selected;
118073
+ }
118074
+ function selectColdOwnedRoles(tasks, health, now) {
118075
+ const owned = new Set;
118076
+ for (const [key, candidate] of selectNextCandidatePerRole(tasks)) {
118077
+ if (!isNativeHarness(candidate.agentConfig.agentHarness))
118078
+ continue;
118079
+ if (!snapshotRequestsNativeColdSession(candidate))
118080
+ continue;
118081
+ if (!isNativeAgentSlotDown(candidate, health, now))
118082
+ continue;
118083
+ owned.add(key);
118084
+ }
118085
+ return owned;
118086
+ }
118087
+ function isNativeActiveTaskAgentDown(task, health, now, coldOwnedRoles) {
117585
118088
  if (!isNativeHarness(task.agentConfig.agentHarness))
117586
118089
  return false;
118090
+ if (coldOwnedRoles?.has(roleKey4(task.chatroomId, task.agentConfig.role)))
118091
+ return false;
117587
118092
  const op = getNativeDeliverySession()?.agentOperationalReadModel?.get(task.chatroomId, task.agentConfig.role);
117588
118093
  if (!isOperationalDesiredRunning(op))
117589
118094
  return false;
@@ -117592,8 +118097,9 @@ function isNativeActiveTaskAgentDown(task, health, now) {
117592
118097
  return isNativeAgentSlotDown(task, health, now);
117593
118098
  }
117594
118099
  function listNativeTasksNeedingRevive(tasks, health, now, cooldown) {
118100
+ const coldOwnedRoles = selectColdOwnedRoles(tasks, health, now);
117595
118101
  return tasks.filter((task) => {
117596
- if (!isNativeActiveTaskAgentDown(task, health, now))
118102
+ if (!isNativeActiveTaskAgentDown(task, health, now, coldOwnedRoles))
117597
118103
  return false;
117598
118104
  const { chatroomId, agentConfig } = task;
117599
118105
  if (!agentConfig.workingDir)
@@ -117604,23 +118110,35 @@ function listNativeTasksNeedingRevive(tasks, health, now, cooldown) {
117604
118110
  return true;
117605
118111
  });
117606
118112
  }
117607
- function isNativePendingTaskNeedingWake(task) {
118113
+ function isNativePendingTaskNeedingWake(task, coldOwnedRoles) {
117608
118114
  if (!isNativeHarness(task.agentConfig.agentHarness))
117609
118115
  return false;
117610
118116
  if (task.status !== "pending")
117611
118117
  return false;
118118
+ if (snapshotRequestsNativeColdSession(task))
118119
+ return false;
118120
+ if (coldOwnedRoles?.has(roleKey4(task.chatroomId, task.agentConfig.role)))
118121
+ return false;
117612
118122
  if (isChatroomStopScopeActive(task.chatroomId))
117613
118123
  return false;
117614
118124
  const op = getNativeDeliverySession()?.agentOperationalReadModel?.get(task.chatroomId, task.agentConfig.role);
117615
118125
  if (isOperationalDesiredRunning(op))
117616
118126
  return false;
118127
+ if (isOperationalCircuitOpen(op))
118128
+ return false;
117617
118129
  if (isOperationalStopIntentActive(op))
117618
118130
  return false;
117619
118131
  return Boolean(task.agentConfig.workingDir);
117620
118132
  }
117621
118133
  function listNativePendingTasksNeedingWake(tasks, cooldown, now) {
118134
+ const coldOwnedRoles = new Set;
118135
+ for (const [key, candidate] of selectNextCandidatePerRole(tasks)) {
118136
+ if (candidate.status === "pending" && isNativeHarness(candidate.agentConfig.agentHarness) && snapshotRequestsNativeColdSession(candidate)) {
118137
+ coldOwnedRoles.add(key);
118138
+ }
118139
+ }
117622
118140
  return tasks.filter((task) => {
117623
- if (!isNativePendingTaskNeedingWake(task))
118141
+ if (!isNativePendingTaskNeedingWake(task, coldOwnedRoles))
117624
118142
  return false;
117625
118143
  const { chatroomId, agentConfig } = task;
117626
118144
  if (!cooldown.canAttempt(chatroomId, agentConfig.role, "wake", now))
@@ -117647,16 +118165,22 @@ class RecoveryCooldown {
117647
118165
  }
117648
118166
  var RECOVERY_COOLDOWN_MS = 60000;
117649
118167
  var init_task_delivery_logic = __esm(() => {
118168
+ init_assigned_task();
117650
118169
  init_check_agent_slot();
117651
118170
  init_agent_process_manager();
117652
118171
  init_execute_stop_targets_adapter();
118172
+ init_native_cold_session_delivery();
117653
118173
  init_native_delivery_session_registry();
117654
118174
  init_native_task_injector_logic();
117655
118175
  });
117656
118176
 
117657
118177
  // src/daemon/entry/native-delivery/task-delivery-processor.ts
117658
118178
  function resolveTaskWantResume(task) {
117659
- return sessionAugmentationToWantResume(resolveSessionAugmentationForTask({ content: task.taskContent ?? "", startInNewSession: task.startInNewSession }, task.agentConfig.role));
118179
+ return sessionAugmentationToWantResume(resolveSessionAugmentationForTask({
118180
+ content: task.taskContent ?? "",
118181
+ taskEnvelope: task.taskEnvelope,
118182
+ startInNewSession: task.startInNewSession
118183
+ }, task.agentConfig.role));
117660
118184
  }
117661
118185
  function resolveTaskRunnerContextFromFull(task) {
117662
118186
  const { chatroomId, agentConfig } = task;
@@ -117679,7 +118203,7 @@ function runNativeReviveEffect(task, runtime4, effectContext2, agentMgr) {
117679
118203
  const { chatroomId, agentConfig, role, workingDir, wantResume } = ctx;
117680
118204
  console.log(`[TaskMonitor] native revive ${role}@${chatroomId} — backend PID stale or missing locally for pending task ${task.taskId}`);
117681
118205
  exports_Runtime.runFork(runtime4)(exports_Effect.gen(function* () {
117682
- yield* agentMgr.ensureRunning({
118206
+ const result = yield* agentMgr.ensureRunning({
117683
118207
  chatroomId,
117684
118208
  role,
117685
118209
  agentHarness: agentConfig.agentHarness,
@@ -117690,6 +118214,9 @@ function runNativeReviveEffect(task, runtime4, effectContext2, agentMgr) {
117690
118214
  lifecycleRevision: task.agentConfig.configLifecycleRevision,
117691
118215
  taskId: task.taskId
117692
118216
  });
118217
+ if (!result.success) {
118218
+ yield* exports_Effect.sync(() => console.warn(`[TaskMonitor] native revive rejected for ${role}@${chatroomId}: ${result.error ?? "unknown error"}`));
118219
+ }
117693
118220
  }).pipe(exports_Effect.provide(effectContext2), exports_Effect.catchAll((err) => exports_Effect.sync(() => console.warn(`[TaskMonitor] native revive failed for ${role}@${chatroomId}: ${getErrorMessage(err)}`)))));
117694
118221
  }
117695
118222
  function runNativeWakeEffect(task, runtime4, effectContext2, agentMgr) {
@@ -117699,7 +118226,7 @@ function runNativeWakeEffect(task, runtime4, effectContext2, agentMgr) {
117699
118226
  const { chatroomId, agentConfig, role, workingDir, wantResume } = ctx;
117700
118227
  console.log(`[TaskMonitor] native wake ${role}@${chatroomId} — operational_state=stopped with pending task ${task.taskId}`);
117701
118228
  exports_Runtime.runFork(runtime4)(exports_Effect.gen(function* () {
117702
- yield* agentMgr.ensureRunning({
118229
+ const result = yield* agentMgr.ensureRunning({
117703
118230
  chatroomId,
117704
118231
  role,
117705
118232
  agentHarness: agentConfig.agentHarness,
@@ -117710,6 +118237,9 @@ function runNativeWakeEffect(task, runtime4, effectContext2, agentMgr) {
117710
118237
  lifecycleRevision: task.agentConfig.configLifecycleRevision,
117711
118238
  taskId: task.taskId
117712
118239
  });
118240
+ if (!result.success) {
118241
+ yield* exports_Effect.sync(() => console.warn(`[TaskMonitor] native wake rejected for ${role}@${chatroomId}: ${result.error ?? "unknown error"}`));
118242
+ }
117713
118243
  }).pipe(exports_Effect.provide(effectContext2), exports_Effect.catchAll((err) => exports_Effect.sync(() => console.warn(`[TaskMonitor] native wake failed for ${role}@${chatroomId}: ${getErrorMessage(err)}`)))));
117714
118244
  }
117715
118245
  async function fetchTaskForAction(sessionDeps, machineId, snapshotRow) {
@@ -117721,17 +118251,30 @@ async function fetchTaskForAction(sessionDeps, machineId, snapshotRow) {
117721
118251
  });
117722
118252
  return result ? mapAssignedTaskView(result) : null;
117723
118253
  }
117724
- async function clearStuckStoppingSlotIfNeeded(agentMgr, chatroomId, role) {
117725
- const cleared = await agentMgr.clearStuckStoppingSlot(chatroomId, role);
118254
+ async function clearStuckStoppingSlotIfNeeded(agentMgr, chatroomId, role, clearStopIntent) {
118255
+ const cleared = await agentMgr.clearStuckStoppingSlot(chatroomId, role, {
118256
+ clearStopIntent
118257
+ });
117726
118258
  if (cleared) {
117727
118259
  console.log(`[TaskMonitor] cleared stuck stopping slot for ${role}@${chatroomId}`);
117728
118260
  }
117729
118261
  }
118262
+ async function normalizeStuckStoppingSlots(tasks, agentMgr) {
118263
+ const seen = new Set;
118264
+ for (const row of tasks) {
118265
+ const key = `${row.chatroomId}:${row.agentConfig.role.toLowerCase()}`;
118266
+ if (seen.has(key))
118267
+ continue;
118268
+ seen.add(key);
118269
+ if (isRestartOrchestratorInFlight(row.chatroomId, row.agentConfig.role))
118270
+ continue;
118271
+ await clearStuckStoppingSlotIfNeeded(agentMgr, row.chatroomId, row.agentConfig.role, row.agentConfig.desiredState === "running");
118272
+ }
118273
+ }
117730
118274
  async function reviveNativeTasks(tasks, localHealth, now, cooldown, runtime4, effectContext2, agentMgr, sessionDeps, machineId) {
117731
118275
  for (const row of listNativeTasksNeedingRevive(tasks, localHealth, now, cooldown)) {
117732
118276
  if (isRestartOrchestratorInFlight(row.chatroomId, row.agentConfig.role))
117733
118277
  continue;
117734
- await clearStuckStoppingSlotIfNeeded(agentMgr, row.chatroomId, row.agentConfig.role);
117735
118278
  const full = await fetchTaskForAction(sessionDeps, machineId, row);
117736
118279
  if (!full)
117737
118280
  continue;
@@ -117742,7 +118285,6 @@ async function wakeStoppedAgentsForPendingTasks(tasks, now, cooldown, runtime4,
117742
118285
  for (const row of listNativePendingTasksNeedingWake(tasks, cooldown, now)) {
117743
118286
  if (isRestartOrchestratorInFlight(row.chatroomId, row.agentConfig.role))
117744
118287
  continue;
117745
- await clearStuckStoppingSlotIfNeeded(agentMgr, row.chatroomId, row.agentConfig.role);
117746
118288
  const full = await fetchTaskForAction(sessionDeps, machineId, row);
117747
118289
  if (!full)
117748
118290
  continue;
@@ -117759,6 +118301,7 @@ async function processTasksUpdate(runtime4, effectContext2, cooldown, agentMgr,
117759
118301
  getSlot: (chatroomId, role) => agentMgr.getSlot(chatroomId, role),
117760
118302
  isPidAlive: (pid) => isProcessAlive((p) => process.kill(p, 0), pid)
117761
118303
  };
118304
+ await normalizeStuckStoppingSlots(filteredTasks, agentMgr);
117762
118305
  await wakeStoppedAgentsForPendingTasks(filteredTasks, now, cooldown, runtime4, effectContext2, agentMgr, sessionDeps, machineId);
117763
118306
  await reviveNativeTasks(filteredTasks, localHealth, now, cooldown, runtime4, effectContext2, agentMgr, sessionDeps, machineId);
117764
118307
  if (filteredTasks.length > 0) {
@@ -135494,16 +136037,50 @@ teamCommand.command("set").description("Set the team preset for a chatroom").req
135494
136037
  const { setTeam: setTeam2 } = await Promise.resolve().then(() => (init_team(), exports_team));
135495
136038
  await setTeam2(options.chatroomId, options.team);
135496
136039
  });
135497
- handoffCommandGroup.command("view-template").description("Print the handoff message template for a role pair").requiredOption("--role <role>", "Your role").requiredOption("--next-role <nextRole>", "Target role for the handoff").option("--team-id <teamId>", "Team id (solo, duo); defaults to duo").action(async (options) => {
136040
+ handoffCommandGroup.command("view-template").description("Print the handoff message template for a role pair").option("--team-id <teamId>", "Team id (solo, duo); defaults to duo").action(async function(options) {
136041
+ const parentOpts = this.parent?.opts() ?? {};
136042
+ if (!parentOpts.role || !parentOpts.nextRole) {
136043
+ console.error(parentOpts.role ? `error: required option '--next-role <nextRole>' not specified` : `error: required option '--role <role>' not specified`);
136044
+ process.exit(1);
136045
+ }
135498
136046
  const { printHandoffViewTemplate: printHandoffViewTemplate2 } = await Promise.resolve().then(() => (init_view_template3(), exports_view_template));
135499
136047
  try {
135500
- printHandoffViewTemplate2(options);
136048
+ printHandoffViewTemplate2({
136049
+ role: parentOpts.role,
136050
+ nextRole: parentOpts.nextRole,
136051
+ teamId: options.teamId
136052
+ });
136053
+ } catch (err) {
136054
+ console.error(`❌ ${err.message}`);
136055
+ process.exit(1);
136056
+ }
136057
+ });
136058
+ handoffCommandGroup.command("list-templates").description("List the role-owned handoff contract and renderable templates (static, no chatroom required)").option("--team-id <teamId>", "Team id (solo, duo); defaults to duo").action(async function(options) {
136059
+ const parentOpts = this.parent?.opts() ?? {};
136060
+ if (!parentOpts.role) {
136061
+ console.error(`error: required option '--role <role>' not specified`);
136062
+ process.exit(1);
136063
+ }
136064
+ const { printHandoffListTemplates: printHandoffListTemplates2 } = await Promise.resolve().then(() => (init_list_templates2(), exports_list_templates));
136065
+ try {
136066
+ printHandoffListTemplates2({ role: parentOpts.role, teamId: options.teamId });
135501
136067
  } catch (err) {
135502
136068
  console.error(`❌ ${err.message}`);
135503
136069
  process.exit(1);
135504
136070
  }
135505
136071
  });
135506
- handoffCommandGroup.requiredOption("--chatroom-id <id>", "Chatroom identifier").requiredOption("--role <role>", "Your role").requiredOption("--next-role <nextRole>", "Role to hand off to").action(async (options) => {
136072
+ handoffCommandGroup.option("--chatroom-id <id>", "Chatroom identifier").option("--role <role>", "Your role").option("--next-role <nextRole>", "Role to hand off to").action(async (options) => {
136073
+ const missing = [
136074
+ ["--chatroom-id", options.chatroomId],
136075
+ ["--role", options.role],
136076
+ ["--next-role", options.nextRole]
136077
+ ].filter(([, value2]) => !value2);
136078
+ if (missing.length > 0) {
136079
+ const [flag] = missing[0];
136080
+ console.error(`error: required option '${flag} <...>' not specified`);
136081
+ process.exit(1);
136082
+ }
136083
+ const { chatroomId, role, nextRole } = options;
135507
136084
  await maybeRequireAuth();
135508
136085
  const { decode: decode6 } = await Promise.resolve().then(() => exports_decode);
135509
136086
  const stdinContent = await readStdin();
@@ -135522,10 +136099,10 @@ handoffCommandGroup.requiredOption("--chatroom-id <id>", "Chatroom identifier").
135522
136099
  process.exit(1);
135523
136100
  }
135524
136101
  const { handoff: handoff2 } = await Promise.resolve().then(() => (init_handoff(), exports_handoff));
135525
- await handoff2(options.chatroomId, {
135526
- role: options.role,
136102
+ await handoff2(chatroomId, {
136103
+ role,
135527
136104
  message,
135528
- nextRole: options.nextRole
136105
+ nextRole
135529
136106
  });
135530
136107
  });
135531
136108
  var agenticQueryCommand = program2.command("agentic-query").description("Agentic search/ask query commands");
@@ -135907,4 +136484,4 @@ program2.hook("preAction", async (_thisCommand, actionCommand) => {
135907
136484
  });
135908
136485
  program2.parse();
135909
136486
 
135910
- //# debugId=FF0641D1EDD955EA64756E2164756E21
136487
+ //# debugId=190F58A249CBBB8164756E2164756E21