@atlasharness/atlascode 0.1.92 → 0.1.93

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli.js +1648 -486
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -742,7 +742,15 @@ var init_fs_operations = __esm(() => {
742
742
  });
743
743
 
744
744
  // src/shared/debug.ts
745
- function logForDebugging(_message, _options) {}
745
+ function setDebugSink(sink) {
746
+ _sink = sink;
747
+ }
748
+ function logForDebugging(message, options) {
749
+ if (_sink !== null) {
750
+ _sink(message, options);
751
+ }
752
+ }
753
+ var _sink = null;
746
754
 
747
755
  // src/shared/platform.ts
748
756
  function memoizeNoArg(fn) {
@@ -1017,6 +1025,89 @@ var init_pdfReference = __esm(() => {
1017
1025
  };
1018
1026
  });
1019
1027
 
1028
+ // src/shared/agentSwarmsEnabled.ts
1029
+ function isAgentTeamsFlagSet() {
1030
+ return process.argv.includes("--agent-teams");
1031
+ }
1032
+ function isAgentSwarmsEnabled() {
1033
+ return isEnvTruthy(process.env.ATLAS_EXPERIMENTAL_AGENT_TEAMS) || isAgentTeamsFlagSet();
1034
+ }
1035
+ var init_agentSwarmsEnabled = () => {};
1036
+
1037
+ // src/shared/swarmSchemaFilter.ts
1038
+ function filterSwarmFieldsFromSchema(toolName, schema, swarmEnabled) {
1039
+ if (swarmEnabled)
1040
+ return schema;
1041
+ const fieldsToRemove = SWARM_FIELDS_BY_TOOL[toolName];
1042
+ if (!fieldsToRemove || fieldsToRemove.length === 0)
1043
+ return schema;
1044
+ if (!schema || typeof schema !== "object")
1045
+ return schema;
1046
+ const props = schema.properties;
1047
+ if (!props || typeof props !== "object")
1048
+ return schema;
1049
+ const nextProps = { ...props };
1050
+ for (const f of fieldsToRemove)
1051
+ delete nextProps[f];
1052
+ return { ...schema, properties: nextProps };
1053
+ }
1054
+ var SWARM_FIELDS_BY_TOOL;
1055
+ var init_swarmSchemaFilter = __esm(() => {
1056
+ SWARM_FIELDS_BY_TOOL = {
1057
+ Agent: ["name", "team_name", "mode"],
1058
+ ExitPlanMode: ["launchSwarm", "teammateCount"]
1059
+ };
1060
+ });
1061
+
1062
+ // src/shared/agentRoleTemplates.ts
1063
+ function getAgentRoleTemplate(role) {
1064
+ return roleTemplates.get(role);
1065
+ }
1066
+ function renderTeammatePrompt(parts) {
1067
+ const sections = [];
1068
+ sections.push(`You are the team member "${parts.name}".`);
1069
+ const template = parts.role ? getAgentRoleTemplate(parts.role) : undefined;
1070
+ if (template?.systemPromptFragment) {
1071
+ sections.push(template.systemPromptFragment);
1072
+ }
1073
+ if (parts.role)
1074
+ sections.push(`Role: ${parts.role}`);
1075
+ if (parts.goal)
1076
+ sections.push(`Goal: ${parts.goal}`);
1077
+ if (parts.backstory)
1078
+ sections.push(`Backstory: ${parts.backstory}`);
1079
+ sections.push(parts.prompt);
1080
+ return sections.join(`
1081
+
1082
+ `);
1083
+ }
1084
+ var roleTemplates;
1085
+ var init_agentRoleTemplates = __esm(() => {
1086
+ roleTemplates = new Map;
1087
+ });
1088
+
1089
+ // src/shared/teammateContext.ts
1090
+ import { AsyncLocalStorage } from "async_hooks";
1091
+ function getTeammateContext() {
1092
+ return teammateContextStorage.getStore();
1093
+ }
1094
+ function runWithTeammateContext(context, fn) {
1095
+ return teammateContextStorage.run(context, fn);
1096
+ }
1097
+ function isInProcessTeammate() {
1098
+ return teammateContextStorage.getStore() !== undefined;
1099
+ }
1100
+ function createTeammateContext(config) {
1101
+ return {
1102
+ ...config,
1103
+ isInProcess: true
1104
+ };
1105
+ }
1106
+ var teammateContextStorage;
1107
+ var init_teammateContext = __esm(() => {
1108
+ teammateContextStorage = new AsyncLocalStorage;
1109
+ });
1110
+
1020
1111
  // src/shared/index.ts
1021
1112
  var init_shared = __esm(() => {
1022
1113
  init_feature();
@@ -1034,6 +1125,10 @@ var init_shared = __esm(() => {
1034
1125
  init_fs_operations();
1035
1126
  init_types();
1036
1127
  init_pdfReference();
1128
+ init_agentSwarmsEnabled();
1129
+ init_swarmSchemaFilter();
1130
+ init_agentRoleTemplates();
1131
+ init_teammateContext();
1037
1132
  });
1038
1133
 
1039
1134
  // node_modules/openai/internal/tslib.mjs
@@ -27531,9 +27626,14 @@ async function buildOpenAITools(tools, options, emptyPermissionContext) {
27531
27626
  } catch {
27532
27627
  desc = tool.name;
27533
27628
  }
27629
+ const filteredSchema = filterSwarmFieldsFromSchema(tool.name, schema, isAgentSwarmsEnabled());
27534
27630
  out.push({
27535
27631
  type: "function",
27536
- function: { name: tool.name, description: desc, parameters: schema }
27632
+ function: {
27633
+ name: tool.name,
27634
+ description: desc,
27635
+ parameters: filteredSchema
27636
+ }
27537
27637
  });
27538
27638
  }
27539
27639
  for (const s of options?.extraToolSchemas ?? []) {
@@ -27620,6 +27720,7 @@ async function buildOpenAIParams(args, role = "small", entry, opts) {
27620
27720
  var init_params = __esm(() => {
27621
27721
  init_roles7();
27622
27722
  init_shared();
27723
+ init_shared();
27623
27724
  init_attachmentProjection();
27624
27725
  init_toolPairing();
27625
27726
  init_schema();
@@ -29563,7 +29664,7 @@ var init_state = __esm(() => {
29563
29664
  });
29564
29665
 
29565
29666
  // src/bootstrap/cwd.ts
29566
- import { AsyncLocalStorage } from "async_hooks";
29667
+ import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
29567
29668
  function runWithCwdOverride(cwd, fn) {
29568
29669
  return cwdOverrideStorage.run(cwd, fn);
29569
29670
  }
@@ -29580,7 +29681,7 @@ function getCwd() {
29580
29681
  var cwdOverrideStorage;
29581
29682
  var init_cwd = __esm(() => {
29582
29683
  init_state();
29583
- cwdOverrideStorage = new AsyncLocalStorage;
29684
+ cwdOverrideStorage = new AsyncLocalStorage2;
29584
29685
  });
29585
29686
 
29586
29687
  // src/bootstrap/index.ts
@@ -34620,7 +34721,7 @@ var init_project = __esm(() => {
34620
34721
  var AGENT_TOOL_NAME = "Agent", MAX_WORKER_SPAWN_DEPTH = 2;
34621
34722
 
34622
34723
  // src/engine/tools/toolNames.ts
34623
- var FILE_READ_TOOL_NAME = "Read", WEB_SEARCH_TOOL_NAME = "WebSearch", TODO_WRITE_TOOL_NAME = "TodoWrite", GREP_TOOL_NAME = "Grep", WEB_FETCH_TOOL_NAME = "WebFetch", GLOB_TOOL_NAME = "Glob", BASH_TOOL_NAME2 = "Bash", POWERSHELL_TOOL_NAME = "PowerShell", FILE_EDIT_TOOL_NAME = "Edit", FILE_WRITE_TOOL_NAME = "Write", NOTEBOOK_EDIT_TOOL_NAME = "NotebookEdit", SKILL_TOOL_NAME = "Skill", SYNTHETIC_OUTPUT_TOOL_NAME = "StructuredOutput", TOOL_SEARCH_TOOL_NAME = "ToolSearch", ENTER_WORKTREE_TOOL_NAME = "EnterWorktree", EXIT_WORKTREE_TOOL_NAME = "ExitWorktree", TEAM_CREATE_TOOL_NAME = "TeamCreate", TEAM_DELETE_TOOL_NAME = "TeamDelete", SNIP_TOOL_NAME = "Snip", SEND_MESSAGE_TOOL_NAME = "SendMessage", TASK_STOP_TOOL_NAME = "TaskStop", TASK_OUTPUT_TOOL_NAME = "TaskOutput", ENTER_PLAN_MODE_TOOL_NAME = "EnterPlanMode", EXIT_PLAN_MODE_V2_TOOL_NAME = "ExitPlanMode", ASK_USER_QUESTION_TOOL_NAME = "AskUserQuestion", TASK_CREATE_TOOL_NAME = "TaskCreate", TASK_GET_TOOL_NAME = "TaskGet", TASK_LIST_TOOL_NAME = "TaskList", TASK_UPDATE_TOOL_NAME = "TaskUpdate", CRON_CREATE_TOOL_NAME = "CronCreate", CRON_DELETE_TOOL_NAME = "CronDelete", CRON_LIST_TOOL_NAME = "CronList", CONFIG_TOOL_NAME = "Config", WORKFLOW_TOOL_NAME = "Workflow", REPL_TOOL_NAME = "REPL", LIST_MCP_RESOURCES_TOOL_NAME = "ListMcpResourcesTool", READ_MCP_RESOURCE_TOOL_NAME = "ReadMcpResourceTool", LSP_TOOL_NAME = "LSP", PROPOSE_GOAL_TOOL_NAME = "ProposeGoal", SHELL_TOOL_NAMES, ASYNC_AGENT_ALLOWED_TOOLS, INTERNAL_WORKER_TOOLS, ALL_AGENT_DISALLOWED_TOOLS, CUSTOM_AGENT_DISALLOWED_TOOLS, IN_PROCESS_TEAMMATE_ALLOWED_TOOLS, COORDINATOR_MODE_ALLOWED_TOOLS;
34724
+ var FILE_READ_TOOL_NAME = "Read", WEB_SEARCH_TOOL_NAME = "WebSearch", TODO_WRITE_TOOL_NAME = "TodoWrite", GREP_TOOL_NAME = "Grep", WEB_FETCH_TOOL_NAME = "WebFetch", GLOB_TOOL_NAME = "Glob", BASH_TOOL_NAME2 = "Bash", POWERSHELL_TOOL_NAME = "PowerShell", FILE_EDIT_TOOL_NAME = "Edit", FILE_WRITE_TOOL_NAME = "Write", NOTEBOOK_EDIT_TOOL_NAME = "NotebookEdit", SKILL_TOOL_NAME = "Skill", SYNTHETIC_OUTPUT_TOOL_NAME = "StructuredOutput", TOOL_SEARCH_TOOL_NAME = "ToolSearch", ENTER_WORKTREE_TOOL_NAME = "EnterWorktree", EXIT_WORKTREE_TOOL_NAME = "ExitWorktree", TEAM_CREATE_TOOL_NAME = "TeamCreate", TEAM_DELETE_TOOL_NAME = "TeamDelete", WAIT_FOR_TEAMMATES_TOOL_NAME = "WaitForTeammates", SNIP_TOOL_NAME = "Snip", SEND_MESSAGE_TOOL_NAME = "SendMessage", TASK_STOP_TOOL_NAME = "TaskStop", TASK_OUTPUT_TOOL_NAME = "TaskOutput", ENTER_PLAN_MODE_TOOL_NAME = "EnterPlanMode", EXIT_PLAN_MODE_V2_TOOL_NAME = "ExitPlanMode", ASK_USER_QUESTION_TOOL_NAME = "AskUserQuestion", TASK_CREATE_TOOL_NAME = "TaskCreate", TASK_GET_TOOL_NAME = "TaskGet", TASK_LIST_TOOL_NAME = "TaskList", TASK_UPDATE_TOOL_NAME = "TaskUpdate", CRON_CREATE_TOOL_NAME = "CronCreate", CRON_DELETE_TOOL_NAME = "CronDelete", CRON_LIST_TOOL_NAME = "CronList", CONFIG_TOOL_NAME = "Config", WORKFLOW_TOOL_NAME = "Workflow", REPL_TOOL_NAME = "REPL", LIST_MCP_RESOURCES_TOOL_NAME = "ListMcpResourcesTool", READ_MCP_RESOURCE_TOOL_NAME = "ReadMcpResourceTool", LSP_TOOL_NAME = "LSP", PROPOSE_GOAL_TOOL_NAME = "ProposeGoal", SHELL_TOOL_NAMES, ASYNC_AGENT_ALLOWED_TOOLS, INTERNAL_WORKER_TOOLS, ALL_AGENT_DISALLOWED_TOOLS, CUSTOM_AGENT_DISALLOWED_TOOLS, IN_PROCESS_TEAMMATE_ALLOWED_TOOLS, COORDINATOR_MODE_ALLOWED_TOOLS;
34624
34725
  var init_toolNames = __esm(() => {
34625
34726
  SHELL_TOOL_NAMES = [BASH_TOOL_NAME2, POWERSHELL_TOOL_NAME];
34626
34727
  ASYNC_AGENT_ALLOWED_TOOLS = new Set([
@@ -35711,9 +35812,22 @@ var init_diskOutput = __esm(() => {
35711
35812
  });
35712
35813
 
35713
35814
  // src/task/task.ts
35815
+ import { randomBytes } from "crypto";
35714
35816
  function isTerminalTaskStatus(status) {
35715
35817
  return status === "completed" || status === "failed" || status === "killed";
35716
35818
  }
35819
+ function getTaskIdPrefix(type) {
35820
+ return TASK_ID_PREFIXES[type] ?? "x";
35821
+ }
35822
+ function generateTaskId(type) {
35823
+ const prefix = getTaskIdPrefix(type);
35824
+ const bytes = randomBytes(8);
35825
+ let id = prefix;
35826
+ for (let i = 0;i < 8; i++) {
35827
+ id += TASK_ID_ALPHABET[bytes[i] % TASK_ID_ALPHABET.length];
35828
+ }
35829
+ return id;
35830
+ }
35717
35831
  function createTaskStateBase(id, type, description, toolUseId) {
35718
35832
  return {
35719
35833
  id,
@@ -35727,14 +35841,79 @@ function createTaskStateBase(id, type, description, toolUseId) {
35727
35841
  notified: false
35728
35842
  };
35729
35843
  }
35844
+ var TASK_ID_PREFIXES, TASK_ID_ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz";
35730
35845
  var init_task = __esm(() => {
35731
35846
  init_diskOutput();
35847
+ TASK_ID_PREFIXES = {
35848
+ local_bash: "b",
35849
+ local_agent: "a",
35850
+ remote_agent: "r",
35851
+ in_process_teammate: "t",
35852
+ local_workflow: "w",
35853
+ monitor_mcp: "m",
35854
+ dream: "d"
35855
+ };
35732
35856
  });
35733
35857
 
35734
35858
  // src/task/inProcessTeammate.ts
35735
35859
  function isInProcessTeammateTask(task) {
35736
35860
  return task.type === "in_process_teammate";
35737
35861
  }
35862
+ function asInProcessTeammate(task) {
35863
+ if (typeof task === "object" && task !== null && isInProcessTeammateTask(task)) {
35864
+ return task;
35865
+ }
35866
+ return;
35867
+ }
35868
+ function isInProcessTeammateLive(task) {
35869
+ const t = asInProcessTeammate(task);
35870
+ return t !== undefined && t.status === "running";
35871
+ }
35872
+ function isInProcessTeammateWorking(task) {
35873
+ const t = asInProcessTeammate(task);
35874
+ return t !== undefined && t.status === "running" && !t.isIdle;
35875
+ }
35876
+ function isInProcessTeammateActiveOrUnknown(task) {
35877
+ const t = asInProcessTeammate(task);
35878
+ const status = t !== undefined ? t.status : task?.status;
35879
+ return status === undefined || status === "running";
35880
+ }
35881
+ function findInProcessTeammateTaskByAgentId(tasks, agentId) {
35882
+ for (const task of Object.values(tasks ?? {})) {
35883
+ const t = asInProcessTeammate(task);
35884
+ if (t !== undefined && t.identity.agentId === agentId)
35885
+ return t;
35886
+ }
35887
+ return;
35888
+ }
35889
+ function probeStampAbortController(ac) {
35890
+ let id = probeControllerIds.get(ac);
35891
+ if (id === undefined) {
35892
+ probeControllerSeq += 1;
35893
+ id = `ac-${probeControllerSeq}`;
35894
+ probeControllerIds.set(ac, id);
35895
+ }
35896
+ return id;
35897
+ }
35898
+ function probeReadAbortControllerId(ac) {
35899
+ if (!ac)
35900
+ return "none";
35901
+ return probeControllerIds.get(ac) ?? "untagged";
35902
+ }
35903
+ function probeStampTaskRecord(record) {
35904
+ let id = probeTaskRecordIds.get(record);
35905
+ if (id === undefined) {
35906
+ probeTaskRecordSeq += 1;
35907
+ id = `task-${probeTaskRecordSeq}`;
35908
+ probeTaskRecordIds.set(record, id);
35909
+ }
35910
+ return id;
35911
+ }
35912
+ function probeReadTaskRecordId(record) {
35913
+ if (typeof record !== "object" || record === null)
35914
+ return "none";
35915
+ return probeTaskRecordIds.get(record) ?? "untagged";
35916
+ }
35738
35917
  function appendCappedMessage(messages, message, cap = MAX_TEAMMATE_DISPLAY_MESSAGES) {
35739
35918
  const next = [...messages ?? [], message];
35740
35919
  if (next.length > cap) {
@@ -35742,7 +35921,11 @@ function appendCappedMessage(messages, message, cap = MAX_TEAMMATE_DISPLAY_MESSA
35742
35921
  }
35743
35922
  return next;
35744
35923
  }
35745
- var MAX_TEAMMATE_DISPLAY_MESSAGES = 100;
35924
+ var probeControllerIds, probeControllerSeq = 0, probeTaskRecordIds, probeTaskRecordSeq = 0, MAX_TEAMMATE_DISPLAY_MESSAGES = 100;
35925
+ var init_inProcessTeammate = __esm(() => {
35926
+ probeControllerIds = new WeakMap;
35927
+ probeTaskRecordIds = new WeakMap;
35928
+ });
35746
35929
 
35747
35930
  // src/task/outputLimits.ts
35748
35931
  function getMaxOutputLength() {
@@ -36024,6 +36207,7 @@ var init_outputFormatting = __esm(() => {
36024
36207
  // src/task/index.ts
36025
36208
  var init_task2 = __esm(() => {
36026
36209
  init_task();
36210
+ init_inProcessTeammate();
36027
36211
  init_TaskOutput();
36028
36212
  init_fsRange();
36029
36213
  init_outputLimits();
@@ -36274,28 +36458,6 @@ function isLocalShellTask(task) {
36274
36458
  return typeof task === "object" && task !== null && "type" in task && task.type === "local_bash";
36275
36459
  }
36276
36460
 
36277
- // src/engine/messaging/teammateContext.ts
36278
- import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
36279
- function getTeammateContext() {
36280
- return teammateContextStorage.getStore();
36281
- }
36282
- function runWithTeammateContext(context, fn) {
36283
- return teammateContextStorage.run(context, fn);
36284
- }
36285
- function isInProcessTeammate() {
36286
- return teammateContextStorage.getStore() !== undefined;
36287
- }
36288
- function createTeammateContext(config) {
36289
- return {
36290
- ...config,
36291
- isInProcess: true
36292
- };
36293
- }
36294
- var teammateContextStorage;
36295
- var init_teammateContext = __esm(() => {
36296
- teammateContextStorage = new AsyncLocalStorage2;
36297
- });
36298
-
36299
36461
  // src/engine/messaging/teammate.ts
36300
36462
  function getParentSessionId() {
36301
36463
  const inProcessCtx = getTeammateContext();
@@ -36426,7 +36588,7 @@ var init_teammate = __esm(() => {
36426
36588
  init_teammateContext();
36427
36589
  init_shared();
36428
36590
  init_task2();
36429
- init_teammateContext();
36591
+ init_shared();
36430
36592
  });
36431
36593
 
36432
36594
  // src/engine/messaging/agentId.ts
@@ -37411,14 +37573,8 @@ var init_queueManager = __esm(() => {
37411
37573
  });
37412
37574
 
37413
37575
  // src/engine/messaging/agentSwarmsEnabled.ts
37414
- function isAgentTeamsFlagSet() {
37415
- return process.argv.includes("--agent-teams");
37416
- }
37417
- function isAgentSwarmsEnabled() {
37418
- return isEnvTruthy(process.env.ATLAS_EXPERIMENTAL_AGENT_TEAMS) || isAgentTeamsFlagSet();
37419
- }
37420
- var init_agentSwarmsEnabled = __esm(() => {
37421
- init_shared();
37576
+ var init_agentSwarmsEnabled2 = __esm(() => {
37577
+ init_agentSwarmsEnabled();
37422
37578
  });
37423
37579
 
37424
37580
  // src/engine/messaging/index.ts
@@ -37428,7 +37584,7 @@ var init_messaging = __esm(() => {
37428
37584
  init_lockfile();
37429
37585
  init_constants4();
37430
37586
  init_queueManager();
37431
- init_agentSwarmsEnabled();
37587
+ init_agentSwarmsEnabled2();
37432
37588
  });
37433
37589
 
37434
37590
  // src/engine/coordinator/tasks/killShellTasks.ts
@@ -37805,7 +37961,8 @@ async function runAgent(args) {
37805
37961
  spawnDepth,
37806
37962
  signal,
37807
37963
  forkContextMessages,
37808
- checkPermission
37964
+ checkPermission,
37965
+ toolContext
37809
37966
  } = args;
37810
37967
  const role = resolveRole(overrideRole, agentDefinition, parentRole);
37811
37968
  const startTime = Date.now();
@@ -37815,7 +37972,7 @@ async function runAgent(args) {
37815
37972
  ...forkContextMessages ?? [],
37816
37973
  { type: "user", role: "user", content: prompt }
37817
37974
  ];
37818
- const loopResult = await queryAgentLoop({ modelProvider, role, signal, checkPermission }, { messages, tools });
37975
+ const loopResult = await queryAgentLoop({ modelProvider, role, signal, checkPermission, toolContext }, { messages, tools });
37819
37976
  const result = finalizeAgentTool(loopResult.messages, agentId, {
37820
37977
  agentType: agentDefinition.agentType,
37821
37978
  startTime
@@ -37922,6 +38079,65 @@ var init_backgroundTracker = __esm(() => {
37922
38079
  pendingBackgroundAgents = new Set;
37923
38080
  });
37924
38081
 
38082
+ // src/engine/tools/agent/teammateSpawnPort.ts
38083
+ function setTeammateSpawnTrigger(fn) {
38084
+ trigger = fn;
38085
+ }
38086
+ function resetTeammateSpawnTrigger() {
38087
+ trigger = null;
38088
+ }
38089
+ function requireTeammateSpawnTrigger() {
38090
+ if (!trigger) {
38091
+ throw new Error("TeammateSpawnTrigger not wired — call setTeammateSpawnTrigger at composition root first (0.1.93 W-D-A spawn seam)");
38092
+ }
38093
+ return trigger;
38094
+ }
38095
+ var trigger = null;
38096
+
38097
+ // src/engine/tools/team/teamServices.ts
38098
+ function setTeamServices(services) {
38099
+ active = services;
38100
+ }
38101
+ function resetTeamServices() {
38102
+ active = undefined;
38103
+ }
38104
+ function requireTeamServices() {
38105
+ if (!active) {
38106
+ throw new Error("TeamServices not wired — call setTeamServices at composition root first (swarm team-file seam, C 桶 ③ S-E2d)");
38107
+ }
38108
+ return active;
38109
+ }
38110
+ function peekTeamContext() {
38111
+ return active?.getTeamContext();
38112
+ }
38113
+ function createDefaultTeamContextStore() {
38114
+ return {
38115
+ getTeamContext: () => teamContext,
38116
+ setTeamContext: (ctx) => {
38117
+ teamContext = ctx;
38118
+ }
38119
+ };
38120
+ }
38121
+ function registerSpawnedTeammate(input) {
38122
+ const services = requireTeamServices();
38123
+ const ctx = services.getTeamContext();
38124
+ if (!ctx) {
38125
+ throw new Error("registerSpawnedTeammate: no active team — call TeamCreate before spawning teammates");
38126
+ }
38127
+ ctx.teammates[input.agentId] = {
38128
+ name: input.name,
38129
+ agentType: input.agentType,
38130
+ color: services.assignTeammateColor(input.agentId),
38131
+ tmuxSessionName: "",
38132
+ tmuxPaneId: "",
38133
+ cwd: input.cwd ?? "",
38134
+ spawnedAt: Date.now(),
38135
+ ...input.taskId ? { taskId: input.taskId } : {}
38136
+ };
38137
+ services.setTeamContext(ctx);
38138
+ }
38139
+ var active, teamContext;
38140
+
37925
38141
  // src/engine/tools/agent/AgentTool.ts
37926
38142
  import { randomUUID as randomUUID5 } from "crypto";
37927
38143
  function isAgentBackgroundByDefault() {
@@ -37945,6 +38161,45 @@ function resolveAgentDefinition(subagentType, agents) {
37945
38161
  whenToUse: "Custom agent type: " + subagentType
37946
38162
  };
37947
38163
  }
38164
+ async function spawnTeammateFromRoster(args) {
38165
+ const services = requireTeamServices();
38166
+ const teamCtx = services.getTeamContext();
38167
+ if (!teamCtx) {
38168
+ throw new Error(`No active team — call TeamCreate before spawning teammates (wanted team "${args.teamName}")`);
38169
+ }
38170
+ if (teamCtx.teamName !== args.teamName) {
38171
+ throw new Error(`Team "${args.teamName}" is not the active team (leading "${teamCtx.teamName}") — one team per leader`);
38172
+ }
38173
+ if (!args.name || args.name.trim().length === 0) {
38174
+ throw new Error("name (the teammate identity) is required for team-based delegation");
38175
+ }
38176
+ const rosterEntry = teamCtx.roster?.find((r) => r.name === args.name);
38177
+ const composedPrompt = renderTeammatePrompt({
38178
+ name: args.name,
38179
+ role: rosterEntry?.role,
38180
+ goal: rosterEntry?.goal,
38181
+ backstory: rosterEntry?.backstory,
38182
+ prompt: args.prompt
38183
+ });
38184
+ const trigger = requireTeammateSpawnTrigger();
38185
+ const result = await trigger({
38186
+ name: args.name,
38187
+ teamName: args.teamName,
38188
+ prompt: composedPrompt,
38189
+ ...args.model ? { model: args.model } : {},
38190
+ allowPermissionPrompts: false
38191
+ });
38192
+ if (!result.success) {
38193
+ throw new Error(result.error ?? `teammate spawn failed for "${args.name}"`);
38194
+ }
38195
+ registerSpawnedTeammate({
38196
+ name: args.name,
38197
+ agentId: result.agentId,
38198
+ agentType: rosterEntry?.role,
38199
+ ...result.taskId ? { taskId: result.taskId } : {}
38200
+ });
38201
+ return result;
38202
+ }
37948
38203
  var AGENT_TOOL_INPUT_SCHEMA, AgentTool;
37949
38204
  var init_AgentTool = __esm(() => {
37950
38205
  init_modelprovider2();
@@ -37958,6 +38213,7 @@ var init_AgentTool = __esm(() => {
37958
38213
  init_localAgentTask();
37959
38214
  init_shared();
37960
38215
  init_backgroundTracker();
38216
+ init_shared();
37961
38217
  AGENT_TOOL_INPUT_SCHEMA = {
37962
38218
  type: "object",
37963
38219
  properties: {
@@ -37980,6 +38236,18 @@ var init_AgentTool = __esm(() => {
37980
38236
  run_in_background: {
37981
38237
  type: "boolean",
37982
38238
  description: "Set to true to run this agent in the background. You will be notified when it completes."
38239
+ },
38240
+ name: {
38241
+ type: "string",
38242
+ description: "Teammate name for team-based delegation. Provide together with team_name to spawn a teammate into that team (TeamCreate first)."
38243
+ },
38244
+ team_name: {
38245
+ type: "string",
38246
+ description: "Name of the team to spawn the teammate into (must match an active TeamCreate team)."
38247
+ },
38248
+ mode: {
38249
+ type: "string",
38250
+ description: "Teammate mode (upstream contract field)."
37983
38251
  }
37984
38252
  },
37985
38253
  required: ["description", "prompt"]
@@ -37997,6 +38265,25 @@ var init_AgentTool = __esm(() => {
37997
38265
  behavior: "passthrough",
37998
38266
  message: "Agent tool requires permission."
37999
38267
  }),
38268
+ async validateInput(input, _context) {
38269
+ const i = input ?? {};
38270
+ const hasTeammateFields = !!(i.name || i.team_name || i.mode);
38271
+ if (hasTeammateFields && !isAgentSwarmsEnabled()) {
38272
+ return {
38273
+ result: false,
38274
+ message: "Agent teammate parameters (name/team_name/mode) require the agent-teams gate (ATLAS_EXPERIMENTAL_AGENT_TEAMS=1 or --agent-teams)",
38275
+ errorCode: 9
38276
+ };
38277
+ }
38278
+ if (i.team_name && !i.name) {
38279
+ return {
38280
+ result: false,
38281
+ message: "team_name requires name (the teammate identity) for team-based delegation",
38282
+ errorCode: 9
38283
+ };
38284
+ }
38285
+ return { result: true };
38286
+ },
38000
38287
  toAutoClassifierInput: (input) => input,
38001
38288
  description: async () => getPrompt(getBuiltInAgents()),
38002
38289
  userFacingName: (input) => {
@@ -38032,6 +38319,30 @@ var init_AgentTool = __esm(() => {
38032
38319
  async call(args, context) {
38033
38320
  const input = args ?? {};
38034
38321
  const ctx = context ?? {};
38322
+ if (input.name || input.team_name) {
38323
+ if (!isAgentSwarmsEnabled()) {
38324
+ throw new Error("Agent teammate spawn requires the agent-teams gate (ATLAS_EXPERIMENTAL_AGENT_TEAMS=1 or --agent-teams)");
38325
+ }
38326
+ const teamName = input.team_name;
38327
+ if (!teamName) {
38328
+ throw new Error("team_name is required when spawning a teammate (name alone is ambiguous)");
38329
+ }
38330
+ const spawnResult = await spawnTeammateFromRoster({
38331
+ name: input.name ?? "",
38332
+ teamName,
38333
+ prompt: input.prompt,
38334
+ model: input.model
38335
+ });
38336
+ return {
38337
+ data: {
38338
+ status: "teammate_spawned",
38339
+ agentId: spawnResult.agentId,
38340
+ ...spawnResult.taskId ? { taskId: spawnResult.taskId } : {},
38341
+ name: input.name,
38342
+ team_name: teamName
38343
+ }
38344
+ };
38345
+ }
38035
38346
  const parentRole = ctx.parentRole ?? "small";
38036
38347
  const modelProvider = ctx.modelProvider ?? getModelProvider();
38037
38348
  const agentDefinition = resolveAgentDefinition(input.subagent_type, getBuiltInAgents());
@@ -43588,9 +43899,9 @@ function createSubcommandPrefixExtractor(getPrefix, splitCommand) {
43588
43899
  }
43589
43900
 
43590
43901
  // src/engine/tools/bash/heredoc.ts
43591
- import { randomBytes } from "crypto";
43902
+ import { randomBytes as randomBytes2 } from "crypto";
43592
43903
  function generatePlaceholderSalt() {
43593
- return randomBytes(8).toString("hex");
43904
+ return randomBytes2(8).toString("hex");
43594
43905
  }
43595
43906
  function extractHeredocs(command, options) {
43596
43907
  const heredocs = new Map;
@@ -44380,9 +44691,9 @@ var init_shellQuote = __esm(() => {
44380
44691
  });
44381
44692
 
44382
44693
  // src/engine/tools/bash/commands.ts
44383
- import { randomBytes as randomBytes2 } from "crypto";
44694
+ import { randomBytes as randomBytes3 } from "crypto";
44384
44695
  function generatePlaceholders() {
44385
- const salt = randomBytes2(8).toString("hex");
44696
+ const salt = randomBytes3(8).toString("hex");
44386
44697
  return {
44387
44698
  SINGLE_QUOTE: `__SINGLE_QUOTE_${salt}__`,
44388
44699
  DOUBLE_QUOTE: `__DOUBLE_QUOTE_${salt}__`,
@@ -50771,13 +51082,13 @@ function getExecutorSandboxPort() {
50771
51082
  var activePort3 = null;
50772
51083
 
50773
51084
  // src/executor/shell/ShellCommand.ts
50774
- import { randomBytes as randomBytes3 } from "crypto";
51085
+ import { randomBytes as randomBytes4 } from "crypto";
50775
51086
  import { stat as stat5 } from "fs/promises";
50776
51087
  function generateLocalTaskId() {
50777
- const bytes = randomBytes3(8);
51088
+ const bytes = randomBytes4(8);
50778
51089
  let id = "b";
50779
51090
  for (let i = 0;i < 8; i++) {
50780
- id += TASK_ID_ALPHABET[bytes[i] % TASK_ID_ALPHABET.length];
51091
+ id += TASK_ID_ALPHABET2[bytes[i] % TASK_ID_ALPHABET2.length];
50781
51092
  }
50782
51093
  return id;
50783
51094
  }
@@ -51043,7 +51354,7 @@ function createFailedCommand(preSpawnError) {
51043
51354
  cleanup() {}
51044
51355
  };
51045
51356
  }
51046
- var SIGKILL = 137, SIGTERM = 143, SIZE_WATCHDOG_INTERVAL_MS = 5000, TASK_ID_ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz";
51357
+ var SIGKILL = 137, SIGTERM = 143, SIZE_WATCHDOG_INTERVAL_MS = 5000, TASK_ID_ALPHABET2 = "0123456789abcdefghijklmnopqrstuvwxyz";
51047
51358
  var init_ShellCommand = __esm(() => {
51048
51359
  init_shared();
51049
51360
  });
@@ -53872,9 +54183,9 @@ Remember: DO NOT write or edit any files yet. This is a read-only exploration an
53872
54183
  });
53873
54184
 
53874
54185
  // src/engine/tools/plan/planWords.ts
53875
- import { randomBytes as randomBytes4 } from "crypto";
54186
+ import { randomBytes as randomBytes5 } from "crypto";
53876
54187
  function randomInt(max) {
53877
- const bytes = randomBytes4(4);
54188
+ const bytes = randomBytes5(4);
53878
54189
  const value = bytes.readUInt32BE(0);
53879
54190
  return value % max;
53880
54191
  }
@@ -70157,15 +70468,21 @@ function parseAddress(to) {
70157
70468
  return { scheme: "uds", target: to };
70158
70469
  return { scheme: "other", target: to };
70159
70470
  }
70160
- // src/swarm/teammateContext.ts
70161
- import { AsyncLocalStorage as AsyncLocalStorage3 } from "async_hooks";
70162
- function runWithTeammateContext2(context, fn) {
70163
- return teammateContextStorage2.run(context, fn);
70471
+
70472
+ // src/swarm/agentId.ts
70473
+ function formatAgentId2(agentName, teamName) {
70474
+ return `${agentName}@${teamName}`;
70475
+ }
70476
+ function parseAgentId2(agentId) {
70477
+ const atIndex = agentId.indexOf("@");
70478
+ if (atIndex === -1) {
70479
+ return null;
70480
+ }
70481
+ return {
70482
+ agentName: agentId.slice(0, atIndex),
70483
+ teamName: agentId.slice(atIndex + 1)
70484
+ };
70164
70485
  }
70165
- var teammateContextStorage2;
70166
- var init_teammateContext2 = __esm(() => {
70167
- teammateContextStorage2 = new AsyncLocalStorage3;
70168
- });
70169
70486
 
70170
70487
  // src/swarm/standaloneAgent.ts
70171
70488
  var init_standaloneAgent = __esm(() => {
@@ -70260,6 +70577,10 @@ var init_types5 = __esm(() => {
70260
70577
  });
70261
70578
 
70262
70579
  // src/swarm/cleanupRegistry.ts
70580
+ function registerCleanup(cleanupFn) {
70581
+ cleanupFunctions.add(cleanupFn);
70582
+ return () => cleanupFunctions.delete(cleanupFn);
70583
+ }
70263
70584
  var cleanupFunctions;
70264
70585
  var init_cleanupRegistry = __esm(() => {
70265
70586
  cleanupFunctions = new Set;
@@ -70323,11 +70644,30 @@ async function readTeamFileAsync(teamName) {
70323
70644
  return null;
70324
70645
  }
70325
70646
  }
70647
+ function writeTeamFile(teamName, teamFile) {
70648
+ const teamDir = getTeamDir(teamName);
70649
+ mkdirSync3(teamDir, { recursive: true });
70650
+ writeFileSync2(getTeamFilePath(teamName), jsonStringify(teamFile, 2));
70651
+ }
70326
70652
  async function writeTeamFileAsync(teamName, teamFile) {
70327
70653
  const teamDir = getTeamDir(teamName);
70328
70654
  await mkdir5(teamDir, { recursive: true });
70329
70655
  await writeFile4(getTeamFilePath(teamName), jsonStringify(teamFile, 2));
70330
70656
  }
70657
+ function removeMemberByAgentId(teamName, agentId) {
70658
+ const teamFile = readTeamFile(teamName);
70659
+ if (!teamFile) {
70660
+ return false;
70661
+ }
70662
+ const memberIndex = teamFile.members.findIndex((m) => m.agentId === agentId);
70663
+ if (memberIndex === -1) {
70664
+ return false;
70665
+ }
70666
+ teamFile.members.splice(memberIndex, 1);
70667
+ writeTeamFile(teamName, teamFile);
70668
+ logForDebugging(`[TeammateTool] Removed member ${agentId} from team ${teamName}`);
70669
+ return true;
70670
+ }
70331
70671
  async function destroyWorktree(worktreePath) {
70332
70672
  const gitFilePath = join25(worktreePath, ".git");
70333
70673
  let mainRepoPath = null;
@@ -70424,17 +70764,152 @@ var init_teamMemoryOps = __esm(() => {
70424
70764
  });
70425
70765
 
70426
70766
  // src/swarm/spawnInProcess.ts
70767
+ async function spawnInProcessTeammate(config, context) {
70768
+ const { name, teamName, prompt, color, planModeRequired, model } = config;
70769
+ const { setAppState } = context;
70770
+ const agentId = formatAgentId2(name, teamName);
70771
+ const taskId = generateTaskId("in_process_teammate");
70772
+ logForDebugging(`[spawnInProcessTeammate] Spawning ${agentId} (taskId: ${taskId})`);
70773
+ try {
70774
+ const abortController = createAbortController();
70775
+ logForDebugging(`[probe-R1][spawn] agent=${agentId} taskId=${taskId} controller=${probeStampAbortController(abortController)}`);
70776
+ const parentSessionId = getSessionId();
70777
+ const identity = {
70778
+ agentId,
70779
+ agentName: name,
70780
+ teamName,
70781
+ color,
70782
+ planModeRequired,
70783
+ parentSessionId
70784
+ };
70785
+ const teammateContext = createTeammateContext({
70786
+ agentId,
70787
+ agentName: name,
70788
+ teamName,
70789
+ color,
70790
+ planModeRequired,
70791
+ parentSessionId,
70792
+ abortController
70793
+ });
70794
+ const description = `${name}: ${prompt.substring(0, 50)}${prompt.length > 50 ? "..." : ""}`;
70795
+ const taskState = {
70796
+ ...createTaskStateBase(taskId, "in_process_teammate", description, context.toolUseId),
70797
+ type: "in_process_teammate",
70798
+ status: "running",
70799
+ identity,
70800
+ prompt,
70801
+ model,
70802
+ abortController,
70803
+ awaitingPlanApproval: false,
70804
+ permissionMode: planModeRequired ? "plan" : "default",
70805
+ isIdle: false,
70806
+ shutdownRequested: false,
70807
+ lastReportedToolCount: 0,
70808
+ lastReportedTokenCount: 0,
70809
+ pendingUserMessages: [],
70810
+ messages: []
70811
+ };
70812
+ logForDebugging(`[probe-R6][spawn-record] agent=${agentId} taskId=${taskId} record=${probeStampTaskRecord(taskState)}`);
70813
+ const unregisterCleanup = registerCleanup(async () => {
70814
+ logForDebugging(`[spawnInProcessTeammate] Cleanup called for ${agentId}`);
70815
+ abortController.abort();
70816
+ });
70817
+ taskState.unregisterCleanup = unregisterCleanup;
70818
+ registerTask(taskState, setAppState);
70819
+ logForDebugging(`[spawnInProcessTeammate] Registered ${agentId} in AppState`);
70820
+ return {
70821
+ success: true,
70822
+ agentId,
70823
+ taskId,
70824
+ abortController,
70825
+ teammateContext
70826
+ };
70827
+ } catch (error) {
70828
+ const errorMessage = error instanceof Error ? error.message : "Unknown error during spawn";
70829
+ logForDebugging(`[spawnInProcessTeammate] Failed to spawn ${agentId}: ${errorMessage}`);
70830
+ return {
70831
+ success: false,
70832
+ agentId,
70833
+ error: errorMessage
70834
+ };
70835
+ }
70836
+ }
70837
+ function killInProcessTeammate(taskId, setAppState) {
70838
+ let killed = false;
70839
+ let teamName = null;
70840
+ let agentId = null;
70841
+ let toolUseId;
70842
+ let description;
70843
+ setAppState((prev) => {
70844
+ const task = prev.tasks[taskId];
70845
+ if (!task || !isInProcessTeammateTask(task)) {
70846
+ return prev;
70847
+ }
70848
+ const teammateTask = task;
70849
+ if (teammateTask.status !== "running") {
70850
+ return prev;
70851
+ }
70852
+ teamName = teammateTask.identity.teamName;
70853
+ agentId = teammateTask.identity.agentId;
70854
+ toolUseId = teammateTask.toolUseId;
70855
+ description = teammateTask.description;
70856
+ teammateTask.abortController?.abort();
70857
+ teammateTask.unregisterCleanup?.();
70858
+ killed = true;
70859
+ teammateTask.onIdleCallbacks?.forEach((cb) => cb());
70860
+ return {
70861
+ ...prev,
70862
+ tasks: {
70863
+ ...prev.tasks,
70864
+ [taskId]: {
70865
+ ...teammateTask,
70866
+ status: "killed",
70867
+ notified: true,
70868
+ endTime: Date.now(),
70869
+ onIdleCallbacks: [],
70870
+ messages: teammateTask.messages?.length ? [teammateTask.messages[teammateTask.messages.length - 1]] : undefined,
70871
+ pendingUserMessages: [],
70872
+ abortController: undefined,
70873
+ unregisterCleanup: undefined
70874
+ }
70875
+ }
70876
+ };
70877
+ });
70878
+ if (teamName && agentId) {
70879
+ removeMemberByAgentId(teamName, agentId);
70880
+ }
70881
+ if (killed) {
70882
+ evictTaskOutput(taskId);
70883
+ emitTaskTerminatedSdk(taskId, "stopped", {
70884
+ toolUseId,
70885
+ summary: description
70886
+ });
70887
+ setTimeout(evictTerminalTask.bind(null, taskId, setAppState), STOPPED_DISPLAY_MS);
70888
+ }
70889
+ return killed;
70890
+ }
70427
70891
  var init_spawnInProcess = __esm(() => {
70428
70892
  init_bootstrap();
70429
70893
  init_task2();
70430
70894
  init_engine();
70431
70895
  init_shared();
70432
- init_teammateContext2();
70896
+ init_shared();
70433
70897
  init_cleanupRegistry();
70434
70898
  init_teamHelpers();
70435
70899
  });
70436
70900
 
70437
70901
  // src/swarm/inProcessTeammateTask.ts
70902
+ function requestTeammateShutdown(taskId, setAppState) {
70903
+ updateTaskState(taskId, setAppState, (task) => {
70904
+ if (task.status !== "running" || task.shutdownRequested) {
70905
+ return task;
70906
+ }
70907
+ return {
70908
+ ...task,
70909
+ shutdownRequested: true
70910
+ };
70911
+ });
70912
+ }
70438
70913
  function appendTeammateMessage(taskId, message, setAppState) {
70439
70914
  updateTaskState(taskId, setAppState, (task) => {
70440
70915
  if (task.status !== "running") {
@@ -70446,6 +70921,83 @@ function appendTeammateMessage(taskId, message, setAppState) {
70446
70921
  };
70447
70922
  });
70448
70923
  }
70924
+ function findTeammateTaskByAgentId(agentId, tasks) {
70925
+ let fallback;
70926
+ for (const task of Object.values(tasks)) {
70927
+ if (isInProcessTeammateTask(task) && task.identity.agentId === agentId) {
70928
+ if (task.status === "running") {
70929
+ return task;
70930
+ }
70931
+ if (!fallback) {
70932
+ fallback = task;
70933
+ }
70934
+ }
70935
+ }
70936
+ return fallback;
70937
+ }
70938
+ function getAllInProcessTeammateTasks(tasks) {
70939
+ return Object.values(tasks).filter(isInProcessTeammateTask);
70940
+ }
70941
+ async function gracefulShutdownInProcessTeammates(deps) {
70942
+ const running = getAllInProcessTeammateTasks(deps.getAppState().tasks ?? {}).filter((t) => t.status === "running");
70943
+ if (running.length === 0) {
70944
+ return { requested: 0, drained: 0, forced: 0, hardTerminated: 0 };
70945
+ }
70946
+ const toRequest = running.filter((t) => !t.shutdownRequested);
70947
+ const requestIdBase = Date.now();
70948
+ for (const teammate of toRequest) {
70949
+ const shutdownRequest = createShutdownRequestMessage({
70950
+ requestId: `shutdown-${teammate.identity.agentId}-session-end-${requestIdBase}`,
70951
+ from: TEAM_LEAD_NAME2,
70952
+ reason: "session end (headless terminal state)"
70953
+ });
70954
+ await writeToMailbox(teammate.identity.agentName, {
70955
+ from: TEAM_LEAD_NAME2,
70956
+ text: jsonStringify(shutdownRequest),
70957
+ timestamp: new Date().toISOString()
70958
+ }, teammate.identity.teamName);
70959
+ requestTeammateShutdown(teammate.id, deps.setAppState);
70960
+ }
70961
+ const freshTasks = () => getAllInProcessTeammateTasks(deps.getAppState().tasks ?? {});
70962
+ const countStillRunning = () => freshTasks().filter((t) => t.status === "running" && running.some((prev) => prev.id === t.id)).length;
70963
+ const waitForDrain = async (timeoutMs) => {
70964
+ const deadline = Date.now() + timeoutMs;
70965
+ for (;; ) {
70966
+ if (countStillRunning() === 0 || Date.now() >= deadline)
70967
+ return;
70968
+ await new Promise((resolve) => setTimeout(resolve, TEAMMATE_GRACEFUL_SHUTDOWN_POLL_MS));
70969
+ }
70970
+ };
70971
+ await waitForDrain(deps.timeoutMs ?? TEAMMATE_GRACEFUL_SHUTDOWN_TIMEOUT_MS);
70972
+ let drained = running.length - countStillRunning();
70973
+ if (drained === running.length) {
70974
+ return { requested: toRequest.length, drained, forced: 0, hardTerminated: 0 };
70975
+ }
70976
+ let forced = 0;
70977
+ for (const prev of running) {
70978
+ const now = freshTasks().find((t) => t.id === prev.id);
70979
+ if (now?.status === "running" && now.abortController) {
70980
+ now.abortController.abort();
70981
+ forced++;
70982
+ }
70983
+ }
70984
+ if (forced > 0) {
70985
+ await waitForDrain(deps.forcedTimeoutMs ?? TEAMMATE_FORCED_SHUTDOWN_TIMEOUT_MS);
70986
+ drained = running.length - countStillRunning();
70987
+ if (drained === running.length) {
70988
+ return { requested: toRequest.length, drained, forced, hardTerminated: 0 };
70989
+ }
70990
+ }
70991
+ let hardTerminated = 0;
70992
+ for (const prev of running) {
70993
+ const now = freshTasks().find((t) => t.id === prev.id);
70994
+ if (now?.status === "running" && killInProcessTeammate(now.id, deps.setAppState)) {
70995
+ hardTerminated++;
70996
+ }
70997
+ }
70998
+ return { requested: toRequest.length, drained, forced, hardTerminated };
70999
+ }
71000
+ var TEAMMATE_GRACEFUL_SHUTDOWN_TIMEOUT_MS = 15000, TEAMMATE_FORCED_SHUTDOWN_TIMEOUT_MS = 5000, TEAMMATE_GRACEFUL_SHUTDOWN_POLL_MS = 250;
70449
71001
  var init_inProcessTeammateTask = __esm(() => {
70450
71002
  init_task2();
70451
71003
  init_task2();
@@ -70559,9 +71111,159 @@ var init_it2Setup = __esm(() => {
70559
71111
  function setStartInProcessTeammate(fn) {
70560
71112
  startFn = fn;
70561
71113
  }
71114
+ function requireStartInProcessTeammate() {
71115
+ if (!startFn) {
71116
+ throw new Error("StartInProcessTeammate not wired — call setStartInProcessTeammate at composition root first (swarm inProcessRunner seam ②)");
71117
+ }
71118
+ return startFn;
71119
+ }
70562
71120
  var startFn = null;
70563
71121
 
70564
71122
  // src/swarm/backends/InProcessBackend.ts
71123
+ class InProcessBackend {
71124
+ type = "in-process";
71125
+ context = null;
71126
+ setContext(context) {
71127
+ this.context = context;
71128
+ }
71129
+ async isAvailable() {
71130
+ return true;
71131
+ }
71132
+ async spawn(config) {
71133
+ if (!this.context) {
71134
+ logForDebugging(`[InProcessBackend] spawn() called without context for ${config.name}`);
71135
+ return {
71136
+ success: false,
71137
+ agentId: `${config.name}@${config.teamName}`,
71138
+ error: "InProcessBackend not initialized. Call setContext() before spawn()."
71139
+ };
71140
+ }
71141
+ logForDebugging(`[InProcessBackend] spawn() called for ${config.name}`);
71142
+ const result = await spawnInProcessTeammate({
71143
+ name: config.name,
71144
+ teamName: config.teamName,
71145
+ prompt: config.prompt,
71146
+ color: config.color,
71147
+ planModeRequired: config.planModeRequired ?? false
71148
+ }, this.context);
71149
+ if (result.success && result.taskId && result.teammateContext && result.abortController) {
71150
+ requireStartInProcessTeammate()({
71151
+ identity: {
71152
+ agentId: result.agentId,
71153
+ agentName: config.name,
71154
+ teamName: config.teamName,
71155
+ color: config.color,
71156
+ planModeRequired: config.planModeRequired ?? false,
71157
+ parentSessionId: result.teammateContext.parentSessionId
71158
+ },
71159
+ taskId: result.taskId,
71160
+ prompt: config.prompt,
71161
+ teammateContext: result.teammateContext,
71162
+ toolUseContext: { ...this.context, messages: [] },
71163
+ abortController: result.abortController,
71164
+ model: config.model,
71165
+ systemPrompt: config.systemPrompt,
71166
+ systemPromptMode: config.systemPromptMode,
71167
+ allowedTools: config.permissions,
71168
+ allowPermissionPrompts: config.allowPermissionPrompts,
71169
+ ...config.termination ? { termination: config.termination } : {}
71170
+ });
71171
+ logForDebugging(`[InProcessBackend] Started agent execution for ${result.agentId}`);
71172
+ }
71173
+ return {
71174
+ success: result.success,
71175
+ agentId: result.agentId,
71176
+ taskId: result.taskId,
71177
+ abortController: result.abortController,
71178
+ error: result.error
71179
+ };
71180
+ }
71181
+ async sendMessage(agentId, message) {
71182
+ logForDebugging(`[InProcessBackend] sendMessage() to ${agentId}: ${message.text.substring(0, 50)}...`);
71183
+ const parsed = parseAgentId2(agentId);
71184
+ if (!parsed) {
71185
+ logForDebugging(`[InProcessBackend] Invalid agentId format: ${agentId}`);
71186
+ throw new Error(`Invalid agentId format: ${agentId}. Expected format: agentName@teamName`);
71187
+ }
71188
+ const { agentName, teamName } = parsed;
71189
+ await writeToMailbox(agentName, {
71190
+ text: message.text,
71191
+ from: message.from,
71192
+ color: message.color,
71193
+ timestamp: message.timestamp ?? new Date().toISOString()
71194
+ }, teamName);
71195
+ logForDebugging(`[InProcessBackend] sendMessage() completed for ${agentId}`);
71196
+ }
71197
+ async terminate(agentId, reason) {
71198
+ logForDebugging(`[InProcessBackend] terminate() called for ${agentId}: ${reason}`);
71199
+ if (!this.context) {
71200
+ logForDebugging(`[InProcessBackend] terminate() failed: no context set for ${agentId}`);
71201
+ return false;
71202
+ }
71203
+ const state = this.context.getAppState();
71204
+ const task = findTeammateTaskByAgentId(agentId, state.tasks);
71205
+ if (!task) {
71206
+ logForDebugging(`[InProcessBackend] terminate() failed: task not found for ${agentId}`);
71207
+ return false;
71208
+ }
71209
+ if (task.shutdownRequested) {
71210
+ logForDebugging(`[InProcessBackend] terminate(): shutdown already requested for ${agentId}`);
71211
+ return true;
71212
+ }
71213
+ const requestId = `shutdown-${agentId}-${Date.now()}`;
71214
+ const shutdownRequest = createShutdownRequestMessage({
71215
+ requestId,
71216
+ from: "team-lead",
71217
+ reason
71218
+ });
71219
+ const teammateAgentName = task.identity.agentName;
71220
+ await writeToMailbox(teammateAgentName, {
71221
+ from: "team-lead",
71222
+ text: jsonStringify(shutdownRequest),
71223
+ timestamp: new Date().toISOString()
71224
+ }, task.identity.teamName);
71225
+ requestTeammateShutdown(task.id, this.context.setAppState);
71226
+ logForDebugging(`[InProcessBackend] terminate() sent shutdown request to ${agentId}`);
71227
+ return true;
71228
+ }
71229
+ async kill(agentId) {
71230
+ logForDebugging(`[InProcessBackend] kill() called for ${agentId}`);
71231
+ if (!this.context) {
71232
+ logForDebugging(`[InProcessBackend] kill() failed: no context set for ${agentId}`);
71233
+ return false;
71234
+ }
71235
+ const state = this.context.getAppState();
71236
+ const task = findTeammateTaskByAgentId(agentId, state.tasks);
71237
+ if (!task) {
71238
+ logForDebugging(`[InProcessBackend] kill() failed: task not found for ${agentId}`);
71239
+ return false;
71240
+ }
71241
+ const killed = killInProcessTeammate(task.id, this.context.setAppState);
71242
+ logForDebugging(`[InProcessBackend] kill() ${killed ? "succeeded" : "failed"} for ${agentId}`);
71243
+ return killed;
71244
+ }
71245
+ async isActive(agentId) {
71246
+ logForDebugging(`[InProcessBackend] isActive() called for ${agentId}`);
71247
+ if (!this.context) {
71248
+ logForDebugging(`[InProcessBackend] isActive() failed: no context set for ${agentId}`);
71249
+ return false;
71250
+ }
71251
+ const state = this.context.getAppState();
71252
+ const task = findTeammateTaskByAgentId(agentId, state.tasks);
71253
+ if (!task) {
71254
+ logForDebugging(`[InProcessBackend] isActive(): task not found for ${agentId}`);
71255
+ return false;
71256
+ }
71257
+ const isRunning = task.status === "running";
71258
+ const isAborted = task.abortController?.signal.aborted ?? true;
71259
+ const active = isRunning && !isAborted;
71260
+ logForDebugging(`[InProcessBackend] isActive() for ${agentId}: ${active} (running=${isRunning}, aborted=${isAborted})`);
71261
+ return active;
71262
+ }
71263
+ }
71264
+ function createInProcessBackend() {
71265
+ return new InProcessBackend;
71266
+ }
70565
71267
  var init_InProcessBackend = __esm(() => {
70566
71268
  init_engine();
70567
71269
  init_shared();
@@ -71317,7 +72019,13 @@ function getBackendByType(type) {
71317
72019
  return createITermBackend();
71318
72020
  }
71319
72021
  }
71320
- var cachedBackend = null, cachedDetectionResult = null, backendsRegistered = false, TmuxBackendClass = null, ITermBackendClass = null;
72022
+ function getInProcessBackend() {
72023
+ if (!cachedInProcessBackend) {
72024
+ cachedInProcessBackend = createInProcessBackend();
72025
+ }
72026
+ return cachedInProcessBackend;
72027
+ }
72028
+ var cachedBackend = null, cachedDetectionResult = null, backendsRegistered = false, cachedInProcessBackend = null, TmuxBackendClass = null, ITermBackendClass = null;
71321
72029
  var init_registry = __esm(() => {
71322
72030
  init_bootstrap();
71323
72031
  init_shared();
@@ -71454,6 +72162,110 @@ var init_permissionSync = __esm(() => {
71454
72162
  });
71455
72163
  });
71456
72164
 
72165
+ // src/swarm/teammateTermination.ts
72166
+ function resolveTerminationSpec(spec) {
72167
+ return spec ?? DEFAULT_TEAMMATE_TERMINATION_SPEC;
72168
+ }
72169
+ function validateTerminationSpec(spec) {
72170
+ if (spec.op !== "or" && spec.op !== "and") {
72171
+ throw new Error(`teammate-termination config: op must be "or" or "and" (got ${String(spec.op)})`);
72172
+ }
72173
+ if (!Array.isArray(spec.conditions) || spec.conditions.length === 0) {
72174
+ throw new Error("teammate-termination config: conditions must be a non-empty array");
72175
+ }
72176
+ for (const c of spec.conditions) {
72177
+ switch (c.kind) {
72178
+ case "max-turns":
72179
+ if (!Number.isInteger(c.maxTurns) || c.maxTurns < 1) {
72180
+ throw new Error(`teammate-termination config: maxTurns must be an integer >= 1 (got ${String(c.maxTurns)})`);
72181
+ }
72182
+ break;
72183
+ case "text-confirm":
72184
+ if (!Array.isArray(c.phrases) || c.phrases.length === 0 || c.phrases.some((p) => typeof p !== "string" || p.length === 0)) {
72185
+ throw new Error("teammate-termination config: text-confirm phrases must be a non-empty array of non-empty strings");
72186
+ }
72187
+ break;
72188
+ case "stall":
72189
+ if (!Number.isInteger(c.maxConsecutive) || c.maxConsecutive < 2) {
72190
+ throw new Error(`teammate-termination config: stall maxConsecutive must be an integer >= 2 (got ${String(c.maxConsecutive)})`);
72191
+ }
72192
+ break;
72193
+ case "external-kill":
72194
+ break;
72195
+ default:
72196
+ throw new Error(`teammate-termination config: unknown condition kind (got ${JSON.stringify(c)})`);
72197
+ }
72198
+ }
72199
+ }
72200
+ function createInitialTerminationLoopState() {
72201
+ return { turns: 0, stallConsecutive: 0 };
72202
+ }
72203
+ function advanceTerminationLoopState(state, outcome) {
72204
+ const finalText = outcome.finalText;
72205
+ const stalled = typeof finalText === "string" && finalText.length > 0 && finalText === state.lastFinalText;
72206
+ return {
72207
+ turns: state.turns + 1,
72208
+ lastFinalText: finalText,
72209
+ stallConsecutive: stalled ? state.stallConsecutive + 1 : 0
72210
+ };
72211
+ }
72212
+ function evaluateCondition(c, state) {
72213
+ switch (c.kind) {
72214
+ case "max-turns":
72215
+ return state.turns >= c.maxTurns ? { type: "max-turns", turns: state.turns } : undefined;
72216
+ case "text-confirm": {
72217
+ const text = (state.lastFinalText ?? "").toLowerCase();
72218
+ const matched = c.phrases.find((p) => text.includes(p.toLowerCase()));
72219
+ return matched !== undefined ? { type: "text-confirm", matched } : undefined;
72220
+ }
72221
+ case "external-kill":
72222
+ return state.aborted ? { type: "external-kill" } : undefined;
72223
+ case "stall":
72224
+ return state.stallConsecutive >= c.maxConsecutive ? { type: "stall", consecutive: state.stallConsecutive } : undefined;
72225
+ }
72226
+ }
72227
+ function evaluateTerminationSpec(spec, state) {
72228
+ const reasons = spec.conditions.map((c) => evaluateCondition(c, state)).filter((r) => r !== undefined);
72229
+ if (spec.op === "or") {
72230
+ if (reasons.length === 0)
72231
+ return { terminate: false };
72232
+ return {
72233
+ terminate: true,
72234
+ reason: spec.conditions.length === 1 ? reasons[0] : { type: "or", satisfied: reasons }
72235
+ };
72236
+ }
72237
+ if (reasons.length !== spec.conditions.length)
72238
+ return { terminate: false };
72239
+ return {
72240
+ terminate: true,
72241
+ reason: spec.conditions.length === 1 ? reasons[0] : { type: "and", satisfied: reasons }
72242
+ };
72243
+ }
72244
+ function extractFinalAssistantText(messages) {
72245
+ for (let i = messages.length - 1;i >= 0; i--) {
72246
+ const m = messages[i];
72247
+ if (m?.role !== "assistant")
72248
+ continue;
72249
+ const content = m.content;
72250
+ if (typeof content === "string") {
72251
+ return content.length > 0 ? content : undefined;
72252
+ }
72253
+ if (Array.isArray(content)) {
72254
+ const text = content.map((b) => b && typeof b === "object" && b.type === "text" ? b.text : "").filter((t) => typeof t === "string").join("").trim();
72255
+ return text.length > 0 ? text : undefined;
72256
+ }
72257
+ return;
72258
+ }
72259
+ return;
72260
+ }
72261
+ var DEFAULT_TEAMMATE_MAX_TURNS = 200, DEFAULT_TEAMMATE_TERMINATION_SPEC;
72262
+ var init_teammateTermination = __esm(() => {
72263
+ DEFAULT_TEAMMATE_TERMINATION_SPEC = {
72264
+ op: "or",
72265
+ conditions: [{ kind: "max-turns", maxTurns: DEFAULT_TEAMMATE_MAX_TURNS }]
72266
+ };
72267
+ });
72268
+
71457
72269
  // src/swarm/inProcessRunner.ts
71458
72270
  import { randomUUID as randomUUID9 } from "node:crypto";
71459
72271
  function buildTeammateToolPermissionContext(narrow) {
@@ -71804,7 +72616,7 @@ async function tryClaimNextTask(taskListId, agentName) {
71804
72616
  }
71805
72617
  async function waitForNextPromptOrShutdown(identity, abortController, taskId, getAppState, setAppState, taskListId) {
71806
72618
  const POLL_INTERVAL_MS = 500;
71807
- logForDebugging(`[inProcessRunner] ${identity.agentName} starting poll loop (abort=${abortController.signal.aborted})`);
72619
+ logForDebugging(`[probe-R2][anchor3-poll-start] [inProcessRunner] ${identity.agentName} starting poll loop (abort=${abortController.signal.aborted}, controller=${probeReadAbortControllerId(abortController)})`);
71808
72620
  let pollCount = 0;
71809
72621
  while (!abortController.signal.aborted) {
71810
72622
  const appState = getAppState();
@@ -71923,6 +72735,7 @@ async function runInProcessTeammate(config) {
71923
72735
  const modelProvider = getModelProvider();
71924
72736
  const contextWindow = getProviderContextWindow(getRoleModel(role) ?? "") ?? HARD_DEFAULT_CONTEXT_WINDOW;
71925
72737
  logForDebugging(`[inProcessRunner] Starting agent loop for ${identity.agentId}`);
72738
+ logForDebugging(`[probe-R1][runner] agent=${identity.agentId} taskId=${taskId} controller=${probeReadAbortControllerId(abortController)}`);
71926
72739
  const teammateSystemPrompt = await buildTeammateSystemPrompt({
71927
72740
  systemPrompt,
71928
72741
  systemPromptMode,
@@ -71950,6 +72763,10 @@ async function runInProcessTeammate(config) {
71950
72763
  turnCounter: 0,
71951
72764
  turnId: "turn-0"
71952
72765
  };
72766
+ let termState = createInitialTerminationLoopState();
72767
+ let terminationReason;
72768
+ const effectiveTermination = resolveTerminationSpec(config.termination);
72769
+ validateTerminationSpec(effectiveTermination);
71953
72770
  try {
71954
72771
  updateTaskState(taskId, setAppState, (task) => ({
71955
72772
  ...task,
@@ -71998,7 +72815,7 @@ async function runInProcessTeammate(config) {
71998
72815
  const forkContextMessages = contextMessages.length > 0 ? [...contextMessages] : undefined;
71999
72816
  allMessages.push(userMessage);
72000
72817
  let workWasAborted = false;
72001
- await runWithTeammateContext2(teammateContext, async () => {
72818
+ await runWithTeammateContext(teammateContext, async () => {
72002
72819
  updateTaskState(taskId, setAppState, (task) => ({ ...task, status: "running", isIdle: false }));
72003
72820
  const agentResult = await runAgent({
72004
72821
  agentDefinition: resolvedAgentDefinition,
@@ -72010,11 +72827,16 @@ async function runInProcessTeammate(config) {
72010
72827
  agentId: identity.agentId,
72011
72828
  signal: currentWorkAbortController.signal,
72012
72829
  forkContextMessages,
72013
- checkPermission: createInProcessPermissionGate(identity, currentWorkAbortController, tools, getAppState, buildTeammateTpc)
72830
+ checkPermission: createInProcessPermissionGate(identity, currentWorkAbortController, tools, getAppState, buildTeammateTpc),
72831
+ toolContext: { getAppState, setAppState }
72014
72832
  });
72833
+ logForDebugging(`[probe-R2][anchor1-runagent-returned] agent=${identity.agentId} lifecycleAborted=${abortController.signal.aborted}`);
72015
72834
  const prefixLen = 2 + (forkContextMessages?.length ?? 0);
72016
72835
  const newMessages = agentResult.messages.slice(prefixLen);
72017
72836
  allMessages.push(...newMessages);
72837
+ termState = advanceTerminationLoopState(termState, {
72838
+ finalText: extractFinalAssistantText(newMessages)
72839
+ });
72018
72840
  updateTaskState(taskId, setAppState, (task) => ({
72019
72841
  ...task,
72020
72842
  messages: allMessages.slice(-MAX_TEAMMATE_DISPLAY_MESSAGES)
@@ -72047,13 +72869,24 @@ async function runInProcessTeammate(config) {
72047
72869
  return { ...task, isIdle: true, onIdleCallbacks: [] };
72048
72870
  });
72049
72871
  if (!wasAlreadyIdle) {
72872
+ logForDebugging(`[probe-R2][anchor2-idle-in] agent=${identity.agentName} lifecycleAborted=${abortController.signal.aborted}`);
72050
72873
  await sendIdleNotification(identity.agentName, identity.color, identity.teamName, {
72051
72874
  idleReason: workWasAborted ? "interrupted" : "available",
72052
72875
  summary: getLastPeerDmSummary(allMessages)
72053
72876
  });
72877
+ logForDebugging(`[probe-R2][anchor2-idle-out] agent=${identity.agentName} lifecycleAborted=${abortController.signal.aborted}`);
72054
72878
  } else {
72055
72879
  logForDebugging(`[inProcessRunner] Skipping duplicate idle notification for ${identity.agentName}`);
72056
72880
  }
72881
+ const terminationVerdict = evaluateTerminationSpec(effectiveTermination, {
72882
+ ...termState,
72883
+ aborted: abortController.signal.aborted
72884
+ });
72885
+ if (terminationVerdict.terminate) {
72886
+ logForDebugging(`[inProcessRunner] ${identity.agentId} termination condition met (${JSON.stringify(terminationVerdict.reason)}) — graceful exit`);
72887
+ terminationReason = terminationVerdict.reason;
72888
+ shouldExit = true;
72889
+ }
72057
72890
  logForDebugging(`[inProcessRunner] ${identity.agentId} finished prompt, waiting for next`);
72058
72891
  const waitResult = await waitForNextPromptOrShutdown(identity, abortController, taskId, getAppState, setAppState, identity.parentSessionId);
72059
72892
  switch (waitResult.type) {
@@ -72079,26 +72912,37 @@ async function runInProcessTeammate(config) {
72079
72912
  }
72080
72913
  let alreadyTerminal = false;
72081
72914
  let toolUseId;
72915
+ logForDebugging(`[probe-R6][completed-in] agent=${identity.agentId} taskId=${taskId}`);
72082
72916
  updateTaskState(taskId, setAppState, (task) => {
72083
- if (task.status !== "running") {
72084
- alreadyTerminal = true;
72085
- return task;
72917
+ logForDebugging(`[probe-R6][completed-updater-enter] agent=${identity.agentId} status=${task.status} recordId=${probeReadTaskRecordId(task)}`);
72918
+ try {
72919
+ if (!isInProcessTeammateLive(task)) {
72920
+ logForDebugging(`[probe-R6][completed-updater-notlive] agent=${identity.agentId}`);
72921
+ alreadyTerminal = true;
72922
+ return task;
72923
+ }
72924
+ toolUseId = task.toolUseId;
72925
+ task.onIdleCallbacks?.forEach((cb) => cb());
72926
+ task.unregisterCleanup?.();
72927
+ const completed = {
72928
+ ...task,
72929
+ status: "completed",
72930
+ notified: true,
72931
+ endTime: Date.now(),
72932
+ messages: task.messages?.length ? [task.messages.at(-1)] : undefined,
72933
+ pendingUserMessages: [],
72934
+ abortController: undefined,
72935
+ unregisterCleanup: undefined,
72936
+ onIdleCallbacks: []
72937
+ };
72938
+ logForDebugging(`[probe-R6][completed-updater-apply] agent=${identity.agentId} recordId=${probeReadTaskRecordId(completed)}`);
72939
+ return completed;
72940
+ } catch (error) {
72941
+ logForDebugging(`[probe-R6][completed-updater-throw] agent=${identity.agentId} ${error instanceof Error ? error.stack ?? error.message : String(error)}`);
72942
+ throw error;
72086
72943
  }
72087
- toolUseId = task.toolUseId;
72088
- task.onIdleCallbacks?.forEach((cb) => cb());
72089
- task.unregisterCleanup?.();
72090
- return {
72091
- ...task,
72092
- status: "completed",
72093
- notified: true,
72094
- endTime: Date.now(),
72095
- messages: task.messages?.length ? [task.messages.at(-1)] : undefined,
72096
- pendingUserMessages: [],
72097
- abortController: undefined,
72098
- unregisterCleanup: undefined,
72099
- onIdleCallbacks: []
72100
- };
72101
72944
  });
72945
+ logForDebugging(`[probe-R6][completed-out] agent=${identity.agentId}`);
72102
72946
  evictTaskOutput(taskId);
72103
72947
  if (!alreadyTerminal) {
72104
72948
  emitTaskTerminatedSdk(taskId, "completed", {
@@ -72106,14 +72950,18 @@ async function runInProcessTeammate(config) {
72106
72950
  summary: identity.agentId
72107
72951
  });
72108
72952
  }
72109
- return { success: true, messages: allMessages };
72953
+ return {
72954
+ success: true,
72955
+ messages: allMessages,
72956
+ ...terminationReason ? { terminationReason } : {}
72957
+ };
72110
72958
  } catch (error) {
72111
72959
  const errorMessage = error instanceof Error ? error.message : "Unknown error";
72112
72960
  logForDebugging(`[inProcessRunner] Agent ${identity.agentId} failed: ${errorMessage}`);
72113
72961
  let alreadyTerminal = false;
72114
72962
  let toolUseId;
72115
72963
  updateTaskState(taskId, setAppState, (task) => {
72116
- if (task.status !== "running") {
72964
+ if (!isInProcessTeammateLive(task)) {
72117
72965
  alreadyTerminal = true;
72118
72966
  return task;
72119
72967
  }
@@ -72167,15 +73015,16 @@ var init_inProcessRunner = __esm(() => {
72167
73015
  init_task2();
72168
73016
  init_engine();
72169
73017
  init_permissions3();
72170
- init_teammateContext2();
73018
+ init_shared();
72171
73019
  init_inProcessTeammateTask();
72172
73020
  init_permissionPoller();
72173
73021
  init_permissionSync();
73022
+ init_teammateTermination();
72174
73023
  });
72175
73024
 
72176
73025
  // src/swarm/index.ts
72177
73026
  var init_swarm = __esm(() => {
72178
- init_teammateContext2();
73027
+ init_teammateContext();
72179
73028
  init_standaloneAgent();
72180
73029
  init_teammateModel();
72181
73030
  init_permissionPoller();
@@ -72202,6 +73051,7 @@ var init_swarm = __esm(() => {
72202
73051
  init_PaneBackendExecutor();
72203
73052
  init_wireBackends();
72204
73053
  init_inProcessRunner();
73054
+ init_teammateTermination();
72205
73055
  init_shared();
72206
73056
  init_permissionSync();
72207
73057
  });
@@ -72238,6 +73088,18 @@ var init_remote = __esm(() => {
72238
73088
  init_udsInboxEnabled();
72239
73089
  });
72240
73090
 
73091
+ // src/engine/session/sessionContextPort.ts
73092
+ function setSessionContextPort(port) {
73093
+ _sessionContextPort = port;
73094
+ }
73095
+ function getSessionContextPort() {
73096
+ return _sessionContextPort;
73097
+ }
73098
+ function resetSessionContextPort() {
73099
+ _sessionContextPort = null;
73100
+ }
73101
+ var _sessionContextPort = null;
73102
+
72241
73103
  // src/engine/tools/team/sendMessagePrompt.ts
72242
73104
  function buildPrompt(udsRow, udsSection) {
72243
73105
  return `
@@ -72265,7 +73127,9 @@ If you receive a JSON message with \`type: "shutdown_request"\` or \`type: "plan
72265
73127
  {"to": "researcher", "message": {"type": "plan_approval_response", "request_id": "...", "approve": false, "feedback": "add error handling"}}
72266
73128
  \`\`\`
72267
73129
 
72268
- Approving shutdown terminates your process. Rejecting plan sends the teammate back to revise. Don't originate \`shutdown_request\` unless asked. Don't send structured JSON status messages — use TaskUpdate.`.trim();
73130
+ Approving shutdown terminates your process. Rejecting plan sends the teammate back to revise. Don't originate \`shutdown_request\` unless asked. Don't send structured JSON status messages — use TaskUpdate.
73131
+
73132
+ Always send protocol responses as JSON **objects** in the \`message\` field, exactly as shown above — never stringify them into a string. (String-encoded JSON of the three protocol types is tolerated as a fallback, but the object form is authoritative.)`.trim();
72269
73133
  }
72270
73134
  function getSendMessagePrompt() {
72271
73135
  const on = isUdsInboxEnabled();
@@ -72291,12 +73155,34 @@ var init_sendMessagePrompt = __esm(() => {
72291
73155
  });
72292
73156
 
72293
73157
  // src/engine/tools/team/sendMessageTool.ts
73158
+ function tryParseStructuredMessage(text) {
73159
+ let parsed;
73160
+ try {
73161
+ parsed = JSON.parse(text);
73162
+ } catch {
73163
+ return;
73164
+ }
73165
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
73166
+ return;
73167
+ }
73168
+ const type = parsed.type;
73169
+ if (type === "shutdown_request" || type === "shutdown_response" || type === "plan_approval_response") {
73170
+ return parsed;
73171
+ }
73172
+ return;
73173
+ }
72294
73174
  function setTeamFileLoader(loader) {
72295
73175
  teamFileLoader = loader;
72296
73176
  }
72297
73177
  function resetTeamFileLoader() {
72298
73178
  teamFileLoader = async () => null;
72299
73179
  }
73180
+ function resolveOutgoingTeamName(teamContext) {
73181
+ return getTeamName(teamContext) ?? peekTeamContext()?.teamName;
73182
+ }
73183
+ function unresolvedTeamMailboxError(recipient) {
73184
+ return new Error(`Cannot route message to "${recipient}": no team mailbox is resolvable ` + "(no teamContext in appState, no in-process teammate context, and no team " + "registered via TeamCreate). Create a team with TeamCreate first; the " + "message was NOT delivered.");
73185
+ }
72300
73186
  function truncatePreview(text, maxWidth) {
72301
73187
  if (text.length <= maxWidth)
72302
73188
  return text;
@@ -72304,7 +73190,9 @@ function truncatePreview(text, maxWidth) {
72304
73190
  }
72305
73191
  async function handleMessage(recipientName, content, summary, context) {
72306
73192
  const appState = context.getAppState();
72307
- const teamName = getTeamName(appState.teamContext);
73193
+ const teamName = resolveOutgoingTeamName(appState.teamContext);
73194
+ if (!teamName)
73195
+ throw unresolvedTeamMailboxError(recipientName);
72308
73196
  const senderName = getAgentName() || (isTeammate() ? "teammate" : TEAM_LEAD_NAME);
72309
73197
  const senderColor = getTeammateColor();
72310
73198
  await writeToMailbox(recipientName, {
@@ -72331,13 +73219,49 @@ async function handleMessage(recipientName, content, summary, context) {
72331
73219
  }
72332
73220
  async function handleBroadcast(content, summary, context) {
72333
73221
  const appState = context.getAppState();
72334
- const teamName = getTeamName(appState.teamContext);
73222
+ const teamName = resolveOutgoingTeamName(appState.teamContext);
72335
73223
  if (!teamName) {
72336
73224
  throw new Error("Not in a team context. Create a team with Teammate spawnTeam first, or set ATLAS_TEAM_NAME.");
72337
73225
  }
72338
- const teamFile = await teamFileLoader(teamName);
72339
- if (!teamFile) {
72340
- throw new Error(`Team "${teamName}" does not exist`);
73226
+ const memberNames = [];
73227
+ const seenNames = new Set;
73228
+ const pushMember = (raw) => {
73229
+ if (!raw)
73230
+ return;
73231
+ const key = raw.toLowerCase();
73232
+ if (!seenNames.has(key)) {
73233
+ seenNames.add(key);
73234
+ memberNames.push(raw);
73235
+ }
73236
+ };
73237
+ const servicesCtx = peekTeamContext();
73238
+ if (servicesCtx && servicesCtx.teamName === teamName) {
73239
+ for (const [agentId, m] of Object.entries(servicesCtx.teammates ?? {})) {
73240
+ pushMember(m.name || agentId);
73241
+ }
73242
+ for (const r of servicesCtx.roster ?? []) {
73243
+ pushMember(r.name);
73244
+ }
73245
+ } else if (appState.teamContext && appState.teamContext.teamName === teamName) {
73246
+ for (const [agentId, m] of Object.entries(appState.teamContext.teammates ?? {})) {
73247
+ pushMember(m.name || agentId);
73248
+ }
73249
+ }
73250
+ let teamFile = null;
73251
+ if (memberNames.length === 0) {
73252
+ teamFile = await teamFileLoader(teamName);
73253
+ if (!teamFile) {
73254
+ return {
73255
+ data: {
73256
+ success: true,
73257
+ message: "No teammates to broadcast to (team has no members yet)",
73258
+ recipients: []
73259
+ }
73260
+ };
73261
+ }
73262
+ for (const member of teamFile.members) {
73263
+ pushMember(member.name);
73264
+ }
72341
73265
  }
72342
73266
  const senderName = getAgentName() || (isTeammate() ? "teammate" : TEAM_LEAD_NAME);
72343
73267
  if (!senderName) {
@@ -72345,11 +73269,11 @@ async function handleBroadcast(content, summary, context) {
72345
73269
  }
72346
73270
  const senderColor = getTeammateColor();
72347
73271
  const recipients = [];
72348
- for (const member of teamFile.members) {
72349
- if (member.name.toLowerCase() === senderName.toLowerCase()) {
73272
+ for (const name of memberNames) {
73273
+ if (name.toLowerCase() === senderName.toLowerCase()) {
72350
73274
  continue;
72351
73275
  }
72352
- recipients.push(member.name);
73276
+ recipients.push(name);
72353
73277
  }
72354
73278
  if (recipients.length === 0) {
72355
73279
  return {
@@ -72386,7 +73310,9 @@ async function handleBroadcast(content, summary, context) {
72386
73310
  }
72387
73311
  async function handleShutdownRequest(targetName, reason, context) {
72388
73312
  const appState = context.getAppState();
72389
- const teamName = getTeamName(appState.teamContext);
73313
+ const teamName = resolveOutgoingTeamName(appState.teamContext);
73314
+ if (!teamName)
73315
+ throw unresolvedTeamMailboxError(targetName);
72390
73316
  const senderName = getAgentName() || TEAM_LEAD_NAME;
72391
73317
  const requestId = generateRequestId("shutdown", targetName);
72392
73318
  const shutdownMessage = createShutdownRequestMessage({
@@ -72410,7 +73336,9 @@ async function handleShutdownRequest(targetName, reason, context) {
72410
73336
  };
72411
73337
  }
72412
73338
  async function handleShutdownApproval(requestId, _context) {
72413
- const teamName = getTeamName();
73339
+ const teamName = resolveOutgoingTeamName();
73340
+ if (!teamName)
73341
+ throw unresolvedTeamMailboxError(TEAM_LEAD_NAME);
72414
73342
  const agentId = getAgentId();
72415
73343
  const agentName = getAgentName() || "teammate";
72416
73344
  logForDebugging(`[SendMessageTool] handleShutdownApproval: teamName=${teamName}, agentId=${agentId}, agentName=${agentName}`);
@@ -72424,16 +73352,32 @@ async function handleShutdownApproval(requestId, _context) {
72424
73352
  timestamp: new Date().toISOString(),
72425
73353
  color: getTeammateColor()
72426
73354
  }, teamName);
73355
+ let exitTriggered = false;
73356
+ try {
73357
+ const port = getSessionContextPort();
73358
+ const memberTask = port ? findInProcessTeammateTaskByAgentId(port.get().tasks, agentId ?? "") : undefined;
73359
+ if (port) {
73360
+ const tasksAll = port.get().tasks ?? {};
73361
+ const sameAgentEntries = Object.entries(tasksAll).filter(([, t]) => t?.identity?.agentId === agentId);
73362
+ logForDebugging(`[probe-R1][trigger] agent=${agentId} taskEntries=${Object.keys(tasksAll).length} sameAgentId=${sameAgentEntries.map(([k, t]) => `${k}:${t.status ?? "unknown"}`).join("|") || "none"} firstHit=${memberTask ? "yes" : "no"} controller=${probeReadAbortControllerId(memberTask?.abortController)} live=${isInProcessTeammateLive(memberTask)} recordId=${probeReadTaskRecordId(memberTask)}`);
73363
+ }
73364
+ if (isInProcessTeammateLive(memberTask) && memberTask.abortController) {
73365
+ memberTask.abortController.abort();
73366
+ exitTriggered = true;
73367
+ }
73368
+ } catch {}
72427
73369
  return {
72428
73370
  data: {
72429
73371
  success: true,
72430
- message: `Shutdown approved. Sent confirmation to team-lead. Agent ${agentName} is now exiting.`,
73372
+ message: exitTriggered ? `Shutdown approved. Confirmation sent to team-lead; exit sequence triggered for agent ${agentName}.` : `Shutdown approved. Confirmation sent to team-lead; agent ${agentName} will exit on its next lifecycle check.`,
72431
73373
  request_id: requestId
72432
73374
  }
72433
73375
  };
72434
73376
  }
72435
73377
  async function handleShutdownRejection(requestId, reason) {
72436
- const teamName = getTeamName();
73378
+ const teamName = resolveOutgoingTeamName();
73379
+ if (!teamName)
73380
+ throw unresolvedTeamMailboxError(TEAM_LEAD_NAME);
72437
73381
  const agentName = getAgentName() || "teammate";
72438
73382
  const rejectedMessage = createShutdownRejectedMessage({
72439
73383
  requestId,
@@ -72456,7 +73400,9 @@ async function handleShutdownRejection(requestId, reason) {
72456
73400
  }
72457
73401
  async function handlePlanApproval(recipientName, requestId, context) {
72458
73402
  const appState = context.getAppState();
72459
- const teamName = appState.teamContext?.teamName;
73403
+ const teamName = resolveOutgoingTeamName(appState.teamContext);
73404
+ if (!teamName)
73405
+ throw unresolvedTeamMailboxError(recipientName);
72460
73406
  if (!isTeamLead(appState.teamContext)) {
72461
73407
  throw new Error("Only the team lead can approve plans. Teammates cannot approve their own or other plans.");
72462
73408
  }
@@ -72484,7 +73430,9 @@ async function handlePlanApproval(recipientName, requestId, context) {
72484
73430
  }
72485
73431
  async function handlePlanRejection(recipientName, requestId, feedback, context) {
72486
73432
  const appState = context.getAppState();
72487
- const teamName = appState.teamContext?.teamName;
73433
+ const teamName = resolveOutgoingTeamName(appState.teamContext);
73434
+ if (!teamName)
73435
+ throw unresolvedTeamMailboxError(recipientName);
72488
73436
  if (!isTeamLead(appState.teamContext)) {
72489
73437
  throw new Error("Only the team lead can reject plans. Teammates cannot reject their own or other plans.");
72490
73438
  }
@@ -72508,12 +73456,29 @@ async function handlePlanRejection(recipientName, requestId, feedback, context)
72508
73456
  }
72509
73457
  };
72510
73458
  }
73459
+ async function dispatchStructuredMessage(message, to, ctx) {
73460
+ switch (message.type) {
73461
+ case "shutdown_request":
73462
+ return handleShutdownRequest(to, message.reason, ctx);
73463
+ case "shutdown_response":
73464
+ if (message.approve) {
73465
+ return handleShutdownApproval(message.request_id, ctx);
73466
+ }
73467
+ return handleShutdownRejection(message.request_id, message.reason);
73468
+ case "plan_approval_response":
73469
+ if (message.approve) {
73470
+ return handlePlanApproval(to, message.request_id, ctx);
73471
+ }
73472
+ return handlePlanRejection(to, message.request_id, message.feedback ?? "Plan needs revision", ctx);
73473
+ }
73474
+ }
72511
73475
  var SEND_MESSAGE_TOOL_INPUT_SCHEMA, teamFileLoader = async () => null, SendMessageTool;
72512
73476
  var init_sendMessageTool = __esm(() => {
72513
73477
  init_shared();
72514
73478
  init_remote();
72515
73479
  init_messaging();
72516
73480
  init_json();
73481
+ init_task2();
72517
73482
  init_toolNames();
72518
73483
  init_sendMessagePrompt();
72519
73484
  SEND_MESSAGE_TOOL_INPUT_SCHEMA = {
@@ -72611,6 +73576,8 @@ var init_sendMessageTool = __esm(() => {
72611
73576
  },
72612
73577
  async validateInput(input, _context) {
72613
73578
  const i = input;
73579
+ const sniffedMessage = typeof i.message === "string" ? tryParseStructuredMessage(i.message) : undefined;
73580
+ const message = sniffedMessage ?? i.message;
72614
73581
  if (i.to.trim().length === 0) {
72615
73582
  return {
72616
73583
  result: false,
@@ -72634,7 +73601,7 @@ var init_sendMessageTool = __esm(() => {
72634
73601
  };
72635
73602
  }
72636
73603
  if (isUdsInboxEnabled() && parseAddress(i.to).scheme === "bridge") {
72637
- if (typeof i.message !== "string") {
73604
+ if (typeof message !== "string") {
72638
73605
  return {
72639
73606
  result: false,
72640
73607
  message: "structured messages cannot be sent cross-session — only plain text",
@@ -72650,10 +73617,10 @@ var init_sendMessageTool = __esm(() => {
72650
73617
  }
72651
73618
  return { result: true };
72652
73619
  }
72653
- if (isUdsInboxEnabled() && parseAddress(i.to).scheme === "uds" && typeof i.message === "string") {
73620
+ if (isUdsInboxEnabled() && parseAddress(i.to).scheme === "uds" && typeof message === "string") {
72654
73621
  return { result: true };
72655
73622
  }
72656
- if (typeof i.message === "string") {
73623
+ if (typeof message === "string") {
72657
73624
  if (!i.summary || i.summary.trim().length === 0) {
72658
73625
  return {
72659
73626
  result: false,
@@ -72677,14 +73644,14 @@ var init_sendMessageTool = __esm(() => {
72677
73644
  errorCode: 9
72678
73645
  };
72679
73646
  }
72680
- if (i.message.type === "shutdown_response" && i.to !== TEAM_LEAD_NAME) {
73647
+ if (message.type === "shutdown_response" && i.to !== TEAM_LEAD_NAME) {
72681
73648
  return {
72682
73649
  result: false,
72683
73650
  message: `shutdown_response must be sent to "${TEAM_LEAD_NAME}"`,
72684
73651
  errorCode: 9
72685
73652
  };
72686
73653
  }
72687
- if (i.message.type === "shutdown_response" && !i.message.approve && (!i.message.reason || i.message.reason.trim().length === 0)) {
73654
+ if (message.type === "shutdown_response" && !message.approve && (!message.reason || message.reason.trim().length === 0)) {
72688
73655
  return {
72689
73656
  result: false,
72690
73657
  message: "reason is required when rejecting a shutdown request",
@@ -72751,6 +73718,13 @@ var init_sendMessageTool = __esm(() => {
72751
73718
  }
72752
73719
  }
72753
73720
  }
73721
+ const sniffed = typeof input.message === "string" ? tryParseStructuredMessage(input.message) : undefined;
73722
+ if (sniffed !== undefined) {
73723
+ if (input.to === "*") {
73724
+ throw new Error("structured messages cannot be broadcast");
73725
+ }
73726
+ return dispatchStructuredMessage(sniffed, input.to, ctx);
73727
+ }
72754
73728
  if (typeof input.message === "string") {
72755
73729
  if (input.to === "*") {
72756
73730
  return handleBroadcast(input.message, input.summary, ctx);
@@ -72760,20 +73734,7 @@ var init_sendMessageTool = __esm(() => {
72760
73734
  if (input.to === "*") {
72761
73735
  throw new Error("structured messages cannot be broadcast");
72762
73736
  }
72763
- switch (input.message.type) {
72764
- case "shutdown_request":
72765
- return handleShutdownRequest(input.to, input.message.reason, ctx);
72766
- case "shutdown_response":
72767
- if (input.message.approve) {
72768
- return handleShutdownApproval(input.message.request_id, ctx);
72769
- }
72770
- return handleShutdownRejection(input.message.request_id, input.message.reason);
72771
- case "plan_approval_response":
72772
- if (input.message.approve) {
72773
- return handlePlanApproval(input.to, input.message.request_id, ctx);
72774
- }
72775
- return handlePlanRejection(input.to, input.message.request_id, input.message.feedback ?? "Plan needs revision", ctx);
72776
- }
73737
+ return dispatchStructuredMessage(input.message, input.to, ctx);
72777
73738
  },
72778
73739
  renderToolUseMessage(input) {
72779
73740
  const { message, to } = input ?? {};
@@ -73365,29 +74326,6 @@ var init_tasks2 = __esm(() => {
73365
74326
  init_tasks();
73366
74327
  });
73367
74328
 
73368
- // src/engine/tools/team/teamServices.ts
73369
- function setTeamServices(services) {
73370
- active = services;
73371
- }
73372
- function resetTeamServices() {
73373
- active = undefined;
73374
- }
73375
- function requireTeamServices() {
73376
- if (!active) {
73377
- throw new Error("TeamServices not wired — call setTeamServices at composition root first (swarm team-file seam, C 桶 ③ S-E2d)");
73378
- }
73379
- return active;
73380
- }
73381
- function createDefaultTeamContextStore() {
73382
- return {
73383
- getTeamContext: () => teamContext,
73384
- setTeamContext: (ctx) => {
73385
- teamContext = ctx;
73386
- }
73387
- };
73388
- }
73389
- var active, teamContext;
73390
-
73391
74329
  // src/engine/tools/team/teamCreatePrompt.ts
73392
74330
  var PROMPT4;
73393
74331
  var init_teamCreatePrompt = __esm(() => {
@@ -73423,7 +74361,7 @@ Create a new team to coordinate multiple agents working on a project. Teams have
73423
74361
  \`\`\`
73424
74362
 
73425
74363
  This creates:
73426
- - A team file at \`~/.atlas/teams/{team-name}/config.json\`
74364
+ - An in-memory team context on the leader (Form A is zero-persistence — no team file is written to \`~/.atlas/teams/\`; the member roster lives in the leader's team context)
73427
74365
  - A corresponding task list directory at \`~/.atlas/tasks/{team-name}/\`
73428
74366
 
73429
74367
  ## Team Workflow
@@ -73465,23 +74403,14 @@ Teammates go idle after every turn—this is completely normal and expected. A t
73465
74403
 
73466
74404
  ## Discovering Team Members
73467
74405
 
73468
- Teammates can read the team config file to discover other team members:
73469
- - **Team config location**: \`~/.atlas/teams/{team-name}/config.json\`
73470
-
73471
- The config file contains a \`members\` array with each teammate's:
74406
+ Form A teams are zero-persistence: no team config file is written to disk. Team members come from the \`members\` roster passed to TeamCreate (carried in the leader's team context). Each roster entry has:
73472
74407
  - \`name\`: Human-readable name (**always use this** for messaging and task assignment)
73473
- - \`agentId\`: Unique identifier (for reference only - do not use for communication)
73474
- - \`agentType\`: Role/type of the agent
74408
+ - \`role\`/\`goal\`/\`backstory\`: Role triplet used to compose the member's prompt when spawned via Agent(name, team_name)
73475
74409
 
73476
74410
  **IMPORTANT**: Always refer to teammates by their NAME (e.g., "team-lead", "researcher", "tester"). Names are used for:
73477
74411
  - \`to\` when sending messages
73478
74412
  - Identifying task owners
73479
74413
 
73480
- Example of reading team config:
73481
- \`\`\`
73482
- Use the Read tool to read ~/.atlas/teams/{team-name}/config.json
73483
- \`\`\`
73484
-
73485
74414
  ## Task List Coordination
73486
74415
 
73487
74416
  Teams share a task list that all teammates can access at \`~/.atlas/tasks/{team-name}/\`.
@@ -73515,7 +74444,6 @@ function generateUniqueTeamName(providedName) {
73515
74444
  var TEAM_CREATE_TOOL_INPUT_SCHEMA, TeamCreateTool;
73516
74445
  var init_teamCreateTool = __esm(() => {
73517
74446
  init_bootstrap();
73518
- init_modelprovider2();
73519
74447
  init_tasks2();
73520
74448
  init_messaging();
73521
74449
  init_json();
@@ -73536,6 +74464,33 @@ var init_teamCreateTool = __esm(() => {
73536
74464
  agent_type: {
73537
74465
  type: "string",
73538
74466
  description: 'Type/role of the team lead (e.g., "researcher", "test-runner"). ' + "Used for team file and inter-agent coordination."
74467
+ },
74468
+ members: {
74469
+ type: "array",
74470
+ description: "Optional roster of team members to plan for this team. Each entry " + "carries an optional role/goal/backstory triplet used to compose the " + "member's prompt when spawned via Agent(name, team_name).",
74471
+ items: {
74472
+ type: "object",
74473
+ properties: {
74474
+ name: {
74475
+ type: "string",
74476
+ description: "Member name (used as the spawn identity)."
74477
+ },
74478
+ role: {
74479
+ type: "string",
74480
+ description: "Role label resolved against the role template registry."
74481
+ },
74482
+ goal: {
74483
+ type: "string",
74484
+ description: "This member's goal for the team's current task."
74485
+ },
74486
+ backstory: {
74487
+ type: "string",
74488
+ description: "This member's background/context for prompt composition."
74489
+ }
74490
+ },
74491
+ required: ["name"],
74492
+ additionalProperties: false
74493
+ }
73539
74494
  }
73540
74495
  },
73541
74496
  required: ["team_name"],
@@ -73569,6 +74524,17 @@ var init_teamCreateTool = __esm(() => {
73569
74524
  errorCode: 9
73570
74525
  };
73571
74526
  }
74527
+ if (i.members) {
74528
+ for (const m of i.members) {
74529
+ if (!m || typeof m !== "object" || !m.name || m.name.trim().length === 0) {
74530
+ return {
74531
+ result: false,
74532
+ message: "each team member requires a non-empty name",
74533
+ errorCode: 9
74534
+ };
74535
+ }
74536
+ }
74537
+ }
73572
74538
  return { result: true };
73573
74539
  },
73574
74540
  async description() {
@@ -73596,29 +74562,8 @@ var init_teamCreateTool = __esm(() => {
73596
74562
  const finalTeamName = generateUniqueTeamName(input.team_name);
73597
74563
  const leadAgentId = formatAgentId(TEAM_LEAD_NAME, finalTeamName);
73598
74564
  const leadAgentType = input.agent_type || TEAM_LEAD_NAME;
73599
- const leadModel = getRoleModel("premium");
73600
74565
  const teamFilePath = services.getTeamFilePath(finalTeamName);
73601
- const teamFile = {
73602
- name: finalTeamName,
73603
- description: input.description,
73604
- createdAt: Date.now(),
73605
- leadAgentId,
73606
- leadSessionId: getSessionId(),
73607
- members: [
73608
- {
73609
- agentId: leadAgentId,
73610
- name: TEAM_LEAD_NAME,
73611
- agentType: leadAgentType,
73612
- model: leadModel,
73613
- joinedAt: Date.now(),
73614
- tmuxPaneId: "",
73615
- cwd: getCwd(),
73616
- subscriptions: []
73617
- }
73618
- ]
73619
- };
73620
- await services.writeTeamFileAsync(finalTeamName, teamFile);
73621
- services.registerTeamForSessionCleanup(finalTeamName);
74566
+ const roster = input.members && input.members.length > 0 ? input.members : undefined;
73622
74567
  const taskListId = services.sanitizeName(finalTeamName);
73623
74568
  await resetTaskList(taskListId);
73624
74569
  await ensureTasksDir(taskListId);
@@ -73627,6 +74572,7 @@ var init_teamCreateTool = __esm(() => {
73627
74572
  teamName: finalTeamName,
73628
74573
  teamFilePath,
73629
74574
  leadAgentId,
74575
+ roster,
73630
74576
  teammates: {
73631
74577
  [leadAgentId]: {
73632
74578
  name: TEAM_LEAD_NAME,
@@ -73679,6 +74625,7 @@ var init_teamDeleteTool = __esm(() => {
73679
74625
  init_tasks2();
73680
74626
  init_messaging();
73681
74627
  init_json();
74628
+ init_task2();
73682
74629
  init_toolNames();
73683
74630
  init_teamDeletePrompt();
73684
74631
  TEAM_DELETE_TOOL_INPUT_SCHEMA = {
@@ -73720,7 +74667,8 @@ var init_teamDeleteTool = __esm(() => {
73720
74667
  },
73721
74668
  async call(_args, _context) {
73722
74669
  const services = requireTeamServices();
73723
- const teamName = services.getTeamContext()?.teamName;
74670
+ const teamContext = services.getTeamContext();
74671
+ const teamName = teamContext?.teamName;
73724
74672
  if (teamName) {
73725
74673
  const teamFile = services.readTeamFile(teamName);
73726
74674
  if (teamFile) {
@@ -73731,7 +74679,22 @@ var init_teamDeleteTool = __esm(() => {
73731
74679
  return {
73732
74680
  data: {
73733
74681
  success: false,
73734
- message: `Cannot cleanup team with ${activeMembers.length} active member(s): ${memberNames}. Use requestShutdown to gracefully terminate teammates first.`,
74682
+ message: `Cannot cleanup team with ${activeMembers.length} active member(s): ${memberNames}. Send each active member a shutdown request via SendMessage first (message: {"type":"shutdown_request","request_id":"<id>","reason":"<why>"}), and wait for their shutdown approval and exit before retrying TeamDelete.`,
74683
+ team_name: teamName
74684
+ }
74685
+ };
74686
+ }
74687
+ }
74688
+ const teammateEntries = Object.entries(teamContext?.teammates ?? {}).filter(([, member]) => member.name !== TEAM_LEAD_NAME);
74689
+ if (teammateEntries.length > 0) {
74690
+ const tasks = getSessionContextPort()?.get().tasks;
74691
+ const alive = teammateEntries.filter(([, member]) => isInProcessTeammateActiveOrUnknown(tasks?.[member.taskId ?? ""]));
74692
+ if (alive.length > 0) {
74693
+ const memberNames = alive.map(([, member]) => member.name).join(", ");
74694
+ return {
74695
+ data: {
74696
+ success: false,
74697
+ message: `Cannot cleanup team with ${alive.length} active member(s): ${memberNames}. Send each active member a shutdown request via SendMessage first (message: {"type":"shutdown_request","request_id":"<id>","reason":"<why>"}), and wait for their shutdown approval and exit before retrying TeamDelete.`,
73735
74698
  team_name: teamName
73736
74699
  }
73737
74700
  };
@@ -73757,6 +74720,171 @@ var init_teamDeleteTool = __esm(() => {
73757
74720
  };
73758
74721
  });
73759
74722
 
74723
+ // src/engine/tools/team/waitForTeammatesPrompt.ts
74724
+ var PROMPT6 = `Wait for all currently working in-process teammates to become idle, then return.
74725
+
74726
+ Use this tool instead of repeatedly polling with other tools when you are waiting for teammates to finish their work, to acknowledge a shutdown request, or to exit after you sent them instructions. One call replaces many polling rounds.
74727
+
74728
+ The call blocks (event-driven, no busy-waiting) until every working teammate is idle, or until the timeout expires:
74729
+
74730
+ - On success it returns { status: 'idle', waited_ms, idle }.
74731
+ - On timeout it returns { status: 'timeout', waited_ms, still_working } listing the teammates that are still working — it never blocks forever. You may call again with a longer timeout, or proceed without those teammates.
74732
+
74733
+ This tool never aborts or kills teammates; it only waits. Graceful termination is driven by shutdown requests via SendMessage, and cleanup remains TeamDelete's responsibility. When no teammates are working, it returns immediately with status 'idle'.
74734
+
74735
+ Parameters:
74736
+ - timeout: Maximum time to wait in milliseconds (default 120000, maximum 600000).
74737
+ `;
74738
+
74739
+ // src/engine/tools/team/waitForTeammatesTool.ts
74740
+ function sessionStateUnavailableError() {
74741
+ return new Error("No session state is available in the current context " + "(SessionContextPort is not injected). WaitForTeammates requires the " + "engine composition root (in-process teammates live in the session " + "task registry). Create a team with TeamCreate and spawn teammates first.");
74742
+ }
74743
+ function listWorkingTeammateNames(appState) {
74744
+ const names = [];
74745
+ for (const task of Object.values(appState.tasks)) {
74746
+ if (isInProcessTeammateWorking(task)) {
74747
+ names.push(task.identity.agentName);
74748
+ }
74749
+ }
74750
+ return names;
74751
+ }
74752
+ var WAIT_FOR_TEAMMATES_TOOL_INPUT_SCHEMA, WAIT_FOR_TEAMMATES_DEFAULT_TIMEOUT_MS = 120000, WAIT_FOR_TEAMMATES_MAX_TIMEOUT_MS = 600000, WaitForTeammatesTool;
74753
+ var init_waitForTeammatesTool = __esm(() => {
74754
+ init_messaging();
74755
+ init_task2();
74756
+ init_json();
74757
+ init_toolNames();
74758
+ WAIT_FOR_TEAMMATES_TOOL_INPUT_SCHEMA = {
74759
+ type: "object",
74760
+ properties: {
74761
+ timeout: {
74762
+ type: "number",
74763
+ minimum: 0,
74764
+ maximum: 600000,
74765
+ default: 120000,
74766
+ description: "Max time to wait in milliseconds (default 120000)"
74767
+ }
74768
+ },
74769
+ additionalProperties: false
74770
+ };
74771
+ WaitForTeammatesTool = {
74772
+ name: WAIT_FOR_TEAMMATES_TOOL_NAME,
74773
+ inputSchema: WAIT_FOR_TEAMMATES_TOOL_INPUT_SCHEMA,
74774
+ inputJSONSchema: WAIT_FOR_TEAMMATES_TOOL_INPUT_SCHEMA,
74775
+ strict: true,
74776
+ searchHint: "wait for teammates to finish or acknowledge",
74777
+ maxResultSizeChars: 1e5,
74778
+ shouldDefer: true,
74779
+ isEnabled: () => isAgentSwarmsEnabled(),
74780
+ isReadOnly: () => true,
74781
+ isDestructive: () => false,
74782
+ isConcurrencySafe: () => true,
74783
+ userFacingName: () => "Wait For Teammates",
74784
+ toAutoClassifierInput: () => "",
74785
+ async checkPermissions(input) {
74786
+ return { behavior: "allow", updatedInput: input };
74787
+ },
74788
+ async description() {
74789
+ return PROMPT6;
74790
+ },
74791
+ mapToolResultToToolResultBlockParam(data, toolUseID) {
74792
+ return {
74793
+ tool_use_id: toolUseID,
74794
+ type: "tool_result",
74795
+ content: [
74796
+ {
74797
+ type: "text",
74798
+ text: jsonStringify(data)
74799
+ }
74800
+ ]
74801
+ };
74802
+ },
74803
+ renderToolUseMessage(input) {
74804
+ const { timeout } = input ?? {};
74805
+ if (timeout !== undefined) {
74806
+ return `waiting for teammates (up to ${timeout}ms)`;
74807
+ }
74808
+ return "waiting for teammates";
74809
+ },
74810
+ async call(args) {
74811
+ const { timeout = WAIT_FOR_TEAMMATES_DEFAULT_TIMEOUT_MS } = args;
74812
+ const effectiveTimeout = Math.min(Math.max(0, timeout), WAIT_FOR_TEAMMATES_MAX_TIMEOUT_MS);
74813
+ const port = getSessionContextPort();
74814
+ if (!port) {
74815
+ throw sessionStateUnavailableError();
74816
+ }
74817
+ const snapshot = port.get();
74818
+ const appState = {
74819
+ tasks: snapshot.tasks ?? {}
74820
+ };
74821
+ const startedAt = Date.now();
74822
+ const workingNames = listWorkingTeammateNames(appState);
74823
+ if (workingNames.length === 0) {
74824
+ return {
74825
+ data: { status: "idle", waited_ms: 0, idle: [], still_working: [] }
74826
+ };
74827
+ }
74828
+ const setAppState = (updater) => {
74829
+ port.set((prev) => {
74830
+ const next = updater({
74831
+ tasks: prev.tasks ?? {}
74832
+ });
74833
+ return {
74834
+ ...prev,
74835
+ tasks: next.tasks
74836
+ };
74837
+ });
74838
+ };
74839
+ let timer;
74840
+ try {
74841
+ const outcome = await Promise.race([
74842
+ waitForTeammatesToBecomeIdle(setAppState, appState).then(() => "idle"),
74843
+ new Promise((resolve) => {
74844
+ timer = setTimeout(() => resolve("timeout"), effectiveTimeout);
74845
+ })
74846
+ ]);
74847
+ const waitedMs = Date.now() - startedAt;
74848
+ const nowWorking = listWorkingTeammateNames({
74849
+ tasks: port.get().tasks ?? {}
74850
+ });
74851
+ const idleNames = workingNames.filter((name) => !nowWorking.includes(name));
74852
+ if (outcome === "timeout" && nowWorking.length === 0) {
74853
+ return {
74854
+ data: {
74855
+ status: "idle",
74856
+ waited_ms: waitedMs,
74857
+ idle: idleNames,
74858
+ still_working: []
74859
+ }
74860
+ };
74861
+ }
74862
+ if (outcome === "idle") {
74863
+ return {
74864
+ data: {
74865
+ status: "idle",
74866
+ waited_ms: waitedMs,
74867
+ idle: idleNames,
74868
+ still_working: []
74869
+ }
74870
+ };
74871
+ }
74872
+ return {
74873
+ data: {
74874
+ status: "timeout",
74875
+ waited_ms: waitedMs,
74876
+ idle: idleNames,
74877
+ still_working: nowWorking
74878
+ }
74879
+ };
74880
+ } finally {
74881
+ if (timer)
74882
+ clearTimeout(timer);
74883
+ }
74884
+ }
74885
+ };
74886
+ });
74887
+
73760
74888
  // src/engine/tools/team/index.ts
73761
74889
  var init_team = __esm(() => {
73762
74890
  init_sendMessageTool();
@@ -73767,6 +74895,7 @@ var init_team = __esm(() => {
73767
74895
  init_teamCreatePrompt();
73768
74896
  init_teamDeleteTool();
73769
74897
  init_teamDeletePrompt();
74898
+ init_waitForTeammatesTool();
73770
74899
  });
73771
74900
 
73772
74901
  // src/engine/scheduler/cron.ts
@@ -75009,7 +76138,7 @@ var init_taskCreateTool = __esm(() => {
75009
76138
  });
75010
76139
 
75011
76140
  // src/engine/tools/tasks/taskGetPrompt.ts
75012
- var PROMPT6 = `Use this tool to retrieve a task by its ID from the task list.
76141
+ var PROMPT7 = `Use this tool to retrieve a task by its ID from the task list.
75013
76142
 
75014
76143
  ## When to Use This Tool
75015
76144
 
@@ -75064,7 +76193,7 @@ var init_taskGetTool = __esm(() => {
75064
76193
  behavior: "allow",
75065
76194
  updatedInput: input
75066
76195
  }),
75067
- description: async () => PROMPT6,
76196
+ description: async () => PROMPT7,
75068
76197
  async call(args) {
75069
76198
  const { taskId } = args;
75070
76199
  const taskListId = getTaskListId();
@@ -75231,7 +76360,7 @@ var init_taskListTool = __esm(() => {
75231
76360
  });
75232
76361
 
75233
76362
  // src/engine/tools/tasks/taskUpdatePrompt.ts
75234
- var PROMPT7 = `Use this tool to update a task in the task list.
76363
+ var PROMPT8 = `Use this tool to update a task in the task list.
75235
76364
 
75236
76365
  ## When to Use This Tool
75237
76366
 
@@ -75385,7 +76514,7 @@ var init_taskUpdateTool = __esm(() => {
75385
76514
  behavior: "allow",
75386
76515
  updatedInput: input
75387
76516
  }),
75388
- description: async () => PROMPT7,
76517
+ description: async () => PROMPT8,
75389
76518
  async call(args, context) {
75390
76519
  const {
75391
76520
  taskId,
@@ -75556,7 +76685,7 @@ Task completed. Call TaskList now to find your next available task or see if you
75556
76685
  });
75557
76686
 
75558
76687
  // src/engine/tools/tasks/taskStopPrompt.ts
75559
- var DESCRIPTION10 = `
76688
+ var DESCRIPTION11 = `
75560
76689
  - Stops a running background task by its ID
75561
76690
  - Takes a task_id parameter identifying the task to stop
75562
76691
  - Returns a success or failure status
@@ -75602,7 +76731,7 @@ var init_taskStopTool = __esm(() => {
75602
76731
  behavior: "allow",
75603
76732
  updatedInput: input
75604
76733
  }),
75605
- description: async () => DESCRIPTION10,
76734
+ description: async () => DESCRIPTION11,
75606
76735
  async validateInput(input, context) {
75607
76736
  const { task_id, shell_id } = input;
75608
76737
  const ctx = context;
@@ -75665,10 +76794,10 @@ var init_taskStopTool = __esm(() => {
75665
76794
  });
75666
76795
 
75667
76796
  // src/engine/tools/tasks/todoWritePrompt.ts
75668
- var PROMPT8;
76797
+ var PROMPT9;
75669
76798
  var init_todoWritePrompt = __esm(() => {
75670
76799
  init_toolNames();
75671
- PROMPT8 = `Use this tool to create and manage a structured task list for your current coding session. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user.
76800
+ PROMPT9 = `Use this tool to create and manage a structured task list for your current coding session. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user.
75672
76801
  It also helps the user understand the progress of the task and overall progress of their requests.
75673
76802
 
75674
76803
  ## When to Use This Tool
@@ -75906,7 +77035,7 @@ var init_todoWriteTool = __esm(() => {
75906
77035
  behavior: "allow",
75907
77036
  updatedInput: input
75908
77037
  }),
75909
- description: async () => PROMPT8,
77038
+ description: async () => PROMPT9,
75910
77039
  async call(args, context) {
75911
77040
  const { todos } = args;
75912
77041
  const ctx = context;
@@ -75941,7 +77070,7 @@ var init_todoWriteTool = __esm(() => {
75941
77070
  });
75942
77071
 
75943
77072
  // src/engine/tools/tasks/taskOutputPrompt.ts
75944
- var PROMPT9 = `DEPRECATED: Prefer using the Read tool on the task's output file path instead. Background tasks return their output file path in the tool result, and you receive a <task-notification> with the same path when the task completes — Read that file directly.
77073
+ var PROMPT10 = `DEPRECATED: Prefer using the Read tool on the task's output file path instead. Background tasks return their output file path in the tool result, and you receive a <task-notification> with the same path when the task completes — Read that file directly.
75945
77074
 
75946
77075
  - Retrieves output from a running or completed task (background shell, agent, or remote session)
75947
77076
  - Takes a task_id parameter identifying the task
@@ -76068,7 +77197,7 @@ var init_taskOutputTool = __esm(() => {
76068
77197
  behavior: "allow",
76069
77198
  updatedInput: input
76070
77199
  }),
76071
- description: async () => PROMPT9,
77200
+ description: async () => PROMPT10,
76072
77201
  async validateInput(input, context) {
76073
77202
  const { task_id } = input;
76074
77203
  const ctx = context;
@@ -76080,6 +77209,13 @@ var init_taskOutputTool = __esm(() => {
76080
77209
  };
76081
77210
  }
76082
77211
  const appState = ctx.getAppState();
77212
+ if (!appState?.tasks) {
77213
+ return {
77214
+ result: false,
77215
+ message: `No task registry is available in the current context ` + `(task_id: ${task_id}). For in-process teammates, communicate via ` + "SendMessage (the mailbox is the coordination channel) instead of " + "polling TaskOutput.",
77216
+ errorCode: 2
77217
+ };
77218
+ }
76083
77219
  const task = appState.tasks[task_id];
76084
77220
  if (!task) {
76085
77221
  return {
@@ -76094,6 +77230,9 @@ var init_taskOutputTool = __esm(() => {
76094
77230
  const { task_id, block = true, timeout = 30000 } = args;
76095
77231
  const ctx = context;
76096
77232
  const appState = ctx.getAppState();
77233
+ if (!appState?.tasks) {
77234
+ throw new Error(`No task registry is available in the current context ` + `(task_id: ${task_id}). For in-process teammates, communicate via ` + "SendMessage (the mailbox is the coordination channel) instead of " + "polling TaskOutput.");
77235
+ }
76097
77236
  const task = appState.tasks[task_id];
76098
77237
  if (!task) {
76099
77238
  throw new Error(`No task found with ID: ${task_id}`);
@@ -82643,18 +83782,6 @@ var init_restore = __esm(() => {
82643
83782
  init_goalState();
82644
83783
  });
82645
83784
 
82646
- // src/engine/session/sessionContextPort.ts
82647
- function setSessionContextPort(port) {
82648
- _sessionContextPort = port;
82649
- }
82650
- function getSessionContextPort() {
82651
- return _sessionContextPort;
82652
- }
82653
- function resetSessionContextPort() {
82654
- _sessionContextPort = null;
82655
- }
82656
- var _sessionContextPort = null;
82657
-
82658
83785
  // src/engine/session/index.ts
82659
83786
  var init_session = __esm(() => {
82660
83787
  init_env();
@@ -84565,6 +85692,7 @@ async function queryAgentLoop(deps, args) {
84565
85692
  assistantMessage: lastRound.messages[roundInputLen],
84566
85693
  toolResultMessages: lastRound.messages.slice(roundInputLen + 1)
84567
85694
  });
85695
+ await deps.afterRound?.();
84568
85696
  break;
84569
85697
  }
84570
85698
  if (lastRound.deferred) {
@@ -84870,6 +85998,7 @@ async function createAgentLoopDeps(config = {}) {
84870
85998
  SnipTool,
84871
85999
  TeamCreateTool,
84872
86000
  TeamDeleteTool,
86001
+ WaitForTeammatesTool,
84873
86002
  ProposeGoalTool
84874
86003
  ],
84875
86004
  mcpTools: [...config.toolRegistryDeps?.mcpTools ?? [], ...mcpTools],
@@ -84966,6 +86095,7 @@ var init_loopDeps = __esm(() => {
84966
86095
  init_snipTool();
84967
86096
  init_teamCreateTool();
84968
86097
  init_teamDeleteTool();
86098
+ init_waitForTeammatesTool();
84969
86099
  init_ProposeGoal();
84970
86100
  init_context();
84971
86101
  });
@@ -84981,6 +86111,7 @@ class EngineState {
84981
86111
  set(f) {
84982
86112
  return new Promise((resolve, reject) => {
84983
86113
  this.queue.push({ f, resolve, reject });
86114
+ logForDebugging(`[probe-R6][es-enqueue] q=${this.queue.length} processing=${this.processing}`);
84984
86115
  this.process();
84985
86116
  });
84986
86117
  }
@@ -84991,6 +86122,7 @@ class EngineState {
84991
86122
  try {
84992
86123
  while (this.queue.length > 0) {
84993
86124
  const item = this.queue.shift();
86125
+ logForDebugging(`[probe-R6][es-apply] q=${this.queue.length}`);
84994
86126
  await Promise.resolve();
84995
86127
  try {
84996
86128
  this.state = item.f(this.state);
@@ -85007,9 +86139,14 @@ class EngineState {
85007
86139
  return this.state;
85008
86140
  }
85009
86141
  }
86142
+ var init_EngineState = __esm(() => {
86143
+ init_shared();
86144
+ });
85010
86145
 
85011
86146
  // src/engine/state/index.ts
85012
- var init_state2 = () => {};
86147
+ var init_state2 = __esm(() => {
86148
+ init_EngineState();
86149
+ });
85013
86150
 
85014
86151
  // src/engine/hooks/index.ts
85015
86152
  var init_hooks2 = __esm(() => {
@@ -87616,6 +88753,8 @@ function initDebugSink() {
87616
88753
  if (initialized)
87617
88754
  return;
87618
88755
  initialized = true;
88756
+ sharedDebugSinkRegistered = true;
88757
+ setDebugSink(sharedLogForDebugging);
87619
88758
  toStderr = argvHas("--debug-to-stderr") || argvHas("-d2e");
87620
88759
  const file = argvValue("--debug-file");
87621
88760
  if (file)
@@ -87658,7 +88797,9 @@ function logForDebugging2(message, { level } = {}) {
87658
88797
  function flushDebugSink() {
87659
88798
  return pendingWrite;
87660
88799
  }
87661
- var LEVEL_ORDER, initialized = false, enabled = false, toStderr = false, sinkFile = null, minLevel = "debug", filter = null, pendingWrite;
88800
+ var LEVEL_ORDER, initialized = false, enabled = false, toStderr = false, sinkFile = null, minLevel = "debug", filter = null, pendingWrite, sharedDebugSinkRegistered = false, sharedLogForDebugging = (message, options) => {
88801
+ logForDebugging2(message, options);
88802
+ };
87662
88803
  var init_debugSink = __esm(() => {
87663
88804
  init_bootstrap();
87664
88805
  init_shared();
@@ -88747,7 +89888,7 @@ function handleControlRequestLocal(request, structuredIO, sessionId) {
88747
89888
  logForDebugging2(`[headless] unknown control_request subtype: ${String(request.request.subtype)}`);
88748
89889
  }
88749
89890
  }
88750
- function extractFinalAssistantText(loopResult) {
89891
+ function extractFinalAssistantText2(loopResult) {
88751
89892
  const contentOf = (m) => {
88752
89893
  const msg = m.message;
88753
89894
  return m.content !== undefined ? m.content : msg?.content;
@@ -89066,6 +90207,7 @@ async function runHeadless(inputPrompt, options) {
89066
90207
  const loopDeps = {
89067
90208
  ...bundle.deps,
89068
90209
  signal: abortController.signal,
90210
+ afterRound: () => drainToOutput(),
89069
90211
  checkPermission,
89070
90212
  toolContext: makeCtx()
89071
90213
  };
@@ -89086,7 +90228,10 @@ async function runHeadless(inputPrompt, options) {
89086
90228
  return queryAgentLoop(loopDeps, {
89087
90229
  messages: turnMessages,
89088
90230
  tools,
89089
- context: { autoCompact, maxTurns: options.maxTurns }
90231
+ context: {
90232
+ autoCompact,
90233
+ maxTurns: options.maxTurns ?? DEFAULT_AGENT_LOOP_MAX_TURNS
90234
+ }
89090
90235
  }).then((r) => {
89091
90236
  logForDebugging2(turnEndLine(n, r));
89092
90237
  return r;
@@ -89100,7 +90245,7 @@ async function runHeadless(inputPrompt, options) {
89100
90245
  }
89101
90246
  };
89102
90247
  const buildResultMessage = (loopResult, isError) => {
89103
- const resultText = extractFinalAssistantText(loopResult);
90248
+ const resultText = extractFinalAssistantText2(loopResult);
89104
90249
  return {
89105
90250
  type: "result",
89106
90251
  subtype: loopResult.terminated ? "success" : "error_max_turns",
@@ -89198,6 +90343,7 @@ async function runHeadless(inputPrompt, options) {
89198
90343
  dir: getSchedulerEnv().getProjectRoot()
89199
90344
  });
89200
90345
  cronScheduler.start();
90346
+ let teammateDrainRequested = 0;
89201
90347
  try {
89202
90348
  const deferredState = findDeferredToolUseState(conversation);
89203
90349
  let reSuspended = false;
@@ -89279,7 +90425,7 @@ async function runHeadless(inputPrompt, options) {
89279
90425
  process.stdout.write(`Execution error`);
89280
90426
  break;
89281
90427
  case "error_max_turns":
89282
- process.stdout.write(`Error: Reached max turns (${String(options.maxTurns)})`);
90428
+ process.stdout.write(`Error: Reached max turns (${String(options.maxTurns ?? DEFAULT_AGENT_LOOP_MAX_TURNS)})`);
89283
90429
  break;
89284
90430
  default:
89285
90431
  break;
@@ -89310,6 +90456,19 @@ async function runHeadless(inputPrompt, options) {
89310
90456
  cronScheduler.stop();
89311
90457
  await drainToOutput();
89312
90458
  await drainPendingBackgroundAgents(abortController.signal);
90459
+ {
90460
+ const sessionPort = getSessionContextPort();
90461
+ if (sessionPort) {
90462
+ const drain = await gracefulShutdownInProcessTeammates({
90463
+ getAppState: () => sessionPort.get(),
90464
+ setAppState: (f) => sessionPort.set(f)
90465
+ });
90466
+ teammateDrainRequested = drain.requested;
90467
+ if (drain.requested > 0) {
90468
+ logForDebugging2(`[headless] teammate shutdown ladder: requested=${drain.requested} drained=${drain.drained} forced=${drain.forced} hardTerminated=${drain.hardTerminated}`);
90469
+ }
90470
+ }
90471
+ }
89313
90472
  await runHeadlessSessionEndHooks("prompt_input_exit");
89314
90473
  } catch (error) {
89315
90474
  cronScheduler.stop();
@@ -89329,10 +90488,32 @@ async function runHeadless(inputPrompt, options) {
89329
90488
  });
89330
90489
  } catch {}
89331
90490
  abortController.abort();
90491
+ {
90492
+ const sessionPort = getSessionContextPort();
90493
+ if (sessionPort) {
90494
+ try {
90495
+ const drain = await gracefulShutdownInProcessTeammates({
90496
+ getAppState: () => sessionPort.get(),
90497
+ setAppState: (f) => sessionPort.set(f)
90498
+ });
90499
+ teammateDrainRequested = drain.requested;
90500
+ if (drain.requested > 0) {
90501
+ logForDebugging2(`[headless] teammate shutdown ladder (error path): requested=${drain.requested} drained=${drain.drained} forced=${drain.forced} hardTerminated=${drain.hardTerminated}`);
90502
+ }
90503
+ } catch {}
90504
+ }
90505
+ }
89332
90506
  await runHeadlessSessionEndHooks("other");
89333
90507
  process.exitCode = 1;
89334
90508
  }
90509
+ if (teammateDrainRequested > 0) {
90510
+ logForDebugging2(`[headless] teammate lifecycle exit guard: forcing process exit after drain (requested=${teammateDrainRequested})`);
90511
+ }
89335
90512
  await flushDebugSink();
90513
+ if (teammateDrainRequested > 0) {
90514
+ await new Promise((resolve) => setTimeout(resolve, 2000));
90515
+ process.exit(process.exitCode ?? 0);
90516
+ }
89336
90517
  }
89337
90518
  async function loadResumedMessages(options) {
89338
90519
  await Promise.resolve().then(() => init_engine());
@@ -89372,6 +90553,7 @@ async function loadResumedMessages(options) {
89372
90553
  }
89373
90554
  var init_print = __esm(() => {
89374
90555
  init_engine();
90556
+ init_swarm();
89375
90557
  init_mcp3();
89376
90558
  init_modelprovider2();
89377
90559
  init_structuredIO();
@@ -124813,7 +125995,7 @@ var init_teamMemPaths = __esm(() => {
124813
125995
  });
124814
125996
 
124815
125997
  // src/tui/utils/config.ts
124816
- import { randomBytes as randomBytes5 } from "crypto";
125998
+ import { randomBytes as randomBytes6 } from "crypto";
124817
125999
  import { unwatchFile as unwatchFile2, watchFile as watchFile2 } from "fs";
124818
126000
  import { basename as basename10, dirname as dirname29, join as join57, resolve as resolve23 } from "path";
124819
126001
  function createDefaultGlobalConfig() {
@@ -125403,7 +126585,7 @@ function getOrCreateUserID() {
125403
126585
  if (config.userID) {
125404
126586
  return config.userID;
125405
126587
  }
125406
- const userID = randomBytes5(32).toString("hex");
126588
+ const userID = randomBytes6(32).toString("hex");
125407
126589
  saveGlobalConfig((current) => ({ ...current, userID }));
125408
126590
  return userID;
125409
126591
  }
@@ -126527,7 +127709,7 @@ var init_constants6 = __esm(() => {
126527
127709
  var TASK_OUTPUT_TOOL_NAME2 = "TaskOutput";
126528
127710
 
126529
127711
  // src/tui/tools/TaskStopTool/prompt.ts
126530
- var TASK_STOP_TOOL_NAME2 = "TaskStop", DESCRIPTION17 = `
127712
+ var TASK_STOP_TOOL_NAME2 = "TaskStop", DESCRIPTION18 = `
126531
127713
  - Stops a running background task by its ID
126532
127714
  - Takes a task_id parameter identifying the task to stop
126533
127715
  - Returns a success or failure status
@@ -135328,7 +136510,7 @@ ${lineFormat}
135328
136510
  - You will regularly be asked to read screenshots. If the user provides a path to a screenshot, ALWAYS use this tool to view the file at the path. This tool will work with all temporary file paths.
135329
136511
  - If you read a file that exists but has empty contents you will receive a system reminder warning in place of file contents.`;
135330
136512
  }
135331
- var FILE_READ_TOOL_NAME2 = "Read", FILE_UNCHANGED_STUB2 = "File unchanged since last read. The content from the earlier Read tool_result in this conversation is still current — refer to that instead of re-reading.", MAX_LINES_TO_READ2 = 2000, DESCRIPTION18 = "Read a file from the local filesystem.", LINE_FORMAT_INSTRUCTION2 = "- Results are returned using cat -n format, with line numbers starting at 1", OFFSET_INSTRUCTION_DEFAULT2 = "- You can optionally specify a line offset and limit (especially handy for long files), but it's recommended to read the whole file by not providing these parameters", OFFSET_INSTRUCTION_TARGETED2 = "- When you already know which part of the file you need, only read that part. This can be important for larger files.";
136513
+ var FILE_READ_TOOL_NAME2 = "Read", FILE_UNCHANGED_STUB2 = "File unchanged since last read. The content from the earlier Read tool_result in this conversation is still current — refer to that instead of re-reading.", MAX_LINES_TO_READ2 = 2000, DESCRIPTION19 = "Read a file from the local filesystem.", LINE_FORMAT_INSTRUCTION2 = "- Results are returned using cat -n format, with line numbers starting at 1", OFFSET_INSTRUCTION_DEFAULT2 = "- You can optionally specify a line offset and limit (especially handy for long files), but it's recommended to read the whole file by not providing these parameters", OFFSET_INSTRUCTION_TARGETED2 = "- When you already know which part of the file you need, only read that part. This can be important for larger files.";
135332
136514
  var init_prompt2 = __esm(() => {
135333
136515
  init_pdfUtils2();
135334
136516
  init_toolName();
@@ -135351,9 +136533,9 @@ var init_outputsScanner = __esm(() => {
135351
136533
  });
135352
136534
 
135353
136535
  // src/tui/utils/words.ts
135354
- import { randomBytes as randomBytes6 } from "crypto";
136536
+ import { randomBytes as randomBytes7 } from "crypto";
135355
136537
  function randomInt2(max) {
135356
- const bytes = randomBytes6(4);
136538
+ const bytes = randomBytes7(4);
135357
136539
  const value = bytes.readUInt32BE(0);
135358
136540
  return value % max;
135359
136541
  }
@@ -153308,28 +154490,28 @@ function getEventPriority(eventType) {
153308
154490
  case "focus":
153309
154491
  case "blur":
153310
154492
  case "paste":
153311
- return import_constants56.DiscreteEventPriority;
154493
+ return import_constants57.DiscreteEventPriority;
153312
154494
  case "resize":
153313
154495
  case "scroll":
153314
154496
  case "mousemove":
153315
- return import_constants56.ContinuousEventPriority;
154497
+ return import_constants57.ContinuousEventPriority;
153316
154498
  default:
153317
- return import_constants56.DefaultEventPriority;
154499
+ return import_constants57.DefaultEventPriority;
153318
154500
  }
153319
154501
  }
153320
154502
 
153321
154503
  class Dispatcher {
153322
154504
  currentEvent = null;
153323
- currentUpdatePriority = import_constants56.DefaultEventPriority;
154505
+ currentUpdatePriority = import_constants57.DefaultEventPriority;
153324
154506
  discreteUpdates = null;
153325
154507
  resolveEventPriority() {
153326
- if (this.currentUpdatePriority !== import_constants56.NoEventPriority) {
154508
+ if (this.currentUpdatePriority !== import_constants57.NoEventPriority) {
153327
154509
  return this.currentUpdatePriority;
153328
154510
  }
153329
154511
  if (this.currentEvent) {
153330
154512
  return getEventPriority(this.currentEvent.type);
153331
154513
  }
153332
- return import_constants56.DefaultEventPriority;
154514
+ return import_constants57.DefaultEventPriority;
153333
154515
  }
153334
154516
  dispatch(target, event) {
153335
154517
  const previousEvent = this.currentEvent;
@@ -153354,18 +154536,18 @@ class Dispatcher {
153354
154536
  dispatchContinuous(target, event) {
153355
154537
  const previousPriority = this.currentUpdatePriority;
153356
154538
  try {
153357
- this.currentUpdatePriority = import_constants56.ContinuousEventPriority;
154539
+ this.currentUpdatePriority = import_constants57.ContinuousEventPriority;
153358
154540
  return this.dispatch(target, event);
153359
154541
  } finally {
153360
154542
  this.currentUpdatePriority = previousPriority;
153361
154543
  }
153362
154544
  }
153363
154545
  }
153364
- var import_constants56;
154546
+ var import_constants57;
153365
154547
  var init_dispatcher = __esm(() => {
153366
154548
  init_log5();
153367
154549
  init_event_handlers();
153368
- import_constants56 = __toESM(require_constants2(), 1);
154550
+ import_constants57 = __toESM(require_constants2(), 1);
153369
154551
  });
153370
154552
 
153371
154553
  // src/tui/ink/events/terminal-event.ts
@@ -162172,7 +163354,7 @@ function applyPositionedHighlight(screen, stylePool, positions, rowOffset, curre
162172
163354
  }
162173
163355
  return true;
162174
163356
  }
162175
- var import_constants58, timing;
163357
+ var import_constants59, timing;
162176
163358
  var init_render_to_screen = __esm(() => {
162177
163359
  init_debug();
162178
163360
  init_dom();
@@ -162181,7 +163363,7 @@ var init_render_to_screen = __esm(() => {
162181
163363
  init_reconciler();
162182
163364
  init_render_node_to_output();
162183
163365
  init_screen();
162184
- import_constants58 = __toESM(require_constants2(), 1);
163366
+ import_constants59 = __toESM(require_constants2(), 1);
162185
163367
  timing = { reconcile: 0, yoga: 0, paint: 0, scan: 0, calls: 0 };
162186
163368
  });
162187
163369
 
@@ -162487,7 +163669,7 @@ class Ink {
162487
163669
  };
162488
163670
  }
162489
163671
  };
162490
- this.container = reconciler_default.createContainer(this.rootNode, import_constants59.ConcurrentRoot, null, false, null, "id", noop_default, noop_default, noop_default, noop_default);
163672
+ this.container = reconciler_default.createContainer(this.rootNode, import_constants60.ConcurrentRoot, null, false, null, "id", noop_default, noop_default, noop_default, noop_default);
162491
163673
  if (false) {}
162492
163674
  }
162493
163675
  handleResume = () => {
@@ -163300,7 +164482,7 @@ function drainStdin(stdin = process.stdin) {
163300
164482
  }
163301
164483
  }
163302
164484
  }
163303
- var import_constants59, jsx_dev_runtime8, ALT_SCREEN_ANCHOR_CURSOR, CURSOR_HOME_PATCH, ERASE_THEN_HOME_PATCH, CONSOLE_STDOUT_METHODS, CONSOLE_STDERR_METHODS;
164485
+ var import_constants60, jsx_dev_runtime8, ALT_SCREEN_ANCHOR_CURSOR, CURSOR_HOME_PATCH, ERASE_THEN_HOME_PATCH, CONSOLE_STDOUT_METHODS, CONSOLE_STDERR_METHODS;
163304
164486
  var init_ink = __esm(() => {
163305
164487
  init_noop();
163306
164488
  init_throttle2();
@@ -163333,7 +164515,7 @@ var init_ink = __esm(() => {
163333
164515
  init_dec();
163334
164516
  init_osc();
163335
164517
  init_useTerminalNotification();
163336
- import_constants59 = __toESM(require_constants2(), 1);
164518
+ import_constants60 = __toESM(require_constants2(), 1);
163337
164519
  jsx_dev_runtime8 = __toESM(require_jsx_dev_runtime(), 1);
163338
164520
  ALT_SCREEN_ANCHOR_CURSOR = Object.freeze({
163339
164521
  x: 0,
@@ -173093,7 +174275,7 @@ var init_agentMemorySnapshot = __esm(() => {
173093
174275
  });
173094
174276
 
173095
174277
  // src/tui/tools/GlobTool/prompt.ts
173096
- var GLOB_TOOL_NAME2 = "Glob", DESCRIPTION19 = `- Fast file pattern matching tool that works with any codebase size
174278
+ var GLOB_TOOL_NAME2 = "Glob", DESCRIPTION20 = `- Fast file pattern matching tool that works with any codebase size
173097
174279
  - Supports glob patterns like "**/*.js" or "src/**/*.ts"
173098
174280
  - Returns matching file paths sorted by modification time
173099
174281
  - Use this tool when you need to find files by name patterns
@@ -173140,7 +174322,7 @@ ${prompt}
173140
174322
  ${guidelines}
173141
174323
  `;
173142
174324
  }
173143
- var WEB_FETCH_TOOL_NAME2 = "WebFetch", DESCRIPTION20 = `
174325
+ var WEB_FETCH_TOOL_NAME2 = "WebFetch", DESCRIPTION21 = `
173144
174326
  - Fetches content from a specified URL and processes it using an AI model
173145
174327
  - Takes a URL and a prompt as input
173146
174328
  - Fetches the URL content, converts HTML to markdown
@@ -182363,7 +183545,7 @@ var TODO_WRITE_TOOL_NAME2 = "TodoWrite";
182363
183545
  var TASK_CREATE_TOOL_NAME2 = "TaskCreate";
182364
183546
 
182365
183547
  // src/tui/tools/AskUserQuestionTool/prompt.ts
182366
- var ASK_USER_QUESTION_TOOL_NAME2 = "AskUserQuestion", ASK_USER_QUESTION_TOOL_CHIP_WIDTH2 = 12, DESCRIPTION21 = "Asks the user multiple choice questions to gather information, clarify ambiguity, understand preferences, make decisions or offer them choices.", PREVIEW_FEATURE_PROMPT2, ASK_USER_QUESTION_TOOL_PROMPT2;
183548
+ var ASK_USER_QUESTION_TOOL_NAME2 = "AskUserQuestion", ASK_USER_QUESTION_TOOL_CHIP_WIDTH2 = 12, DESCRIPTION22 = "Asks the user multiple choice questions to gather information, clarify ambiguity, understand preferences, make decisions or offer them choices.", PREVIEW_FEATURE_PROMPT2, ASK_USER_QUESTION_TOOL_PROMPT2;
182367
183549
  var init_prompt8 = __esm(() => {
182368
183550
  PREVIEW_FEATURE_PROMPT2 = {
182369
183551
  markdown: `
@@ -182904,6 +184086,7 @@ __export(exports_engineCompat, {
182904
184086
  WEB_SEARCH_TOOL_NAME: () => WEB_SEARCH_TOOL_NAME,
182905
184087
  WORKER_AGENT: () => WORKER_AGENT,
182906
184088
  WORKFLOW_TOOL_NAME: () => WORKFLOW_TOOL_NAME,
184089
+ WaitForTeammatesTool: () => WaitForTeammatesTool,
182907
184090
  WebFetchTool: () => WebFetchTool,
182908
184091
  WebSearchTool: () => WebSearchTool,
182909
184092
  WriteTool: () => WriteTool,
@@ -183366,6 +184549,7 @@ __export(exports_engineCompat, {
183366
184549
  removeExtraFields: () => removeExtraFields,
183367
184550
  renderableSearchText: () => renderableSearchText,
183368
184551
  reportAutoCompactCircuitFailures: () => reportAutoCompactCircuitFailures,
184552
+ requireTeammateSpawnTrigger: () => requireTeammateSpawnTrigger,
183369
184553
  resetAutoCompactCircuitForTesting: () => resetAutoCompactCircuitForTesting,
183370
184554
  resetBackgroundAgentTracker: () => resetBackgroundAgentTracker,
183371
184555
  resetBuiltinCommandNamesSourceForTesting: () => resetBuiltinCommandNamesSourceForTesting,
@@ -183393,6 +184577,7 @@ __export(exports_engineCompat, {
183393
184577
  resetTaskNotificationHandler: () => resetTaskNotificationHandler,
183394
184578
  resetTeamFileLoader: () => resetTeamFileLoader,
183395
184579
  resetTeamServices: () => resetTeamServices,
184580
+ resetTeammateSpawnTrigger: () => resetTeammateSpawnTrigger,
183396
184581
  resetWorktreeGitCaches: () => resetWorktreeGitCaches,
183397
184582
  resolveAgentTools: () => resolveAgentTools,
183398
184583
  resolveAutoCompactWindow: () => resolveAutoCompactWindow,
@@ -183455,6 +184640,7 @@ __export(exports_engineCompat, {
183455
184640
  setTaskNotificationHandler: () => setTaskNotificationHandler,
183456
184641
  setTeamFileLoader: () => setTeamFileLoader,
183457
184642
  setTeamServices: () => setTeamServices,
184643
+ setTeammateSpawnTrigger: () => setTeammateSpawnTrigger,
183458
184644
  setTimeBasedMCConfigSource: () => setTimeBasedMCConfigSource,
183459
184645
  setWebSearchSettingsKeyProvider: () => setWebSearchSettingsKeyProvider,
183460
184646
  setWebSearchTransportForTesting: () => setWebSearchTransportForTesting,
@@ -192618,14 +193804,14 @@ var init_terminal2 = __esm(() => {
192618
193804
  });
192619
193805
 
192620
193806
  // src/tui/tools/ListMcpResourcesTool/prompt.ts
192621
- var LIST_MCP_RESOURCES_TOOL_NAME2 = "ListMcpResourcesTool", DESCRIPTION22 = `
193807
+ var LIST_MCP_RESOURCES_TOOL_NAME2 = "ListMcpResourcesTool", DESCRIPTION23 = `
192622
193808
  Lists available resources from configured MCP servers.
192623
193809
  Each resource object includes a 'server' field indicating which server it's from.
192624
193810
 
192625
193811
  Usage examples:
192626
193812
  - List all resources from all servers: \`listMcpResources\`
192627
193813
  - List resources from a specific server: \`listMcpResources({ server: "myserver" })\`
192628
- `, PROMPT10 = `
193814
+ `, PROMPT11 = `
192629
193815
  List available resources from configured MCP servers.
192630
193816
  Each returned resource will include all standard MCP resource fields plus a 'server' field
192631
193817
  indicating which server the resource belongs to.
@@ -192864,10 +194050,10 @@ var init_ListMcpResourcesTool = __esm(() => {
192864
194050
  searchHint: "list resources from connected MCP servers",
192865
194051
  maxResultSizeChars: 1e5,
192866
194052
  async description() {
192867
- return DESCRIPTION22;
194053
+ return DESCRIPTION23;
192868
194054
  },
192869
194055
  async prompt() {
192870
- return PROMPT10;
194056
+ return PROMPT11;
192871
194057
  },
192872
194058
  get inputSchema() {
192873
194059
  return inputSchema4();
@@ -192920,7 +194106,7 @@ var init_ListMcpResourcesTool = __esm(() => {
192920
194106
  });
192921
194107
 
192922
194108
  // src/tui/tools/MCPTool/prompt.ts
192923
- var PROMPT11 = "", DESCRIPTION23 = "";
194109
+ var PROMPT12 = "", DESCRIPTION24 = "";
192924
194110
 
192925
194111
  // src/tui/components/Spinner/utils.ts
192926
194112
  function getDefaultCharacters() {
@@ -194221,10 +195407,10 @@ var init_MCPTool = __esm(() => {
194221
195407
  name: "mcp",
194222
195408
  maxResultSizeChars: 1e5,
194223
195409
  async description() {
194224
- return DESCRIPTION23;
195410
+ return DESCRIPTION24;
194225
195411
  },
194226
195412
  async prompt() {
194227
- return PROMPT11;
195413
+ return PROMPT12;
194228
195414
  },
194229
195415
  get inputSchema() {
194230
195416
  return inputSchema5();
@@ -197601,7 +198787,7 @@ var init_xaa = __esm(() => {
197601
198787
  });
197602
198788
 
197603
198789
  // src/tui/services/mcp/xaaIdpLogin.ts
197604
- import { randomBytes as randomBytes7 } from "crypto";
198790
+ import { randomBytes as randomBytes8 } from "crypto";
197605
198791
  import { createServer as createServer2 } from "http";
197606
198792
  import { parse as parse10 } from "url";
197607
198793
  function isXaaEnabled() {
@@ -197826,7 +199012,7 @@ async function acquireIdpIdToken(opts) {
197826
199012
  const metadata = await discoverOidc(idpIssuer);
197827
199013
  const port = opts.callbackPort ?? await findAvailablePort();
197828
199014
  const redirectUri = buildRedirectUri(port);
197829
- const state = randomBytes7(32).toString("base64url");
199015
+ const state = randomBytes8(32).toString("base64url");
197830
199016
  const clientInformation = {
197831
199017
  client_id: idpClientId,
197832
199018
  ...opts.idpClientSecret ? { client_secret: opts.idpClientSecret } : {}
@@ -197885,7 +199071,7 @@ var init_xaaIdpLogin = __esm(() => {
197885
199071
  });
197886
199072
 
197887
199073
  // src/tui/services/mcp/auth.ts
197888
- import { createHash as createHash5, randomBytes as randomBytes8, randomUUID as randomUUID24 } from "crypto";
199074
+ import { createHash as createHash5, randomBytes as randomBytes9, randomUUID as randomUUID24 } from "crypto";
197889
199075
  import { mkdir as mkdir17 } from "fs/promises";
197890
199076
  import { createServer as createServer3 } from "http";
197891
199077
  import { join as join80 } from "path";
@@ -198668,7 +199854,7 @@ class ClaudeAuthProvider {
198668
199854
  }
198669
199855
  async state() {
198670
199856
  if (!this._state) {
198671
- this._state = randomBytes8(32).toString("base64url");
199857
+ this._state = randomBytes9(32).toString("base64url");
198672
199858
  logMCPDebug(this.serverName, "Generated new OAuth state");
198673
199859
  }
198674
199860
  return this._state;
@@ -199857,14 +201043,14 @@ var init_mcpOutputStorage = __esm(() => {
199857
201043
  });
199858
201044
 
199859
201045
  // src/tui/tools/ReadMcpResourceTool/prompt.ts
199860
- var DESCRIPTION24 = `
201046
+ var DESCRIPTION25 = `
199861
201047
  Reads a specific resource from an MCP server.
199862
201048
  - server: The name of the MCP server to read from
199863
201049
  - uri: The URI of the resource to read
199864
201050
 
199865
201051
  Usage examples:
199866
201052
  - Read a resource from a server: \`readMcpResource({ server: "myserver", uri: "my-resource-uri" })\`
199867
- `, PROMPT12 = `
201053
+ `, PROMPT13 = `
199868
201054
  Reads a specific resource from an MCP server, identified by server name and resource URI.
199869
201055
 
199870
201056
  Parameters:
@@ -199952,10 +201138,10 @@ var init_ReadMcpResourceTool = __esm(() => {
199952
201138
  searchHint: "read a specific MCP resource by URI",
199953
201139
  maxResultSizeChars: 1e5,
199954
201140
  async description() {
199955
- return DESCRIPTION24;
201141
+ return DESCRIPTION25;
199956
201142
  },
199957
201143
  async prompt() {
199958
- return PROMPT12;
201144
+ return PROMPT13;
199959
201145
  },
199960
201146
  get inputSchema() {
199961
201147
  return inputSchema7();
@@ -200556,7 +201742,7 @@ var init_auth4 = __esm(() => {
200556
201742
  });
200557
201743
 
200558
201744
  // src/tui/utils/workloadContext.ts
200559
- import { AsyncLocalStorage as AsyncLocalStorage4 } from "async_hooks";
201745
+ import { AsyncLocalStorage as AsyncLocalStorage3 } from "async_hooks";
200560
201746
  function getWorkload() {
200561
201747
  return workloadStorage.getStore()?.workload;
200562
201748
  }
@@ -200565,7 +201751,7 @@ function runWithWorkload(workload, fn) {
200565
201751
  }
200566
201752
  var WORKLOAD_CRON = "cron", workloadStorage;
200567
201753
  var init_workloadContext = __esm(() => {
200568
- workloadStorage = new AsyncLocalStorage4;
201754
+ workloadStorage = new AsyncLocalStorage3;
200569
201755
  });
200570
201756
 
200571
201757
  // src/tui/utils/http.ts
@@ -203277,10 +204463,10 @@ function parseProxyResponse(socket) {
203277
204463
  read();
203278
204464
  });
203279
204465
  }
203280
- var import_debug54, debug;
204466
+ var import_debug55, debug;
203281
204467
  var init_parse_proxy_response = __esm(() => {
203282
- import_debug54 = __toESM(require_src(), 1);
203283
- debug = import_debug54.default("https-proxy-agent:parse-proxy-response");
204468
+ import_debug55 = __toESM(require_src(), 1);
204469
+ debug = import_debug55.default("https-proxy-agent:parse-proxy-response");
203284
204470
  });
203285
204471
 
203286
204472
  // node_modules/proxy-agent-negotiate/dist/index.js
@@ -203333,7 +204519,7 @@ function omit2(obj, ...keys) {
203333
204519
  }
203334
204520
  return ret;
203335
204521
  }
203336
- var import_debug55, debug2, setServernameFromNonIpHost = (options) => {
204522
+ var import_debug56, debug2, setServernameFromNonIpHost = (options) => {
203337
204523
  if (options.servername === undefined && options.host && !net2.isIP(options.host)) {
203338
204524
  return {
203339
204525
  ...options,
@@ -203345,8 +204531,8 @@ var import_debug55, debug2, setServernameFromNonIpHost = (options) => {
203345
204531
  var init_dist7 = __esm(() => {
203346
204532
  init_dist6();
203347
204533
  init_parse_proxy_response();
203348
- import_debug55 = __toESM(require_src(), 1);
203349
- debug2 = import_debug55.default("https-proxy-agent");
204534
+ import_debug56 = __toESM(require_src(), 1);
204535
+ debug2 = import_debug56.default("https-proxy-agent");
203350
204536
  HttpsProxyAgent2 = class HttpsProxyAgent2 extends Agent2 {
203351
204537
  constructor(proxy, opts) {
203352
204538
  super(opts);
@@ -204466,7 +205652,7 @@ var init_use_declared_cursor = __esm(() => {
204466
205652
  });
204467
205653
 
204468
205654
  // src/tui/utils/imagePaste.ts
204469
- import { randomBytes as randomBytes9 } from "crypto";
205655
+ import { randomBytes as randomBytes10 } from "crypto";
204470
205656
  import { basename as basename20, extname as extname8, isAbsolute as isAbsolute18, join as join86 } from "path";
204471
205657
  function getClipboardCommands() {
204472
205658
  const platform = process.platform;
@@ -204625,7 +205811,7 @@ function stripBackslashEscapes(path) {
204625
205811
  if (platform === "win32") {
204626
205812
  return path;
204627
205813
  }
204628
- const salt = randomBytes9(8).toString("hex");
205814
+ const salt = randomBytes10(8).toString("hex");
204629
205815
  const placeholder = `__DOUBLE_BACKSLASH_${salt}__`;
204630
205816
  const withPlaceholder = path.replace(/\\\\/g, placeholder);
204631
205817
  const withoutEscapes = withPlaceholder.replace(/\\(.)/g, "$1");
@@ -207033,7 +208219,7 @@ __export(exports_terminalSetup, {
207033
208219
  setupTerminal: () => setupTerminal,
207034
208220
  shouldOfferTerminalSetup: () => shouldOfferTerminalSetup
207035
208221
  });
207036
- import { randomBytes as randomBytes10 } from "crypto";
208222
+ import { randomBytes as randomBytes11 } from "crypto";
207037
208223
  import { copyFile as copyFile3, mkdir as mkdir20, readFile as readFile25, writeFile as writeFile14 } from "fs/promises";
207038
208224
  import { homedir as homedir27, platform as platform3 } from "os";
207039
208225
  import { dirname as dirname45, join as join89 } from "path";
@@ -207190,7 +208376,7 @@ async function installBindingsForVSCodeTerminal(editor = "VSCode", theme) {
207190
208376
  throw e;
207191
208377
  }
207192
208378
  if (fileExists) {
207193
- const randomSha = randomBytes10(4).toString("hex");
208379
+ const randomSha = randomBytes11(4).toString("hex");
207194
208380
  const backupPath = `${keybindingsPath}.${randomSha}.bak`;
207195
208381
  try {
207196
208382
  await copyFile3(keybindingsPath, backupPath);
@@ -207349,7 +208535,7 @@ chars = "\\u001B\\r"`;
207349
208535
  if (configContent.includes('mods = "Shift"') && configContent.includes('key = "Return"')) {
207350
208536
  return `${color("warning", theme)("Found existing Alacritty Shift+Enter key binding. Remove it to continue.")}${EOL}${source_default.dim(`See ${formatPathLink(configPath)}`)}${EOL}`;
207351
208537
  }
207352
- const randomSha = randomBytes10(4).toString("hex");
208538
+ const randomSha = randomBytes11(4).toString("hex");
207353
208539
  const backupPath = `${configPath}.${randomSha}.bak`;
207354
208540
  try {
207355
208541
  await copyFile3(configPath, backupPath);
@@ -207401,7 +208587,7 @@ async function installBindingsForZed(theme) {
207401
208587
  if (keymapContent.includes("shift-enter")) {
207402
208588
  return `${color("warning", theme)("Found existing Zed Shift+Enter key binding. Remove it to continue.")}${EOL}${source_default.dim(`See ${formatPathLink(keymapPath)}`)}${EOL}`;
207403
208589
  }
207404
- const randomSha = randomBytes10(4).toString("hex");
208590
+ const randomSha = randomBytes11(4).toString("hex");
207405
208591
  const backupPath = `${keymapPath}.${randomSha}.bak`;
207406
208592
  try {
207407
208593
  await copyFile3(keymapPath, backupPath);
@@ -261410,7 +262596,7 @@ var init_GlobTool = __esm(() => {
261410
262596
  searchHint: "find files by name pattern or wildcard",
261411
262597
  maxResultSizeChars: 1e5,
261412
262598
  async description() {
261413
- return DESCRIPTION19;
262599
+ return DESCRIPTION20;
261414
262600
  },
261415
262601
  userFacingName: userFacingName3,
261416
262602
  getToolUseSummary: getToolUseSummary3,
@@ -261482,7 +262668,7 @@ var init_GlobTool = __esm(() => {
261482
262668
  return checkReadPermissionForTool2(GlobTool2, input, appState.toolPermissionContext);
261483
262669
  },
261484
262670
  async prompt() {
261485
- return DESCRIPTION19;
262671
+ return DESCRIPTION20;
261486
262672
  },
261487
262673
  renderToolUseMessage: renderToolUseMessage6,
261488
262674
  renderToolUseErrorMessage: renderToolUseErrorMessage3,
@@ -262013,52 +263199,30 @@ function getMaxBashTimeoutMs2(env = process.env) {
262013
263199
  }
262014
263200
  var DEFAULT_TIMEOUT_MS2 = 120000, MAX_TIMEOUT_MS2 = 600000;
262015
263201
 
262016
- // src/tui/utils/teammateContext.ts
262017
- import { AsyncLocalStorage as AsyncLocalStorage5 } from "async_hooks";
262018
- function getTeammateContext3() {
262019
- return teammateContextStorage3.getStore();
262020
- }
262021
- function runWithTeammateContext3(context, fn) {
262022
- return teammateContextStorage3.run(context, fn);
262023
- }
262024
- function isInProcessTeammate3() {
262025
- return teammateContextStorage3.getStore() !== undefined;
262026
- }
262027
- function createTeammateContext3(config) {
262028
- return {
262029
- ...config,
262030
- isInProcess: true
262031
- };
262032
- }
262033
- var teammateContextStorage3;
262034
- var init_teammateContext3 = __esm(() => {
262035
- teammateContextStorage3 = new AsyncLocalStorage5;
262036
- });
262037
-
262038
263202
  // src/tui/utils/teammate.ts
262039
263203
  var exports_teammate = {};
262040
263204
  __export(exports_teammate, {
262041
263205
  clearDynamicTeamContext: () => clearDynamicTeamContext2,
262042
- createTeammateContext: () => createTeammateContext3,
263206
+ createTeammateContext: () => createTeammateContext,
262043
263207
  getAgentId: () => getAgentId2,
262044
263208
  getAgentName: () => getAgentName2,
262045
263209
  getDynamicTeamContext: () => getDynamicTeamContext2,
262046
263210
  getParentSessionId: () => getParentSessionId2,
262047
263211
  getTeamName: () => getTeamName2,
262048
263212
  getTeammateColor: () => getTeammateColor3,
262049
- getTeammateContext: () => getTeammateContext3,
263213
+ getTeammateContext: () => getTeammateContext,
262050
263214
  hasActiveInProcessTeammates: () => hasActiveInProcessTeammates2,
262051
263215
  hasWorkingInProcessTeammates: () => hasWorkingInProcessTeammates2,
262052
- isInProcessTeammate: () => isInProcessTeammate3,
263216
+ isInProcessTeammate: () => isInProcessTeammate,
262053
263217
  isPlanModeRequired: () => isPlanModeRequired2,
262054
263218
  isTeamLead: () => isTeamLead2,
262055
263219
  isTeammate: () => isTeammate2,
262056
- runWithTeammateContext: () => runWithTeammateContext3,
263220
+ runWithTeammateContext: () => runWithTeammateContext,
262057
263221
  setDynamicTeamContext: () => setDynamicTeamContext2,
262058
263222
  waitForTeammatesToBecomeIdle: () => waitForTeammatesToBecomeIdle2
262059
263223
  });
262060
263224
  function getParentSessionId2() {
262061
- const inProcessCtx = getTeammateContext3();
263225
+ const inProcessCtx = getTeammateContext();
262062
263226
  if (inProcessCtx)
262063
263227
  return inProcessCtx.parentSessionId;
262064
263228
  return dynamicTeamContext2?.parentSessionId;
@@ -262073,19 +263237,19 @@ function getDynamicTeamContext2() {
262073
263237
  return dynamicTeamContext2;
262074
263238
  }
262075
263239
  function getAgentId2() {
262076
- const inProcessCtx = getTeammateContext3();
263240
+ const inProcessCtx = getTeammateContext();
262077
263241
  if (inProcessCtx)
262078
263242
  return inProcessCtx.agentId;
262079
263243
  return dynamicTeamContext2?.agentId;
262080
263244
  }
262081
263245
  function getAgentName2() {
262082
- const inProcessCtx = getTeammateContext3();
263246
+ const inProcessCtx = getTeammateContext();
262083
263247
  if (inProcessCtx)
262084
263248
  return inProcessCtx.agentName;
262085
263249
  return dynamicTeamContext2?.agentName;
262086
263250
  }
262087
263251
  function getTeamName2(teamContext) {
262088
- const inProcessCtx = getTeammateContext3();
263252
+ const inProcessCtx = getTeammateContext();
262089
263253
  if (inProcessCtx)
262090
263254
  return inProcessCtx.teamName;
262091
263255
  if (dynamicTeamContext2?.teamName)
@@ -262093,19 +263257,19 @@ function getTeamName2(teamContext) {
262093
263257
  return teamContext?.teamName;
262094
263258
  }
262095
263259
  function isTeammate2() {
262096
- const inProcessCtx = getTeammateContext3();
263260
+ const inProcessCtx = getTeammateContext();
262097
263261
  if (inProcessCtx)
262098
263262
  return true;
262099
263263
  return !!(dynamicTeamContext2?.agentId && dynamicTeamContext2?.teamName);
262100
263264
  }
262101
263265
  function getTeammateColor3() {
262102
- const inProcessCtx = getTeammateContext3();
263266
+ const inProcessCtx = getTeammateContext();
262103
263267
  if (inProcessCtx)
262104
263268
  return inProcessCtx.color;
262105
263269
  return dynamicTeamContext2?.color;
262106
263270
  }
262107
263271
  function isPlanModeRequired2() {
262108
- const inProcessCtx = getTeammateContext3();
263272
+ const inProcessCtx = getTeammateContext();
262109
263273
  if (inProcessCtx)
262110
263274
  return inProcessCtx.planModeRequired;
262111
263275
  if (dynamicTeamContext2 !== null) {
@@ -262182,9 +263346,9 @@ function waitForTeammatesToBecomeIdle2(setAppState, appState) {
262182
263346
  }
262183
263347
  var dynamicTeamContext2 = null;
262184
263348
  var init_teammate2 = __esm(() => {
262185
- init_teammateContext3();
263349
+ init_teammateContext();
262186
263350
  init_envUtils2();
262187
- init_teammateContext3();
263351
+ init_shared();
262188
263352
  });
262189
263353
 
262190
263354
  // src/tui/utils/tasks.ts
@@ -262268,7 +263432,7 @@ function getTaskListId2() {
262268
263432
  if (process.env.ATLAS_TASK_LIST_ID) {
262269
263433
  return process.env.ATLAS_TASK_LIST_ID;
262270
263434
  }
262271
- const teammateCtx = getTeammateContext3();
263435
+ const teammateCtx = getTeammateContext();
262272
263436
  if (teammateCtx) {
262273
263437
  return teammateCtx.teamName;
262274
263438
  }
@@ -262492,7 +263656,7 @@ var init_tasks5 = __esm(() => {
262492
263656
  init_log5();
262493
263657
  init_slowOperations();
262494
263658
  init_teammate2();
262495
- init_teammateContext3();
263659
+ init_shared();
262496
263660
  tasksUpdated2 = createSignal3();
262497
263661
  onTasksUpdated2 = tasksUpdated2.subscribe;
262498
263662
  TaskStatusSchema2 = lazySchema2(() => _enum(["pending", "in_progress", "completed"]));
@@ -262530,10 +263694,10 @@ var init_types13 = __esm(() => {
262530
263694
  });
262531
263695
 
262532
263696
  // src/tui/tools/TodoWriteTool/prompt.ts
262533
- var PROMPT13, DESCRIPTION25 = "Update the todo list for the current session. To be used proactively and often to track progress and pending tasks. Make sure that at least one task is in_progress at all times. Always provide both content (imperative) and activeForm (present continuous) for each task.";
263697
+ var PROMPT14, DESCRIPTION26 = "Update the todo list for the current session. To be used proactively and often to track progress and pending tasks. Make sure that at least one task is in_progress at all times. Always provide both content (imperative) and activeForm (present continuous) for each task.";
262534
263698
  var init_prompt10 = __esm(() => {
262535
263699
  init_constants8();
262536
- PROMPT13 = `Use this tool to create and manage a structured task list for your current coding session. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user.
263700
+ PROMPT14 = `Use this tool to create and manage a structured task list for your current coding session. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user.
262537
263701
  It also helps the user understand the progress of the task and overall progress of their requests.
262538
263702
 
262539
263703
  ## When to Use This Tool
@@ -262740,10 +263904,10 @@ var init_TodoWriteTool = __esm(() => {
262740
263904
  maxResultSizeChars: 1e5,
262741
263905
  strict: true,
262742
263906
  async description() {
262743
- return DESCRIPTION25;
263907
+ return DESCRIPTION26;
262744
263908
  },
262745
263909
  async prompt() {
262746
- return PROMPT13;
263910
+ return PROMPT14;
262747
263911
  },
262748
263912
  get inputSchema() {
262749
263913
  return inputSchema11();
@@ -263410,7 +264574,7 @@ function isAgentSwarmsEnabled2() {
263410
264574
  }
263411
264575
  return true;
263412
264576
  }
263413
- var init_agentSwarmsEnabled2 = __esm(() => {
264577
+ var init_agentSwarmsEnabled3 = __esm(() => {
263414
264578
  init_growthbook();
263415
264579
  init_envUtils2();
263416
264580
  });
@@ -264567,14 +265731,14 @@ var init_agent2 = __esm(() => {
264567
265731
  });
264568
265732
 
264569
265733
  // src/tui/utils/uuid.ts
264570
- import { randomBytes as randomBytes11 } from "crypto";
265734
+ import { randomBytes as randomBytes12 } from "crypto";
264571
265735
  function validateUuid2(maybeUuid) {
264572
265736
  if (typeof maybeUuid !== "string")
264573
265737
  return null;
264574
265738
  return uuidRegex2.test(maybeUuid) ? maybeUuid : null;
264575
265739
  }
264576
265740
  function createAgentId(label) {
264577
- const suffix = randomBytes11(8).toString("hex");
265741
+ const suffix = randomBytes12(8).toString("hex");
264578
265742
  return label ? `a${label}-${suffix}` : `a${suffix}`;
264579
265743
  }
264580
265744
  var uuidRegex2;
@@ -266584,7 +267748,7 @@ var init_notebook3 = __esm(() => {
266584
267748
  });
266585
267749
 
266586
267750
  // src/tui/tools/NotebookEditTool/prompt.ts
266587
- var DESCRIPTION26 = "Replace the contents of a specific cell in a Jupyter notebook.", PROMPT14 = `Completely replaces the contents of a specific cell in a Jupyter notebook (.ipynb file) with new source. Jupyter notebooks are interactive documents that combine code, text, and visualizations, commonly used for data analysis and scientific computing. The notebook_path parameter must be an absolute path, not a relative path. The cell_number is 0-indexed. Use edit_mode=insert to add a new cell at the index specified by cell_number. Use edit_mode=delete to delete the cell at the index specified by cell_number.`;
267751
+ var DESCRIPTION27 = "Replace the contents of a specific cell in a Jupyter notebook.", PROMPT15 = `Completely replaces the contents of a specific cell in a Jupyter notebook (.ipynb file) with new source. Jupyter notebooks are interactive documents that combine code, text, and visualizations, commonly used for data analysis and scientific computing. The notebook_path parameter must be an absolute path, not a relative path. The cell_number is 0-indexed. Use edit_mode=insert to add a new cell at the index specified by cell_number. Use edit_mode=delete to delete the cell at the index specified by cell_number.`;
266588
267752
 
266589
267753
  // src/tui/components/NotebookEditToolUseRejectedMessage.tsx
266590
267754
  import { relative as relative16 } from "path";
@@ -266875,10 +268039,10 @@ var init_NotebookEditTool = __esm(() => {
266875
268039
  maxResultSizeChars: 1e5,
266876
268040
  shouldDefer: true,
266877
268041
  async description() {
266878
- return DESCRIPTION26;
268042
+ return DESCRIPTION27;
266879
268043
  },
266880
268044
  async prompt() {
266881
- return PROMPT14;
268045
+ return PROMPT15;
266882
268046
  },
266883
268047
  userFacingName() {
266884
268048
  return "Edit Notebook";
@@ -274800,7 +275964,7 @@ var import_compiler_runtime85, jsx_dev_runtime93;
274800
275964
  var init_UserTextMessage = __esm(() => {
274801
275965
  init_shared();
274802
275966
  init_xml();
274803
- init_agentSwarmsEnabled2();
275967
+ init_agentSwarmsEnabled3();
274804
275968
  init_messages3();
274805
275969
  init_InterruptedByUser();
274806
275970
  init_MessageResponse();
@@ -275791,7 +276955,7 @@ var init_AttachmentMessage = __esm(() => {
275791
276955
  init_ink3();
275792
276956
  init_slowOperations();
275793
276957
  init_stringUtils2();
275794
- init_agentSwarmsEnabled2();
276958
+ init_agentSwarmsEnabled3();
275795
276959
  init_PlanApprovalMessage();
275796
276960
  init_figures2();
275797
276961
  init_UserTeammateMessage();
@@ -279976,7 +281140,7 @@ var init_UI9 = __esm(() => {
279976
281140
  });
279977
281141
 
279978
281142
  // src/tui/utils/agentContext.ts
279979
- import { AsyncLocalStorage as AsyncLocalStorage6 } from "async_hooks";
281143
+ import { AsyncLocalStorage as AsyncLocalStorage4 } from "async_hooks";
279980
281144
  function getAgentContext() {
279981
281145
  return agentContextStorage.getStore();
279982
281146
  }
@@ -279985,8 +281149,8 @@ function runWithAgentContext(context, fn) {
279985
281149
  }
279986
281150
  var agentContextStorage;
279987
281151
  var init_agentContext = __esm(() => {
279988
- init_agentSwarmsEnabled2();
279989
- agentContextStorage = new AsyncLocalStorage6;
281152
+ init_agentSwarmsEnabled3();
281153
+ agentContextStorage = new AsyncLocalStorage4;
279990
281154
  });
279991
281155
 
279992
281156
  // src/tui/utils/generators.ts
@@ -282934,7 +284098,7 @@ function filterToolsForAgent2({
282934
284098
  return false;
282935
284099
  }
282936
284100
  if (isAsync && !ASYNC_AGENT_ALLOWED_TOOLS.has(tool.name)) {
282937
- if (isAgentSwarmsEnabled2() && isInProcessTeammate3()) {
284101
+ if (isAgentSwarmsEnabled2() && isInProcessTeammate()) {
282938
284102
  if (toolMatchesName(tool, AGENT_TOOL_NAME2)) {
282939
284103
  return true;
282940
284104
  }
@@ -283278,7 +284442,7 @@ var init_agentToolUtils2 = __esm(() => {
283278
284442
  init_Tool();
283279
284443
  init_LocalAgentTask();
283280
284444
  init_ids();
283281
- init_agentSwarmsEnabled2();
284445
+ init_agentSwarmsEnabled3();
283282
284446
  init_debug();
283283
284447
  init_errors4();
283284
284448
  init_messages3();
@@ -283286,7 +284450,7 @@ var init_agentToolUtils2 = __esm(() => {
283286
284450
  init_mcpStringUtils();
283287
284451
  init_yoloClassifier();
283288
284452
  init_sdkProgress();
283289
- init_teammateContext3();
284453
+ init_shared();
283290
284454
  init_tokens();
283291
284455
  init_constants6();
283292
284456
  agentToolResultSchema = lazySchema2(() => object({
@@ -283482,7 +284646,7 @@ ${whenNotToUseSection}
283482
284646
 
283483
284647
  Usage notes:
283484
284648
  - Always include a short description (3-5 words) summarizing what the agent will do${concurrencyNote}
283485
- - When the agent is done, it will return a single message back to you. The result returned by the agent is not visible to the user. To show the user the result, you should send a text message back to the user with a concise summary of the result.${!isEnvTruthy2(process.env.ATLAS_DISABLE_BACKGROUND_TASKS) && !isInProcessTeammate3() && !forkEnabled ? `
284649
+ - When the agent is done, it will return a single message back to you. The result returned by the agent is not visible to the user. To show the user the result, you should send a text message back to the user with a concise summary of the result.${!isEnvTruthy2(process.env.ATLAS_DISABLE_BACKGROUND_TASKS) && !isInProcessTeammate() && !forkEnabled ? `
283486
284650
  - Agents run in the background by default. When an agent runs in the background, you will be automatically notified when it completes — do NOT sleep, poll, or proactively check on its progress. Continue with other work or respond to the user instead.
283487
284651
  - **Foreground vs background**: Agents run in the background by default. Use foreground (set run_in_background to false) when you need the agent's results before you can proceed — e.g., research agents whose findings inform your next steps. Use background when you have genuinely independent work to do in parallel.` : ""}
283488
284652
  - To continue a previously spawned agent, use ${SEND_MESSAGE_TOOL_NAME3} with the agent's ID or name as the \`to\` field. The agent resumes with its full context preserved. ${forkEnabled ? "Each fresh Agent invocation with a subagent_type starts without context — provide a complete task description." : "Each Agent invocation starts fresh — provide a complete task description."}
@@ -283490,7 +284654,7 @@ Usage notes:
283490
284654
  - Clearly tell the agent whether you expect it to write code or just to do research (search, file reads, web fetches, etc.)${forkEnabled ? "" : ", since it is not aware of the user's intent"}
283491
284655
  - If the agent description mentions that it should be used proactively, then you should try your best to use it without the user having to ask for it first. Use your judgement.
283492
284656
  - If the user specifies that they want you to run agents "in parallel", you MUST send a single message with multiple ${AGENT_TOOL_NAME2} tool use content blocks. For example, if you need to launch both a build-validator agent and a test-runner agent in parallel, send a single message with both tool calls.
283493
- - You can optionally set \`isolation: "worktree"\` to run the agent in a temporary git worktree, giving it an isolated copy of the repository. The worktree is automatically cleaned up if the agent makes no changes; if changes are made, the worktree path and branch are returned in the result.${isInProcessTeammate3() ? `
284657
+ - You can optionally set \`isolation: "worktree"\` to run the agent in a temporary git worktree, giving it an isolated copy of the repository. The worktree is automatically cleaned up if the agent makes no changes; if changes are made, the worktree path and branch are returned in the result.${isInProcessTeammate() ? `
283494
284658
  - The run_in_background, name, team_name, and mode parameters are not available in this context. Only synchronous subagents are supported.` : isTeammate2() ? `
283495
284659
  - The name, team_name, and mode parameters are not available in this context — teammates cannot spawn other teammates. Omit them to spawn a subagent.` : ""}${whenToForkSection}${writingThePromptSection}
283496
284660
 
@@ -283501,7 +284665,7 @@ var init_prompt13 = __esm(() => {
283501
284665
  init_embeddedTools();
283502
284666
  init_envUtils2();
283503
284667
  init_teammate2();
283504
- init_teammateContext3();
284668
+ init_shared();
283505
284669
  init_prompt2();
283506
284670
  init_prompt3();
283507
284671
  init_constants6();
@@ -302431,7 +303595,7 @@ var init_WebFetchTool = __esm(() => {
302431
303595
  },
302432
303596
  async prompt(_options) {
302433
303597
  return `IMPORTANT: WebFetch WILL FAIL for authenticated or private URLs. Before using this tool, check if the URL points to an authenticated service (e.g. Google Docs, Confluence, Jira, GitHub). If so, look for a specialized MCP tool that provides authenticated access.
302434
- ${DESCRIPTION20}`;
303598
+ ${DESCRIPTION21}`;
302435
303599
  },
302436
303600
  async validateInput(input) {
302437
303601
  const { url } = input;
@@ -302907,7 +304071,7 @@ var init_TaskStopTool = __esm(() => {
302907
304071
  return `Stop a running background task by ID`;
302908
304072
  },
302909
304073
  async prompt() {
302910
- return DESCRIPTION17;
304074
+ return DESCRIPTION18;
302911
304075
  },
302912
304076
  mapToolResultToToolResultBlockParam(output, toolUseID) {
302913
304077
  return {
@@ -304130,7 +305294,7 @@ var init_ExitPlanModeV2Tool = __esm(() => {
304130
305294
  init_v4();
304131
305295
  init_bootstrapState();
304132
305296
  init_Tool();
304133
- init_agentSwarmsEnabled2();
305297
+ init_agentSwarmsEnabled3();
304134
305298
  init_debug();
304135
305299
  init_inProcessTeammateHelpers2();
304136
305300
  init_log5();
@@ -304613,7 +305777,7 @@ var init_AskUserQuestionTool = __esm(() => {
304613
305777
  maxResultSizeChars: 1e5,
304614
305778
  shouldDefer: true,
304615
305779
  async description() {
304616
- return DESCRIPTION21;
305780
+ return DESCRIPTION22;
304617
305781
  },
304618
305782
  async prompt() {
304619
305783
  const format = getQuestionPreviewFormat();
@@ -305109,7 +306273,7 @@ var init_formatters = __esm(() => {
305109
306273
  });
305110
306274
 
305111
306275
  // src/tui/tools/LSPTool/prompt.ts
305112
- var LSP_TOOL_NAME2 = "LSP", DESCRIPTION27 = `Interact with Language Server Protocol (LSP) servers to get code intelligence features.
306276
+ var LSP_TOOL_NAME2 = "LSP", DESCRIPTION28 = `Interact with Language Server Protocol (LSP) servers to get code intelligence features.
305113
306277
 
305114
306278
  Supported operations:
305115
306279
  - goToDefinition: Find where a symbol is defined
@@ -305856,7 +307020,7 @@ var init_LSPTool = __esm(() => {
305856
307020
  maxResultSizeChars: 1e5,
305857
307021
  isLsp: true,
305858
307022
  async description() {
305859
- return DESCRIPTION27;
307023
+ return DESCRIPTION28;
305860
307024
  },
305861
307025
  userFacingName: userFacingName5,
305862
307026
  shouldDefer: true,
@@ -305925,7 +307089,7 @@ var init_LSPTool = __esm(() => {
305925
307089
  return checkReadPermissionForTool2(LSPTool2, input, appState.toolPermissionContext);
305926
307090
  },
305927
307091
  async prompt() {
305928
- return DESCRIPTION27;
307092
+ return DESCRIPTION28;
305929
307093
  },
305930
307094
  renderToolUseMessage: renderToolUseMessage16,
305931
307095
  renderToolUseErrorMessage: renderToolUseErrorMessage7,
@@ -307858,7 +309022,7 @@ ${lines.join(`
307858
309022
  - model - Override the default model (sonnet, opus, haiku, best, or full model ID)`;
307859
309023
  }
307860
309024
  }
307861
- var DESCRIPTION28 = "Get or set Atlas configuration settings.";
309025
+ var DESCRIPTION29 = "Get or set Atlas configuration settings.";
307862
309026
  var init_prompt16 = __esm(() => {
307863
309027
  init_shared();
307864
309028
  init_modelOptions();
@@ -308384,7 +309548,7 @@ var init_ConfigTool = __esm(() => {
308384
309548
  searchHint: "get or set Atlas settings (theme, model)",
308385
309549
  maxResultSizeChars: 1e5,
308386
309550
  async description() {
308387
- return DESCRIPTION28;
309551
+ return DESCRIPTION29;
308388
309552
  },
308389
309553
  async prompt() {
308390
309554
  return generatePrompt2();
@@ -308680,9 +309844,9 @@ All tasks are created with status \`pending\`.
308680
309844
  ${teammateTips}- Check TaskList first to avoid creating duplicate tasks
308681
309845
  `;
308682
309846
  }
308683
- var DESCRIPTION29 = "Create a new task in the task list";
309847
+ var DESCRIPTION30 = "Create a new task in the task list";
308684
309848
  var init_prompt17 = __esm(() => {
308685
- init_agentSwarmsEnabled2();
309849
+ init_agentSwarmsEnabled3();
308686
309850
  });
308687
309851
 
308688
309852
  // src/tui/tools/TaskCreateTool/TaskCreateTool.ts
@@ -308711,7 +309875,7 @@ var init_TaskCreateTool = __esm(() => {
308711
309875
  searchHint: "create a task in the task list",
308712
309876
  maxResultSizeChars: 1e5,
308713
309877
  async description() {
308714
- return DESCRIPTION29;
309878
+ return DESCRIPTION30;
308715
309879
  },
308716
309880
  async prompt() {
308717
309881
  return getPrompt23();
@@ -308790,7 +309954,7 @@ var init_TaskCreateTool = __esm(() => {
308790
309954
  var TASK_GET_TOOL_NAME2 = "TaskGet";
308791
309955
 
308792
309956
  // src/tui/tools/TaskGetTool/prompt.ts
308793
- var DESCRIPTION30 = "Get a task by ID from the task list", PROMPT15 = `Use this tool to retrieve a task by its ID from the task list.
309957
+ var DESCRIPTION31 = "Get a task by ID from the task list", PROMPT16 = `Use this tool to retrieve a task by its ID from the task list.
308794
309958
 
308795
309959
  ## When to Use This Tool
308796
309960
 
@@ -308837,10 +310001,10 @@ var init_TaskGetTool = __esm(() => {
308837
310001
  searchHint: "retrieve a task by ID",
308838
310002
  maxResultSizeChars: 1e5,
308839
310003
  async description() {
308840
- return DESCRIPTION30;
310004
+ return DESCRIPTION31;
308841
310005
  },
308842
310006
  async prompt() {
308843
- return PROMPT15;
310007
+ return PROMPT16;
308844
310008
  },
308845
310009
  get inputSchema() {
308846
310010
  return inputSchema30();
@@ -308924,7 +310088,7 @@ var init_TaskGetTool = __esm(() => {
308924
310088
  var TASK_UPDATE_TOOL_NAME2 = "TaskUpdate";
308925
310089
 
308926
310090
  // src/tui/tools/TaskUpdateTool/prompt.ts
308927
- var DESCRIPTION31 = "Update a task in the task list", PROMPT16 = `Use this tool to update a task in the task list.
310091
+ var DESCRIPTION32 = "Update a task in the task list", PROMPT17 = `Use this tool to update a task in the task list.
308928
310092
 
308929
310093
  ## When to Use This Tool
308930
310094
 
@@ -309007,7 +310171,7 @@ var init_TaskUpdateTool = __esm(() => {
309007
310171
  init_v4();
309008
310172
  init_growthbook();
309009
310173
  init_Tool();
309010
- init_agentSwarmsEnabled2();
310174
+ init_agentSwarmsEnabled3();
309011
310175
  init_hooks7();
309012
310176
  init_tasks5();
309013
310177
  init_teammate2();
@@ -309043,10 +310207,10 @@ var init_TaskUpdateTool = __esm(() => {
309043
310207
  searchHint: "update a task",
309044
310208
  maxResultSizeChars: 1e5,
309045
310209
  async description() {
309046
- return DESCRIPTION31;
310210
+ return DESCRIPTION32;
309047
310211
  },
309048
310212
  async prompt() {
309049
- return PROMPT16;
310213
+ return PROMPT17;
309050
310214
  },
309051
310215
  get inputSchema() {
309052
310216
  return inputSchema31();
@@ -309311,9 +310475,9 @@ ${idDescription}
309311
310475
  Use TaskGet with a specific task ID to view full details including description and comments.
309312
310476
  ${teammateWorkflow}`;
309313
310477
  }
309314
- var DESCRIPTION32 = "List all tasks in the task list";
310478
+ var DESCRIPTION33 = "List all tasks in the task list";
309315
310479
  var init_prompt18 = __esm(() => {
309316
- init_agentSwarmsEnabled2();
310480
+ init_agentSwarmsEnabled3();
309317
310481
  });
309318
310482
 
309319
310483
  // src/tui/tools/TaskListTool/TaskListTool.ts
@@ -309338,7 +310502,7 @@ var init_TaskListTool = __esm(() => {
309338
310502
  searchHint: "list all tasks",
309339
310503
  maxResultSizeChars: 1e5,
309340
310504
  async description() {
309341
- return DESCRIPTION32;
310505
+ return DESCRIPTION33;
309342
310506
  },
309343
310507
  async prompt() {
309344
310508
  return getPrompt24();
@@ -309966,7 +311130,7 @@ var init_CronCreateTool = __esm(() => {
309966
311130
  init_cron2();
309967
311131
  init_cronTasks2();
309968
311132
  init_semanticBoolean();
309969
- init_teammateContext3();
311133
+ init_shared();
309970
311134
  init_prompt19();
309971
311135
  init_UI20();
309972
311136
  inputSchema33 = lazySchema2(() => strictObject({
@@ -310030,7 +311194,7 @@ var init_CronCreateTool = __esm(() => {
310030
311194
  errorCode: 3
310031
311195
  };
310032
311196
  }
310033
- if (input.durable && getTeammateContext3()) {
311197
+ if (input.durable && getTeammateContext()) {
310034
311198
  return {
310035
311199
  result: false,
310036
311200
  message: "durable crons are not supported for teammates (teammates do not persist across sessions)",
@@ -310041,7 +311205,7 @@ var init_CronCreateTool = __esm(() => {
310041
311205
  },
310042
311206
  async call({ cron, prompt, recurring = true, durable = false }) {
310043
311207
  const effectiveDurable = durable && isDurableCronEnabled2();
310044
- const id = await addCronTask2(cron, prompt, recurring, effectiveDurable, getTeammateContext3()?.agentId);
311208
+ const id = await addCronTask2(cron, prompt, recurring, effectiveDurable, getTeammateContext()?.agentId);
310045
311209
  setScheduledTasksEnabled(true);
310046
311210
  return {
310047
311211
  data: {
@@ -310075,7 +311239,7 @@ var init_CronDeleteTool = __esm(() => {
310075
311239
  init_v4();
310076
311240
  init_Tool();
310077
311241
  init_cronTasks2();
310078
- init_teammateContext3();
311242
+ init_shared();
310079
311243
  init_prompt19();
310080
311244
  init_UI20();
310081
311245
  inputSchema34 = lazySchema2(() => strictObject({
@@ -310120,7 +311284,7 @@ var init_CronDeleteTool = __esm(() => {
310120
311284
  errorCode: 1
310121
311285
  };
310122
311286
  }
310123
- const ctx = getTeammateContext3();
311287
+ const ctx = getTeammateContext();
310124
311288
  if (ctx && task.agentId !== ctx.agentId) {
310125
311289
  return {
310126
311290
  result: false,
@@ -310158,7 +311322,7 @@ var init_CronListTool = __esm(() => {
310158
311322
  init_cron2();
310159
311323
  init_cronTasks2();
310160
311324
  init_format2();
310161
- init_teammateContext3();
311325
+ init_shared();
310162
311326
  init_prompt19();
310163
311327
  init_UI20();
310164
311328
  inputSchema35 = lazySchema2(() => strictObject({}));
@@ -310200,7 +311364,7 @@ var init_CronListTool = __esm(() => {
310200
311364
  },
310201
311365
  async call() {
310202
311366
  const allTasks = await listAllCronTasks2();
310203
- const ctx = getTeammateContext3();
311367
+ const ctx = getTeammateContext();
310204
311368
  const tasks = ctx ? allTasks.filter((t) => t.agentId === ctx.agentId) : allTasks;
310205
311369
  const jobs = tasks.map((t) => ({
310206
311370
  id: t.id,
@@ -310458,7 +311622,7 @@ var init_spawnInProcess2 = __esm(() => {
310458
311622
  init_sdkEventQueue2();
310459
311623
  init_diskOutput2();
310460
311624
  init_framework2();
310461
- init_teammateContext3();
311625
+ init_shared();
310462
311626
  init_perfettoTracing();
310463
311627
  init_teamHelpers2();
310464
311628
  });
@@ -314754,9 +315918,9 @@ var init_ParsedCommand2 = __esm(() => {
314754
315918
  });
314755
315919
 
314756
315920
  // src/tui/utils/bash/heredoc.ts
314757
- import { randomBytes as randomBytes12 } from "crypto";
315921
+ import { randomBytes as randomBytes13 } from "crypto";
314758
315922
  function generatePlaceholderSalt2() {
314759
- return randomBytes12(8).toString("hex");
315923
+ return randomBytes13(8).toString("hex");
314760
315924
  }
314761
315925
  function extractHeredocs2(command, options) {
314762
315926
  const heredocs = new Map;
@@ -317187,7 +318351,7 @@ var init_inProcessRunner2 = __esm(() => {
317187
318351
  init_sdkEventQueue2();
317188
318352
  init_slowOperations();
317189
318353
  init_tasks5();
317190
- init_teammateContext3();
318354
+ init_shared();
317191
318355
  init_teammateMailbox();
317192
318356
  init_perfettoTracing();
317193
318357
  init_toolResultStorage();
@@ -318126,7 +319290,7 @@ async function readTeamFileAsync2(teamName) {
318126
319290
  return null;
318127
319291
  }
318128
319292
  }
318129
- function writeTeamFile(teamName, teamFile) {
319293
+ function writeTeamFile2(teamName, teamFile) {
318130
319294
  const teamDir = getTeamDir2(teamName);
318131
319295
  mkdirSync7(teamDir, { recursive: true });
318132
319296
  writeFileSync6(getTeamFilePath2(teamName), jsonStringify5(teamFile, null, 2));
@@ -318159,7 +319323,7 @@ function removeTeammateFromTeamFile2(teamName, identifier) {
318159
319323
  logForDebugging3(`[TeammateTool] Teammate ${identifierStr} not found in team file for "${teamName}"`);
318160
319324
  return false;
318161
319325
  }
318162
- writeTeamFile(teamName, teamFile);
319326
+ writeTeamFile2(teamName, teamFile);
318163
319327
  logForDebugging3(`[TeammateTool] Removed teammate from team file: ${identifierStr}`);
318164
319328
  return true;
318165
319329
  }
@@ -318179,7 +319343,7 @@ function removeMemberFromTeam2(teamName, tmuxPaneId) {
318179
319343
  teamFile.hiddenPaneIds.splice(hiddenIndex, 1);
318180
319344
  }
318181
319345
  }
318182
- writeTeamFile(teamName, teamFile);
319346
+ writeTeamFile2(teamName, teamFile);
318183
319347
  logForDebugging3(`[TeammateTool] Removed member with pane ${tmuxPaneId} from team ${teamName}`);
318184
319348
  return true;
318185
319349
  }
@@ -318193,7 +319357,7 @@ function removeMemberByAgentId2(teamName, agentId) {
318193
319357
  return false;
318194
319358
  }
318195
319359
  teamFile.members.splice(memberIndex, 1);
318196
- writeTeamFile(teamName, teamFile);
319360
+ writeTeamFile2(teamName, teamFile);
318197
319361
  logForDebugging3(`[TeammateTool] Removed member ${agentId} from team ${teamName}`);
318198
319362
  return true;
318199
319363
  }
@@ -318211,7 +319375,7 @@ function setMemberMode2(teamName, memberName, mode) {
318211
319375
  return true;
318212
319376
  }
318213
319377
  const updatedMembers = teamFile.members.map((m) => m.name === memberName ? { ...m, mode } : m);
318214
- writeTeamFile(teamName, { ...teamFile, members: updatedMembers });
319378
+ writeTeamFile2(teamName, { ...teamFile, members: updatedMembers });
318215
319379
  logForDebugging3(`[TeammateTool] Set member ${memberName} in team ${teamName} to mode: ${mode}`);
318216
319380
  return true;
318217
319381
  }
@@ -318240,7 +319404,7 @@ function setMultipleMemberModes2(teamName, modeUpdates) {
318240
319404
  return member;
318241
319405
  });
318242
319406
  if (anyChanged) {
318243
- writeTeamFile(teamName, { ...teamFile, members: updatedMembers });
319407
+ writeTeamFile2(teamName, { ...teamFile, members: updatedMembers });
318244
319408
  logForDebugging3(`[TeammateTool] Set ${modeUpdates.length} member modes in team ${teamName}`);
318245
319409
  }
318246
319410
  return true;
@@ -318294,9 +319458,6 @@ async function destroyWorktree2(worktreePath) {
318294
319458
  logForDebugging3(`[TeammateTool] Failed to remove worktree ${worktreePath}: ${errorMessage2(error)}`);
318295
319459
  }
318296
319460
  }
318297
- function registerTeamForSessionCleanup2(teamName) {
318298
- getSessionCreatedTeams().add(teamName);
318299
- }
318300
319461
  function unregisterTeamForSessionCleanup2(teamName) {
318301
319462
  getSessionCreatedTeams().delete(teamName);
318302
319463
  }
@@ -318416,7 +319577,7 @@ Create a new team to coordinate multiple agents working on a project. Teams have
318416
319577
  \`\`\`
318417
319578
 
318418
319579
  This creates:
318419
- - A team file at \`~/.atlas/teams/{team-name}/config.json\`
319580
+ - An in-memory team context on the leader (Form A is zero-persistence — no team file is written to \`~/.atlas/teams/\`; the member roster lives in the leader's team context)
318420
319581
  - A corresponding task list directory at \`~/.atlas/tasks/{team-name}/\`
318421
319582
 
318422
319583
  ## Team Workflow
@@ -318458,23 +319619,14 @@ Teammates go idle after every turn—this is completely normal and expected. A t
318458
319619
 
318459
319620
  ## Discovering Team Members
318460
319621
 
318461
- Teammates can read the team config file to discover other team members:
318462
- - **Team config location**: \`~/.atlas/teams/{team-name}/config.json\`
318463
-
318464
- The config file contains a \`members\` array with each teammate's:
319622
+ Form A teams are zero-persistence: no team config file is written to disk. Team members come from the \`members\` roster passed to TeamCreate (carried in the leader's team context). Each roster entry has:
318465
319623
  - \`name\`: Human-readable name (**always use this** for messaging and task assignment)
318466
- - \`agentId\`: Unique identifier (for reference only - do not use for communication)
318467
- - \`agentType\`: Role/type of the agent
319624
+ - \`role\`/\`goal\`/\`backstory\`: Role triplet used to compose the member's prompt when spawned via Agent(name, team_name)
318468
319625
 
318469
319626
  **IMPORTANT**: Always refer to teammates by their NAME (e.g., "team-lead", "researcher", "tester"). Names are used for:
318470
319627
  - \`to\` when sending messages
318471
319628
  - Identifying task owners
318472
319629
 
318473
- Example of reading team config:
318474
- \`\`\`
318475
- Use the Read tool to read ~/.atlas/teams/{team-name}/config.json
318476
- \`\`\`
318477
-
318478
319630
  ## Task List Coordination
318479
319631
 
318480
319632
  Teams share a task list that all teammates can access at \`~/.atlas/tasks/{team-name}/\`.
@@ -318516,11 +319668,9 @@ function generateUniqueTeamName2(providedName) {
318516
319668
  var inputSchema37, TeamCreateTool2;
318517
319669
  var init_TeamCreateTool = __esm(() => {
318518
319670
  init_v4();
318519
- init_bootstrap();
318520
319671
  init_Tool();
318521
- init_agentSwarmsEnabled2();
319672
+ init_agentSwarmsEnabled3();
318522
319673
  init_cwd3();
318523
- init_model();
318524
319674
  init_slowOperations();
318525
319675
  init_teamHelpers2();
318526
319676
  init_teammateLayoutManager2();
@@ -318529,7 +319679,13 @@ var init_TeamCreateTool = __esm(() => {
318529
319679
  inputSchema37 = lazySchema2(() => strictObject({
318530
319680
  team_name: string2().describe("Name for the new team to create."),
318531
319681
  description: string2().optional().describe("Team description/purpose."),
318532
- agent_type: string2().optional().describe('Type/role of the team lead (e.g., "researcher", "test-runner"). ' + "Used for team file and inter-agent coordination.")
319682
+ agent_type: string2().optional().describe('Type/role of the team lead (e.g., "researcher", "test-runner"). ' + "Used for team file and inter-agent coordination."),
319683
+ members: array(strictObject({
319684
+ name: string2().describe("Member name (used as the spawn identity)."),
319685
+ role: string2().optional().describe("Role label resolved against the role template registry."),
319686
+ goal: string2().optional().describe("This member's goal for the team's current task."),
319687
+ backstory: string2().optional().describe("This member's background/context for prompt composition.")
319688
+ })).optional().describe("Optional roster of team members to plan for this team. Each entry " + "carries an optional role/goal/backstory triplet used to compose the " + "member's prompt when spawned via Agent(name, team_name).")
318533
319689
  }));
318534
319690
  TeamCreateTool2 = buildTool({
318535
319691
  name: TEAM_CREATE_TOOL_NAME2,
@@ -318556,6 +319712,17 @@ var init_TeamCreateTool = __esm(() => {
318556
319712
  errorCode: 9
318557
319713
  };
318558
319714
  }
319715
+ if (input.members) {
319716
+ for (const m of input.members) {
319717
+ if (!m || typeof m !== "object" || !m.name || m.name.trim().length === 0) {
319718
+ return {
319719
+ result: false,
319720
+ message: "each team member requires a non-empty name",
319721
+ errorCode: 9
319722
+ };
319723
+ }
319724
+ }
319725
+ }
318559
319726
  return { result: true };
318560
319727
  },
318561
319728
  async description() {
@@ -318578,7 +319745,7 @@ var init_TeamCreateTool = __esm(() => {
318578
319745
  },
318579
319746
  async call(input, context) {
318580
319747
  const { setAppState, getAppState } = context;
318581
- const { team_name, description: _description, agent_type } = input;
319748
+ const { team_name, agent_type } = input;
318582
319749
  const appState = getAppState();
318583
319750
  const existingTeam = appState.teamContext?.teamName;
318584
319751
  if (existingTeam) {
@@ -318587,29 +319754,8 @@ var init_TeamCreateTool = __esm(() => {
318587
319754
  const finalTeamName = generateUniqueTeamName2(team_name);
318588
319755
  const leadAgentId = formatAgentId3(TEAM_LEAD_NAME3, finalTeamName);
318589
319756
  const leadAgentType = agent_type || TEAM_LEAD_NAME3;
318590
- const leadModel = parseUserSpecifiedModel2(appState.mainLoopModelForSession ?? appState.mainLoopModel ?? getDefaultMainLoopModel());
318591
319757
  const teamFilePath = getTeamFilePath2(finalTeamName);
318592
- const teamFile = {
318593
- name: finalTeamName,
318594
- description: _description,
318595
- createdAt: Date.now(),
318596
- leadAgentId,
318597
- leadSessionId: getSessionId(),
318598
- members: [
318599
- {
318600
- agentId: leadAgentId,
318601
- name: TEAM_LEAD_NAME3,
318602
- agentType: leadAgentType,
318603
- model: leadModel,
318604
- joinedAt: Date.now(),
318605
- tmuxPaneId: "",
318606
- cwd: getCwd(),
318607
- subscriptions: []
318608
- }
318609
- ]
318610
- };
318611
- await writeTeamFileAsync2(finalTeamName, teamFile);
318612
- registerTeamForSessionCleanup2(finalTeamName);
319758
+ const roster = input.members && input.members.length > 0 ? input.members : undefined;
318613
319759
  const taskListId = sanitizeName3(finalTeamName);
318614
319760
  await resetTaskList2(taskListId);
318615
319761
  await ensureTasksDir2(taskListId);
@@ -318620,6 +319766,7 @@ var init_TeamCreateTool = __esm(() => {
318620
319766
  teamName: finalTeamName,
318621
319767
  teamFilePath,
318622
319768
  leadAgentId,
319769
+ roster,
318623
319770
  teammates: {
318624
319771
  [leadAgentId]: {
318625
319772
  name: TEAM_LEAD_NAME3,
@@ -318689,7 +319836,7 @@ var inputSchema38, TeamDeleteTool2;
318689
319836
  var init_TeamDeleteTool = __esm(() => {
318690
319837
  init_v4();
318691
319838
  init_Tool();
318692
- init_agentSwarmsEnabled2();
319839
+ init_agentSwarmsEnabled3();
318693
319840
  init_slowOperations();
318694
319841
  init_teamHelpers2();
318695
319842
  init_teammateLayoutManager2();
@@ -318742,7 +319889,7 @@ var init_TeamDeleteTool = __esm(() => {
318742
319889
  return {
318743
319890
  data: {
318744
319891
  success: false,
318745
- message: `Cannot cleanup team with ${activeMembers.length} active member(s): ${memberNames}. Use requestShutdown to gracefully terminate teammates first.`,
319892
+ message: `Cannot cleanup team with ${activeMembers.length} active member(s): ${memberNames}. Send each active member a shutdown request via SendMessage first (message: {"type":"shutdown_request","request_id":"<id>","reason":"<why>"}), and wait for their shutdown approval and exit before retrying TeamDelete.`,
318746
319893
  team_name: teamName
318747
319894
  }
318748
319895
  };
@@ -318774,12 +319921,12 @@ var init_TeamDeleteTool = __esm(() => {
318774
319921
  });
318775
319922
 
318776
319923
  // src/tui/tasks/LocalMainSessionTask.ts
318777
- import { randomBytes as randomBytes13 } from "crypto";
319924
+ import { randomBytes as randomBytes14 } from "crypto";
318778
319925
  function generateMainSessionTaskId() {
318779
- const bytes = randomBytes13(8);
319926
+ const bytes = randomBytes14(8);
318780
319927
  let id = "s";
318781
319928
  for (let i = 0;i < 8; i++) {
318782
- id += TASK_ID_ALPHABET2[bytes[i] % TASK_ID_ALPHABET2.length];
319929
+ id += TASK_ID_ALPHABET3[bytes[i] % TASK_ID_ALPHABET3.length];
318783
319930
  }
318784
319931
  return id;
318785
319932
  }
@@ -318995,7 +320142,7 @@ function startBackgroundSession({
318995
320142
  });
318996
320143
  return taskId;
318997
320144
  }
318998
- var DEFAULT_MAIN_SESSION_AGENT, TASK_ID_ALPHABET2 = "0123456789abcdefghijklmnopqrstuvwxyz", MAX_RECENT_ACTIVITIES3 = 5;
320145
+ var DEFAULT_MAIN_SESSION_AGENT, TASK_ID_ALPHABET3 = "0123456789abcdefghijklmnopqrstuvwxyz", MAX_RECENT_ACTIVITIES3 = 5;
318999
320146
  var init_LocalMainSessionTask = __esm(() => {
319000
320147
  init_xml();
319001
320148
  init_loopEvents();
@@ -319523,7 +320670,7 @@ If you receive a JSON message with \`type: "shutdown_request"\` or \`type: "plan
319523
320670
  Approving shutdown terminates your process. Rejecting plan sends the teammate back to revise. Don't originate \`shutdown_request\` unless asked. Don't send structured JSON status messages — use TaskUpdate.
319524
320671
  `.trim();
319525
320672
  }
319526
- var DESCRIPTION33 = "Send a message to another agent";
320673
+ var DESCRIPTION34 = "Send a message to another agent";
319527
320674
  var init_prompt20 = __esm(() => {
319528
320675
  init_shared();
319529
320676
  });
@@ -319845,7 +320992,7 @@ var init_SendMessageTool = __esm(() => {
319845
320992
  init_LocalAgentTask();
319846
320993
  init_LocalMainSessionTask();
319847
320994
  init_ids();
319848
- init_agentSwarmsEnabled2();
320995
+ init_agentSwarmsEnabled3();
319849
320996
  init_debug();
319850
320997
  init_errors4();
319851
320998
  init_format2();
@@ -320038,7 +321185,7 @@ var init_SendMessageTool = __esm(() => {
320038
321185
  return { result: true };
320039
321186
  },
320040
321187
  async description() {
320041
- return DESCRIPTION33;
321188
+ return DESCRIPTION34;
320042
321189
  },
320043
321190
  async prompt() {
320044
321191
  return getPrompt27();
@@ -328995,7 +330142,7 @@ var init_tools3 = __esm(() => {
328995
330142
  init_embeddedTools();
328996
330143
  init_envUtils2();
328997
330144
  init_shellToolUtils();
328998
- init_agentSwarmsEnabled2();
330145
+ init_agentSwarmsEnabled3();
328999
330146
  init_constants9();
329000
330147
  IS_ATLAS_DEV = process.env.ATLAS_DEV === "1" || process.env.ATLAS_DEV === "true";
329001
330148
  REPLTool2 = IS_ATLAS_DEV ? __toCommonJS(exports_REPLTool).REPLTool : null;
@@ -329050,21 +330197,8 @@ var init_zodToJsonSchema2 = __esm(() => {
329050
330197
  });
329051
330198
 
329052
330199
  // src/tui/utils/api.ts
329053
- function filterSwarmFieldsFromSchema(toolName, schema) {
329054
- const fieldsToRemove = SWARM_FIELDS_BY_TOOL[toolName];
329055
- if (!fieldsToRemove || fieldsToRemove.length === 0) {
329056
- return schema;
329057
- }
329058
- const filtered = { ...schema };
329059
- const props = filtered.properties;
329060
- if (props && typeof props === "object") {
329061
- const filteredProps = { ...props };
329062
- for (const field of fieldsToRemove) {
329063
- delete filteredProps[field];
329064
- }
329065
- filtered.properties = filteredProps;
329066
- }
329067
- return filtered;
330200
+ function filterSwarmFieldsFromSchema2(toolName, schema) {
330201
+ return filterSwarmFieldsFromSchema(toolName, schema, !isAgentSwarmsEnabled2());
329068
330202
  }
329069
330203
  async function toolToAPISchema(tool, options) {
329070
330204
  const cacheKey = "inputJSONSchema" in tool && tool.inputJSONSchema ? `${tool.name}:${jsonStringify5(tool.inputJSONSchema)}` : tool.name;
@@ -329074,7 +330208,7 @@ async function toolToAPISchema(tool, options) {
329074
330208
  const strictToolsEnabled = checkStatsigFeatureGate_CACHED_MAY_BE_STALE("atlas_tool_pear");
329075
330209
  let input_schema = "inputJSONSchema" in tool && tool.inputJSONSchema ? tool.inputJSONSchema : zodToJsonSchema(tool.inputSchema);
329076
330210
  if (!isAgentSwarmsEnabled2()) {
329077
- input_schema = filterSwarmFieldsFromSchema(tool.name, input_schema);
330211
+ input_schema = filterSwarmFieldsFromSchema2(tool.name, input_schema);
329078
330212
  }
329079
330213
  base = {
329080
330214
  name: tool.name,
@@ -329223,7 +330357,7 @@ function normalizeToolInputForAPI(tool, input) {
329223
330357
  return input;
329224
330358
  }
329225
330359
  }
329226
- var SWARM_FIELDS_BY_TOOL, loggedStrip = false;
330360
+ var loggedStrip = false;
329227
330361
  var init_api2 = __esm(() => {
329228
330362
  init_prompts2();
329229
330363
  init_context5();
@@ -329237,8 +330371,7 @@ var init_api2 = __esm(() => {
329237
330371
  init_tools3();
329238
330372
  init_system();
329239
330373
  init_tokenEstimation();
329240
- init_constants6();
329241
- init_agentSwarmsEnabled2();
330374
+ init_agentSwarmsEnabled3();
329242
330375
  init_betas2();
329243
330376
  init_cwd3();
329244
330377
  init_debug();
@@ -329252,10 +330385,7 @@ var init_api2 = __esm(() => {
329252
330385
  init_toolSchemaCache();
329253
330386
  init_windowsPaths2();
329254
330387
  init_zodToJsonSchema2();
329255
- SWARM_FIELDS_BY_TOOL = {
329256
- [EXIT_PLAN_MODE_V2_TOOL_NAME2]: ["launchSwarm", "teammateCount"],
329257
- [AGENT_TOOL_NAME2]: ["name", "team_name", "mode"]
329258
- };
330388
+ init_shared();
329259
330389
  });
329260
330390
 
329261
330391
  // src/tui/loopPermissionBridge.ts
@@ -329898,7 +331028,7 @@ Format: 2-12 words, match the user's style. Or nothing.
329898
331028
  Reply with ONLY the suggestion, no quotes or explanation.`, SUGGESTION_PROMPTS;
329899
331029
  var init_promptSuggestion = __esm(() => {
329900
331030
  init_bootstrap();
329901
- init_agentSwarmsEnabled2();
331031
+ init_agentSwarmsEnabled3();
329902
331032
  init_envUtils2();
329903
331033
  init_errors4();
329904
331034
  init_forkedAgent2();
@@ -332340,7 +333470,7 @@ var init_LocalShellTask = __esm(() => {
332340
333470
  });
332341
333471
 
332342
333472
  // src/tui/tools/BashTool/sedEditParser.ts
332343
- import { randomBytes as randomBytes14 } from "crypto";
333473
+ import { randomBytes as randomBytes15 } from "crypto";
332344
333474
  function parseSedEditCommand2(command) {
332345
333475
  const trimmed = command.trim();
332346
333476
  const sedMatch = trimmed.match(/^\s*sed\s+/);
@@ -332492,7 +333622,7 @@ function applySedSubstitution2(content, sedInfo) {
332492
333622
  if (!sedInfo.extendedRegex) {
332493
333623
  jsPattern = jsPattern.replace(/\\\\/g, BACKSLASH_PLACEHOLDER2).replace(/\\\+/g, PLUS_PLACEHOLDER2).replace(/\\\?/g, QUESTION_PLACEHOLDER2).replace(/\\\|/g, PIPE_PLACEHOLDER2).replace(/\\\(/g, LPAREN_PLACEHOLDER2).replace(/\\\)/g, RPAREN_PLACEHOLDER2).replace(/\+/g, "\\+").replace(/\?/g, "\\?").replace(/\|/g, "\\|").replace(/\(/g, "\\(").replace(/\)/g, "\\)").replace(BACKSLASH_PLACEHOLDER_RE2, "\\\\").replace(PLUS_PLACEHOLDER_RE2, "+").replace(QUESTION_PLACEHOLDER_RE2, "?").replace(PIPE_PLACEHOLDER_RE2, "|").replace(LPAREN_PLACEHOLDER_RE2, "(").replace(RPAREN_PLACEHOLDER_RE2, ")");
332494
333624
  }
332495
- const salt = randomBytes14(8).toString("hex");
333625
+ const salt = randomBytes15(8).toString("hex");
332496
333626
  const ESCAPED_AMP_PLACEHOLDER = `___ESCAPED_AMPERSAND_${salt}___`;
332497
333627
  const jsReplacement = sedInfo.replacement.replace(/\\\//g, "/").replace(/\\&/g, ESCAPED_AMP_PLACEHOLDER).replace(/&/g, "$$&").replace(new RegExp(ESCAPED_AMP_PLACEHOLDER, "g"), "&");
332498
333628
  try {
@@ -335560,7 +336690,7 @@ var init_FileReadTool = __esm(() => {
335560
336690
  maxResultSizeChars: Infinity,
335561
336691
  strict: true,
335562
336692
  async description() {
335563
- return DESCRIPTION18;
336693
+ return DESCRIPTION19;
335564
336694
  },
335565
336695
  async prompt() {
335566
336696
  const limits = getDefaultFileReadingLimits2();
@@ -337467,7 +338597,7 @@ var init_attachments = __esm(() => {
337467
338597
  init_pdfUtils2();
337468
338598
  init_common();
337469
338599
  init_pdf2();
337470
- init_agentSwarmsEnabled2();
338600
+ init_agentSwarmsEnabled3();
337471
338601
  init_findRelevantMemories();
337472
338602
  init_paths3();
337473
338603
  init_factory();
@@ -338256,7 +339386,7 @@ var init_zip = __esm(() => {
338256
339386
  });
338257
339387
 
338258
339388
  // src/tui/utils/plugins/zipCache.ts
338259
- import { randomBytes as randomBytes15 } from "crypto";
339389
+ import { randomBytes as randomBytes16 } from "crypto";
338260
339390
  import {
338261
339391
  chmod as chmod5,
338262
339392
  lstat as lstat8,
@@ -338278,7 +339408,7 @@ async function getSessionPluginCachePath() {
338278
339408
  }
338279
339409
  if (!sessionPluginCachePromise) {
338280
339410
  sessionPluginCachePromise = (async () => {
338281
- const suffix = randomBytes15(8).toString("hex");
339411
+ const suffix = randomBytes16(8).toString("hex");
338282
339412
  const dir = join120(tmpdir7(), `atlas-plugin-session-${suffix}`);
338283
339413
  await getFsImplementation2().mkdir(dir);
338284
339414
  sessionPluginCachePath = dir;
@@ -338291,7 +339421,7 @@ async function getSessionPluginCachePath() {
338291
339421
  async function atomicWriteToZipCache(targetPath, data) {
338292
339422
  const dir = dirname62(targetPath);
338293
339423
  await getFsImplementation2().mkdir(dir);
338294
- const tmpName = `.${basename35(targetPath)}.tmp.${randomBytes15(4).toString("hex")}`;
339424
+ const tmpName = `.${basename35(targetPath)}.tmp.${randomBytes16(4).toString("hex")}`;
338295
339425
  const tmpPath = join120(dir, tmpName);
338296
339426
  try {
338297
339427
  if (typeof data === "string") {
@@ -340732,7 +341862,7 @@ function mtimeAwareMemoize(fn, watchFiles, options) {
340732
341862
  var init_mtimeAwareMemoize = () => {};
340733
341863
 
340734
341864
  // src/tui/utils/plugins/installCounts.ts
340735
- import { randomBytes as randomBytes16 } from "crypto";
341865
+ import { randomBytes as randomBytes17 } from "crypto";
340736
341866
  import { readFile as readFile46, rename as rename5, unlink as unlink19, writeFile as writeFile33 } from "fs/promises";
340737
341867
  import { join as join126 } from "path";
340738
341868
  function normalizeStatsBase(raw) {
@@ -340806,7 +341936,7 @@ async function loadInstallCountsCache() {
340806
341936
  }
340807
341937
  async function saveInstallCountsCache(cache) {
340808
341938
  const cachePath = getInstallCountsCachePath();
340809
- const tempPath = `${cachePath}.${randomBytes16(8).toString("hex")}.tmp`;
341939
+ const tempPath = `${cachePath}.${randomBytes17(8).toString("hex")}.tmp`;
340810
341940
  try {
340811
341941
  const pluginsDir = getPluginsDirectory();
340812
341942
  await getFsImplementation2().mkdir(pluginsDir);
@@ -340985,7 +342115,7 @@ var init_pluginVersioning = __esm(() => {
340985
342115
  });
340986
342116
 
340987
342117
  // src/tui/utils/plugins/pluginInstallationHelpers.ts
340988
- import { randomBytes as randomBytes17 } from "crypto";
342118
+ import { randomBytes as randomBytes18 } from "crypto";
340989
342119
  import { rename as rename6, rm as rm9 } from "fs/promises";
340990
342120
  import { dirname as dirname66, join as join127, resolve as resolve48, sep as sep28 } from "path";
340991
342121
  function getCurrentTimestamp() {
@@ -341016,7 +342146,7 @@ async function cacheAndRegisterPlugin(pluginId, entry, scope = "user", projectPa
341016
342146
  const normalizedCachePath = cacheResult.path.endsWith(sep28) ? cacheResult.path : cacheResult.path + sep28;
341017
342147
  const isSubdirectory = versionedPath.startsWith(normalizedCachePath);
341018
342148
  if (isSubdirectory) {
341019
- const tempPath = join127(dirname66(cacheResult.path), `.atlas-plugin-temp-${Date.now()}-${randomBytes17(4).toString("hex")}`);
342149
+ const tempPath = join127(dirname66(cacheResult.path), `.atlas-plugin-temp-${Date.now()}-${randomBytes18(4).toString("hex")}`);
341020
342150
  await rename6(cacheResult.path, tempPath);
341021
342151
  await getFsImplementation2().mkdir(dirname66(versionedPath));
341022
342152
  await rename6(tempPath, versionedPath);
@@ -346006,7 +347136,7 @@ var init_messages3 = __esm(() => {
346006
347136
  init_paths3();
346007
347137
  init_growthbook();
346008
347138
  init_modelprovider2();
346009
- init_agentSwarmsEnabled2();
347139
+ init_agentSwarmsEnabled3();
346010
347140
  init_attachments();
346011
347141
  init_shellQuote2();
346012
347142
  init_format2();
@@ -346223,9 +347353,9 @@ var init_prefix = __esm(() => {
346223
347353
  });
346224
347354
 
346225
347355
  // src/tui/utils/bash/commands.ts
346226
- import { randomBytes as randomBytes18 } from "crypto";
347356
+ import { randomBytes as randomBytes19 } from "crypto";
346227
347357
  function generatePlaceholders2() {
346228
- const salt = randomBytes18(8).toString("hex");
347358
+ const salt = randomBytes19(8).toString("hex");
346229
347359
  return {
346230
347360
  SINGLE_QUOTE: `__SINGLE_QUOTE_${salt}__`,
346231
347361
  DOUBLE_QUOTE: `__DOUBLE_QUOTE_${salt}__`,
@@ -360928,7 +362058,7 @@ var init_Config = __esm(() => {
360928
362058
  init_outputStyles();
360929
362059
  init_envUtils2();
360930
362060
  init_growthbook();
360931
- init_agentSwarmsEnabled2();
362061
+ init_agentSwarmsEnabled3();
360932
362062
  init_teammateModeSnapshot2();
360933
362063
  init_teammateModel2();
360934
362064
  init_modelprovider2();
@@ -370652,7 +371782,7 @@ var init_TaskListV2 = __esm(() => {
370652
371782
  init_AppState();
370653
371783
  init_types15();
370654
371784
  init_agentColorManager();
370655
- init_agentSwarmsEnabled2();
371785
+ init_agentSwarmsEnabled3();
370656
371786
  init_collapseReadSearch();
370657
371787
  init_format2();
370658
371788
  init_tasks5();
@@ -410482,7 +411612,7 @@ var init_ManageMarketplaces = __esm(() => {
410482
411612
  });
410483
411613
 
410484
411614
  // src/tui/utils/plugins/pluginFlagging.ts
410485
- import { randomBytes as randomBytes19 } from "crypto";
411615
+ import { randomBytes as randomBytes20 } from "crypto";
410486
411616
  import { readFile as readFile56, rename as rename10, unlink as unlink22, writeFile as writeFile42 } from "fs/promises";
410487
411617
  import { join as join149 } from "path";
410488
411618
  function getFlaggedPluginsPath() {
@@ -410520,7 +411650,7 @@ async function readFromDisk() {
410520
411650
  }
410521
411651
  async function writeToDisk(plugins) {
410522
411652
  const filePath = getFlaggedPluginsPath();
410523
- const tempPath = `${filePath}.${randomBytes19(8).toString("hex")}.tmp`;
411653
+ const tempPath = `${filePath}.${randomBytes20(8).toString("hex")}.tmp`;
410524
411654
  try {
410525
411655
  await getFsImplementation2().mkdir(getPluginsDirectory());
410526
411656
  const content = jsonStringify5({ plugins }, null, 2);
@@ -420014,7 +421144,7 @@ var require_asciichart = __commonJS(function(exports) {
420014
421144
  });
420015
421145
 
420016
421146
  // src/tui/utils/statsCache.ts
420017
- import { randomBytes as randomBytes20 } from "crypto";
421147
+ import { randomBytes as randomBytes21 } from "crypto";
420018
421148
  import { open as open18 } from "fs/promises";
420019
421149
  import { join as join159 } from "path";
420020
421150
  async function withStatsCacheLock(fn) {
@@ -420110,7 +421240,7 @@ async function loadStatsCache() {
420110
421240
  async function saveStatsCache(cache) {
420111
421241
  const fs = getFsImplementation2();
420112
421242
  const cachePath = getStatsCachePath();
420113
- const tempPath = `${cachePath}.${randomBytes20(8).toString("hex")}.tmp`;
421243
+ const tempPath = `${cachePath}.${randomBytes21(8).toString("hex")}.tmp`;
420114
421244
  try {
420115
421245
  const configDir = getAtlasConfigHomeDir3();
420116
421246
  try {
@@ -429095,7 +430225,7 @@ var init_plans = __esm(() => {
429095
430225
  });
429096
430226
 
429097
430227
  // src/tui/utils/permissions/filesystem.ts
429098
- import { randomBytes as randomBytes21 } from "crypto";
430228
+ import { randomBytes as randomBytes22 } from "crypto";
429099
430229
  import { homedir as homedir38, tmpdir as tmpdir11 } from "os";
429100
430230
  import { join as join165, normalize as normalize15, posix as posix9, resolve as resolve57, sep as sep37 } from "path";
429101
430231
  function normalizeCaseForComparison2(path) {
@@ -430023,7 +431153,7 @@ var init_filesystem2 = __esm(() => {
430023
431153
  return join165(resolvedBaseTmpDir, getAtlasTempDirName2()) + sep37;
430024
431154
  });
430025
431155
  getBundledSkillsRoot2 = memoize_default(function getBundledSkillsRoot() {
430026
- const nonce = randomBytes21(16).toString("hex");
431156
+ const nonce = randomBytes22(16).toString("hex");
430027
431157
  return join165(getAtlasTempDir2(), "bundled-skills", MACRO.VERSION, nonce);
430028
431158
  });
430029
431159
  worktreeCwdProbeCache2 = new Map;
@@ -430244,22 +431374,22 @@ var init_diskOutput2 = __esm(() => {
430244
431374
  });
430245
431375
 
430246
431376
  // src/tui/Task.ts
430247
- import { randomBytes as randomBytes22 } from "crypto";
431377
+ import { randomBytes as randomBytes23 } from "crypto";
430248
431378
  function isTerminalTaskStatus2(status) {
430249
431379
  return status === "completed" || status === "failed" || status === "killed";
430250
431380
  }
430251
431381
  function hasNonTerminalTasks(tasks) {
430252
431382
  return Object.values(tasks).some((t) => !isTerminalTaskStatus2(t.status));
430253
431383
  }
430254
- function getTaskIdPrefix(type) {
430255
- return TASK_ID_PREFIXES[type] ?? "x";
431384
+ function getTaskIdPrefix2(type) {
431385
+ return TASK_ID_PREFIXES2[type] ?? "x";
430256
431386
  }
430257
431387
  function generateTaskId2(type) {
430258
- const prefix = getTaskIdPrefix(type);
430259
- const bytes = randomBytes22(8);
431388
+ const prefix = getTaskIdPrefix2(type);
431389
+ const bytes = randomBytes23(8);
430260
431390
  let id = prefix;
430261
431391
  for (let i = 0;i < 8; i++) {
430262
- id += TASK_ID_ALPHABET3[bytes[i] % TASK_ID_ALPHABET3.length];
431392
+ id += TASK_ID_ALPHABET4[bytes[i] % TASK_ID_ALPHABET4.length];
430263
431393
  }
430264
431394
  return id;
430265
431395
  }
@@ -430276,10 +431406,10 @@ function createTaskStateBase2(id, type, description, toolUseId) {
430276
431406
  notified: false
430277
431407
  };
430278
431408
  }
430279
- var TASK_ID_PREFIXES, TASK_ID_ALPHABET3 = "0123456789abcdefghijklmnopqrstuvwxyz";
431409
+ var TASK_ID_PREFIXES2, TASK_ID_ALPHABET4 = "0123456789abcdefghijklmnopqrstuvwxyz";
430280
431410
  var init_Task = __esm(() => {
430281
431411
  init_diskOutput2();
430282
- TASK_ID_PREFIXES = {
431412
+ TASK_ID_PREFIXES2 = {
430283
431413
  local_bash: "b",
430284
431414
  local_agent: "a",
430285
431415
  remote_agent: "r",
@@ -432172,7 +433302,7 @@ var init_betaSessionTracing = __esm(() => {
432172
433302
  });
432173
433303
 
432174
433304
  // src/tui/utils/telemetry/sessionTracing.ts
432175
- import { AsyncLocalStorage as AsyncLocalStorage7 } from "async_hooks";
433305
+ import { AsyncLocalStorage as AsyncLocalStorage5 } from "async_hooks";
432176
433306
  function getSpanId(span) {
432177
433307
  return span.spanContext().spanId || "";
432178
433308
  }
@@ -432357,8 +433487,8 @@ var init_sessionTracing = __esm(() => {
432357
433487
  init_betaSessionTracing();
432358
433488
  init_perfettoTracing();
432359
433489
  import_api5 = __toESM(require_src3(), 1);
432360
- interactionContext = new AsyncLocalStorage7;
432361
- toolContext = new AsyncLocalStorage7;
433490
+ interactionContext = new AsyncLocalStorage5;
433491
+ toolContext = new AsyncLocalStorage5;
432362
433492
  activeSpans = new Map;
432363
433493
  strongSpans = new Map;
432364
433494
  SPAN_TTL_MS = 30 * 60 * 1000;
@@ -432608,7 +433738,7 @@ var init_hookInputMaterialize = __esm(() => {
432608
433738
  });
432609
433739
 
432610
433740
  // src/tui/utils/hooks/hookReentrancy.ts
432611
- import { AsyncLocalStorage as AsyncLocalStorage8 } from "async_hooks";
433741
+ import { AsyncLocalStorage as AsyncLocalStorage6 } from "async_hooks";
432612
433742
  function getCallbackId(fn) {
432613
433743
  let id = callbackIds.get(fn);
432614
433744
  if (id === undefined) {
@@ -432635,7 +433765,7 @@ function runWithHookReentrancy(hookEvent, hook, pluginRoot, fn) {
432635
433765
  }
432636
433766
  var hookReentrancyStorage, callbackIds, nextCallbackId = 1;
432637
433767
  var init_hookReentrancy = __esm(() => {
432638
- hookReentrancyStorage = new AsyncLocalStorage8;
433768
+ hookReentrancyStorage = new AsyncLocalStorage6;
432639
433769
  callbackIds = new WeakMap;
432640
433770
  });
432641
433771
 
@@ -441394,7 +442524,7 @@ function useLogMessages(messages, ignore = false) {
441394
442524
  var import_react178;
441395
442525
  var init_useLogMessages = __esm(() => {
441396
442526
  init_AppState();
441397
- init_agentSwarmsEnabled2();
442527
+ init_agentSwarmsEnabled3();
441398
442528
  init_sessionStorage();
441399
442529
  import_react178 = __toESM(require_react(), 1);
441400
442530
  });
@@ -450540,7 +451670,7 @@ var init_ExitPlanModePermissionRequest = __esm(() => {
450540
451670
  init_generateSessionName();
450541
451671
  init_ink2();
450542
451672
  init_constants6();
450543
- init_agentSwarmsEnabled2();
451673
+ init_agentSwarmsEnabled3();
450544
451674
  init_context2();
450545
451675
  init_editor();
450546
451676
  init_file();
@@ -461217,7 +462347,7 @@ var init_useTypeahead = __esm(() => {
461217
462347
  init_useKeybinding();
461218
462348
  init_useShortcutDisplay();
461219
462349
  init_AppState();
461220
- init_agentSwarmsEnabled2();
462350
+ init_agentSwarmsEnabled3();
461221
462351
  init_argumentSubstitution2();
461222
462352
  init_shellCompletion();
461223
462353
  init_format2();
@@ -466463,7 +467593,7 @@ var init_PromptInputFooterLeftSide = __esm(() => {
466463
467593
  init_BackgroundTaskStatus();
466464
467594
  init_types14();
466465
467595
  init_taskStatusUtils();
466466
- init_agentSwarmsEnabled2();
467596
+ init_agentSwarmsEnabled3();
466467
467597
  init_TeamStatus();
466468
467598
  init_registry3();
466469
467599
  init_AppState();
@@ -466741,7 +467871,7 @@ var init_PromptInputModeIndicator = __esm(() => {
466741
467871
  init_ink2();
466742
467872
  init_agentColorManager();
466743
467873
  init_teammate2();
466744
- init_agentSwarmsEnabled2();
467874
+ init_agentSwarmsEnabled3();
466745
467875
  import_compiler_runtime297 = __toESM(require_compiler_runtime(), 1);
466746
467876
  jsx_dev_runtime405 = __toESM(require_jsx_dev_runtime(), 1);
466747
467877
  });
@@ -467158,7 +468288,7 @@ function useSwarmBanner() {
467158
468288
  isInsideTmux3().then(setInsideTmux);
467159
468289
  }, []);
467160
468290
  const state = store.getState();
467161
- if (isTeammate2() && !isInProcessTeammate3()) {
468291
+ if (isTeammate2() && !isInProcessTeammate()) {
467162
468292
  const agentName = getAgentName2();
467163
468293
  if (agentName && getTeamName2()) {
467164
468294
  return {
@@ -467230,7 +468360,7 @@ var init_useSwarmBanner = __esm(() => {
467230
468360
  init_detection2();
467231
468361
  init_registry3();
467232
468362
  init_teammate2();
467233
- init_teammateContext3();
468363
+ init_shared();
467234
468364
  React127 = __toESM(require_react(), 1);
467235
468365
  });
467236
468366
 
@@ -468742,7 +469872,7 @@ function PromptInput({
468742
469872
  if (modeColors[mode]) {
468743
469873
  return modeColors[mode];
468744
469874
  }
468745
- if (isInProcessTeammate3()) {
469875
+ if (isInProcessTeammate()) {
468746
469876
  return "promptBorder";
468747
469877
  }
468748
469878
  const teammateColorName = getTeammateColor3();
@@ -468983,7 +470113,7 @@ var init_PromptInput = __esm(() => {
468983
470113
  init_InProcessTeammateTask();
468984
470114
  init_types14();
468985
470115
  init_agentColorManager();
468986
- init_agentSwarmsEnabled2();
470116
+ init_agentSwarmsEnabled3();
468987
470117
  init_Cursor();
468988
470118
  init_config6();
468989
470119
  init_debug();
@@ -469007,7 +470137,7 @@ var init_PromptInput = __esm(() => {
469007
470137
  init_registry3();
469008
470138
  init_teamHelpers2();
469009
470139
  init_teammate2();
469010
- init_teammateContext3();
470140
+ init_shared();
469011
470141
  init_teammateMailbox();
469012
470142
  init_thinking();
469013
470143
  init_tokenBudget();
@@ -471615,7 +472745,7 @@ function useSwarmInitialization(setAppState, initialMessages, { enabled = true }
471615
472745
  var import_react248;
471616
472746
  var init_useSwarmInitialization = __esm(() => {
471617
472747
  init_bootstrap();
471618
- init_agentSwarmsEnabled2();
472748
+ init_agentSwarmsEnabled3();
471619
472749
  init_reconnection2();
471620
472750
  init_teamHelpers2();
471621
472751
  init_teammateInit();
@@ -472410,7 +473540,7 @@ async function handleSwarmWorkerPermission(params) {
472410
473540
  }
472411
473541
  var init_swarmWorkerHandler = __esm(() => {
472412
473542
  init_shared();
472413
- init_agentSwarmsEnabled2();
473543
+ init_agentSwarmsEnabled3();
472414
473544
  init_errors4();
472415
473545
  init_log5();
472416
473546
  init_permissionSync2();
@@ -474924,7 +476054,7 @@ var init_sessionRestore = __esm(() => {
474924
476054
  // src/tui/hooks/useInboxPoller.ts
474925
476055
  import { randomUUID as randomUUID51 } from "crypto";
474926
476056
  function getAgentNameToPoll(appState) {
474927
- if (isInProcessTeammate3()) {
476057
+ if (isInProcessTeammate()) {
474928
476058
  return;
474929
476059
  }
474930
476060
  if (isTeammate2()) {
@@ -475503,7 +476633,7 @@ var init_useInboxPoller = __esm(() => {
475503
476633
  init_teamHelpers2();
475504
476634
  init_tasks5();
475505
476635
  init_teammate2();
475506
- init_teammateContext3();
476636
+ init_shared();
475507
476637
  init_teammateMailbox();
475508
476638
  init_useSwarmPermissionPoller();
475509
476639
  import_react257 = __toESM(require_react(), 1);
@@ -485406,7 +486536,7 @@ var init_REPL = __esm(() => {
485406
486536
  init_concurrentSessions2();
485407
486537
  init_types15();
485408
486538
  init_useInboxPoller();
485409
- init_agentSwarmsEnabled2();
486539
+ init_agentSwarmsEnabled3();
485410
486540
  init_ide();
485411
486541
  init_useIDEIntegration();
485412
486542
  init_exit2();
@@ -493231,7 +494361,7 @@ var init_setup4 = __esm(() => {
493231
494361
  init_commands5();
493232
494362
  init_sessionMemory2();
493233
494363
  init_ids();
493234
- init_agentSwarmsEnabled2();
494364
+ init_agentSwarmsEnabled3();
493235
494365
  init_appleTerminalBackup();
493236
494366
  init_auth4();
493237
494367
  init_memoryFiles();
@@ -498412,7 +499542,7 @@ var init_main3 = __esm(() => {
498412
499542
  init_growthbook();
498413
499543
  init_SyntheticOutputTool();
498414
499544
  init_tools3();
498415
- init_agentSwarmsEnabled2();
499545
+ init_agentSwarmsEnabled3();
498416
499546
  init_asciicast();
498417
499547
  init_auth4();
498418
499548
  init_config6();
@@ -498842,6 +499972,38 @@ function createCoreDependencies() {
498842
499972
  setTeammateToolRegistryDeps({
498843
499973
  baseTools: [SnipTool, TeamCreateTool, TeamDeleteTool]
498844
499974
  });
499975
+ getInProcessBackend().setContext({
499976
+ getAppState: () => appState.get(),
499977
+ setAppState: (f) => {
499978
+ appState.set(f);
499979
+ },
499980
+ messages: []
499981
+ });
499982
+ setTeammateSpawnTrigger(async (config) => {
499983
+ if (isTeammate()) {
499984
+ return {
499985
+ success: false,
499986
+ agentId: `${config.name}@${config.teamName}`,
499987
+ error: "nested teammate spawn is not supported (a teammate cannot spawn teammates)"
499988
+ };
499989
+ }
499990
+ const result = await getInProcessBackend().spawn({
499991
+ name: config.name,
499992
+ teamName: config.teamName,
499993
+ prompt: config.prompt,
499994
+ ...config.model ? { model: config.model } : {},
499995
+ ...config.allowedTools ? { permissions: config.allowedTools } : {},
499996
+ allowPermissionPrompts: config.allowPermissionPrompts ?? false,
499997
+ ...config.systemPrompt ? { systemPrompt: config.systemPrompt } : {},
499998
+ ...config.systemPromptMode ? { systemPromptMode: config.systemPromptMode } : {}
499999
+ });
500000
+ return {
500001
+ success: result.success,
500002
+ agentId: result.agentId,
500003
+ ...result.taskId ? { taskId: result.taskId } : {},
500004
+ ...result.error ? { error: result.error } : {}
500005
+ };
500006
+ });
498845
500007
  setAgentLoopDepsTeammatePoolSync(setTeammateToolRegistryDeps);
498846
500008
  setAgentLoopDepsMcpConnectionsProvider(() => buildMcpEngineConnections(getMcpConnectionManager()));
498847
500009
  setWebSearchSettingsKeyProvider(() => {