u-foo 2.3.32 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (235) hide show
  1. package/README.md +157 -213
  2. package/README.zh-CN.md +151 -197
  3. package/SKILLS/ufoo/SKILL.md +8 -8
  4. package/bin/uagy.js +69 -0
  5. package/bin/uclaude.js +2 -2
  6. package/bin/ucode.js +4 -4
  7. package/bin/ucodex.js +2 -2
  8. package/bin/ufoo.js +5 -23
  9. package/modules/AGENTS.template.md +1 -1
  10. package/modules/bus/SKILLS/ubus/SKILL.md +35 -10
  11. package/package.json +5 -5
  12. package/scripts/chat-app-smoke.js +1 -1
  13. package/scripts/global-chat-switch-benchmark.js +5 -5
  14. package/scripts/ink-demo.js +1 -1
  15. package/scripts/ink-smoke.js +1 -1
  16. package/scripts/ucode-app-smoke.js +1 -1
  17. package/src/{agent → agents/activity}/activityDetector.js +39 -2
  18. package/src/{agent → agents/activity}/activityStatePublisher.js +1 -1
  19. package/src/{agent → agents/activity}/activityStateWriter.js +2 -2
  20. package/src/{agent → agents/activity}/activityTracker.js +1 -1
  21. package/src/agents/activity/index.js +8 -0
  22. package/src/{agent → agents/controller}/controllerToolExecutor.js +4 -4
  23. package/src/agents/controller/index.js +8 -0
  24. package/src/{agent → agents/controller}/loopObservability.js +2 -2
  25. package/src/{agent → agents/controller}/loopRuntime.js +1 -1
  26. package/src/{agent → agents/controller}/ufooAgent.js +9 -9
  27. package/src/agents/index.js +10 -0
  28. package/src/agents/internal/index.js +3 -0
  29. package/src/{agent → agents/internal}/internalRunner.js +45 -22
  30. package/src/agents/launch/agyConversation.js +159 -0
  31. package/src/agents/launch/index.js +12 -0
  32. package/src/{agent → agents/launch}/launchEnvironment.js +2 -3
  33. package/src/{agent → agents/launch}/launcher.js +64 -21
  34. package/src/{agent → agents/launch}/notifier.js +23 -12
  35. package/src/{agent → agents/launch}/ptyRunner.js +44 -12
  36. package/src/{agent → agents/launch}/ptyWrapper.js +2 -2
  37. package/src/{agent → agents/launch}/publisherRouting.js +1 -1
  38. package/src/{agent → agents/launch}/readyDetector.js +23 -0
  39. package/src/{agent → agents/prompts}/defaultBootstrap.js +63 -4
  40. package/src/{group/bootstrap.js → agents/prompts/groupBootstrap.js} +41 -6
  41. package/src/agents/prompts/index.js +8 -0
  42. package/src/{code/prompts → agents/prompts/native}/index.js +1 -1
  43. package/src/{agent → agents/providers}/claudeThreadProvider.js +1 -1
  44. package/src/{agent → agents/providers}/codexThreadProvider.js +1 -1
  45. package/src/{agent → agents/providers}/directAuthStatus.js +184 -1
  46. package/src/agents/providers/index.js +13 -0
  47. package/src/{agent → agents/providers}/upstreamTransport.js +2 -2
  48. package/src/{chat → app/chat}/agentSockets.js +1 -1
  49. package/src/{chat → app/chat}/commandExecutor.js +50 -26
  50. package/src/{chat → app/chat}/commands.js +119 -5
  51. package/src/{chat → app/chat}/daemonConnection.js +1 -1
  52. package/src/{chat → app/chat}/daemonMessageRouter.js +45 -3
  53. package/src/{chat → app/chat}/dashboardView.js +2 -1
  54. package/src/app/chat/index.js +6 -0
  55. package/src/{chat → app/chat}/inputSubmitHandler.js +4 -13
  56. package/src/{chat → app/chat}/internalAgentLogHistory.js +1 -1
  57. package/src/app/chat/multiWindow/index.js +268 -0
  58. package/src/app/chat/multiWindow/paneLayout.js +84 -0
  59. package/src/app/chat/multiWindow/paneManager.js +299 -0
  60. package/src/app/chat/multiWindow/renderer.js +384 -0
  61. package/src/app/chat/multiWindow/virtualTerminal.js +327 -0
  62. package/src/{chat → app/chat}/transport.js +1 -1
  63. package/src/{cli → app/cli}/ctxCoreCommands.js +3 -3
  64. package/src/{doctor/index.js → app/cli/features/doctor.js} +1 -1
  65. package/src/{init/index.js → app/cli/features/init.js} +14 -32
  66. package/src/{cli → app/cli}/groupCoreCommands.js +2 -2
  67. package/src/app/cli/index.js +9 -0
  68. package/src/{cli → app/cli}/onlineCoreCommands.js +5 -5
  69. package/src/{cli.js → app/cli/run.js} +59 -57
  70. package/src/app/index.js +6 -0
  71. package/src/code/agent.js +10 -9
  72. package/src/code/index.js +2 -0
  73. package/src/code/launcher/index.js +9 -0
  74. package/src/{agent → code/launcher}/ucode.js +7 -8
  75. package/src/{agent → code/launcher}/ucodeBootstrap.js +3 -3
  76. package/src/{agent → code/launcher}/ucodeBuild.js +2 -2
  77. package/src/{agent → code/launcher}/ucodeDoctor.js +2 -2
  78. package/src/{agent → code/launcher}/ucodeRuntimeConfig.js +1 -2
  79. package/src/code/nativeRunner.js +4 -4
  80. package/src/code/tui.js +3 -1454
  81. package/src/config.js +15 -2
  82. package/src/{bus → coordination/bus}/activate.js +2 -2
  83. package/src/{bus → coordination/bus}/daemon.js +15 -5
  84. package/src/coordination/bus/envelope.js +173 -0
  85. package/src/{bus → coordination/bus}/index.js +7 -3
  86. package/src/{bus → coordination/bus}/inject.js +11 -3
  87. package/src/{bus → coordination/bus}/message.js +1 -1
  88. package/src/coordination/bus/messageMeta.js +130 -0
  89. package/src/coordination/bus/promptEnvelope.js +65 -0
  90. package/src/{bus → coordination/bus}/shake.js +1 -1
  91. package/src/{bus → coordination/bus}/store.js +3 -3
  92. package/src/{bus → coordination/bus}/subscriber.js +2 -2
  93. package/src/{bus → coordination/bus}/utils.js +2 -2
  94. package/src/{history → coordination/history}/inputTimeline.js +5 -5
  95. package/src/coordination/index.js +10 -0
  96. package/src/{memory → coordination/memory}/historySearch.js +1 -1
  97. package/src/{memory → coordination/memory}/index.js +3 -3
  98. package/src/{report → coordination/report}/store.js +2 -2
  99. package/src/{status → coordination/status}/index.js +3 -3
  100. package/src/online/bridge.js +2 -2
  101. package/src/{controller → orchestration/controller}/flags.js +1 -1
  102. package/src/{controller → orchestration/controller}/gateRouter.js +1 -1
  103. package/src/orchestration/controller/index.js +10 -0
  104. package/src/{controller → orchestration/controller}/shadowGuard.js +1 -1
  105. package/src/orchestration/groups/bootstrap.js +3 -0
  106. package/src/orchestration/groups/index.js +10 -0
  107. package/src/orchestration/groups/promptProfiles.js +3 -0
  108. package/src/{group → orchestration/groups}/templates.js +1 -1
  109. package/src/{group → orchestration/groups}/validateTemplate.js +1 -1
  110. package/src/orchestration/index.js +7 -0
  111. package/src/orchestration/solo/index.js +3 -0
  112. package/src/{daemon → runtime/daemon}/agentProcessManager.js +1 -1
  113. package/src/{daemon → runtime/daemon}/cronOps.js +3 -2
  114. package/src/{daemon → runtime/daemon}/groupOrchestrator.js +26 -9
  115. package/src/{daemon → runtime/daemon}/index.js +105 -53
  116. package/src/{daemon → runtime/daemon}/ipcServer.js +1 -1
  117. package/src/{daemon → runtime/daemon}/nicknameScope.js +6 -3
  118. package/src/{daemon → runtime/daemon}/ops.js +48 -61
  119. package/src/{daemon → runtime/daemon}/promptLoop.js +1 -1
  120. package/src/{daemon → runtime/daemon}/promptRequest.js +7 -7
  121. package/src/runtime/daemon/providerSessions.js +230 -0
  122. package/src/{daemon → runtime/daemon}/reporting.js +4 -4
  123. package/src/{daemon → runtime/daemon}/run.js +4 -4
  124. package/src/{daemon → runtime/daemon}/soloBootstrap.js +7 -7
  125. package/src/{daemon → runtime/daemon}/status.js +5 -5
  126. package/src/runtime/index.js +10 -0
  127. package/src/{projects → runtime/projects}/registry.js +1 -1
  128. package/src/{terminal → runtime/terminal}/adapterRouter.js +0 -10
  129. package/src/{terminal → runtime/terminal}/adapters/internalAdapter.js +0 -4
  130. package/src/tools/handlers/common.js +1 -1
  131. package/src/tools/handlers/listAgents.js +1 -1
  132. package/src/tools/handlers/memory.js +3 -3
  133. package/src/tools/handlers/readBusSummary.js +1 -1
  134. package/src/tools/handlers/readOpenDecisions.js +1 -1
  135. package/src/tools/handlers/readProjectRegistry.js +1 -1
  136. package/src/tools/handlers/readPromptHistory.js +2 -2
  137. package/src/tools/schemaFixtures.js +1 -1
  138. package/src/ui/MIGRATION.md +42 -88
  139. package/src/ui/format/index.js +5 -28
  140. package/src/ui/index.js +1 -1
  141. package/src/ui/{components → ink}/ChatApp.js +812 -88
  142. package/src/ui/ink/DashboardBar.js +685 -0
  143. package/src/ui/{components → ink}/MultilineInput.js +230 -5
  144. package/src/ui/{components → ink}/UcodeApp.js +16 -7
  145. package/src/ui/{components → ink}/agentMirror.js +24 -19
  146. package/src/ui/{components → ink}/chatReducer.js +29 -7
  147. package/src/bus/messageMeta.js +0 -52
  148. package/src/chat/agentViewController.js +0 -1072
  149. package/src/chat/chatLogController.js +0 -138
  150. package/src/chat/completionController.js +0 -533
  151. package/src/chat/dashboardKeyController.js +0 -533
  152. package/src/chat/index.js +0 -2222
  153. package/src/chat/inputHistoryController.js +0 -135
  154. package/src/chat/inputListenerController.js +0 -470
  155. package/src/chat/layout.js +0 -186
  156. package/src/chat/pasteController.js +0 -81
  157. package/src/chat/statusLineController.js +0 -223
  158. package/src/chat/streamTracker.js +0 -156
  159. package/src/code/config +0 -0
  160. package/src/daemon/providerSessions.js +0 -488
  161. package/src/terminal/adapters/internalPtyAdapter.js +0 -42
  162. package/src/ui/components/DashboardBar.js +0 -417
  163. /package/src/{code/prompts → agents/prompts/native}/actions.js +0 -0
  164. /package/src/{code/prompts → agents/prompts/native}/efficiency.js +0 -0
  165. /package/src/{code/prompts → agents/prompts/native}/environment.js +0 -0
  166. /package/src/{code/prompts → agents/prompts/native}/identity.js +0 -0
  167. /package/src/{code/prompts → agents/prompts/native}/safety.js +0 -0
  168. /package/src/{code/prompts → agents/prompts/native}/sections.js +0 -0
  169. /package/src/{code/prompts → agents/prompts/native}/system.js +0 -0
  170. /package/src/{code/prompts → agents/prompts/native}/tasks.js +0 -0
  171. /package/src/{code/prompts → agents/prompts/native}/toolDescriptions/bash.js +0 -0
  172. /package/src/{code/prompts → agents/prompts/native}/toolDescriptions/edit.js +0 -0
  173. /package/src/{code/prompts → agents/prompts/native}/toolDescriptions/read.js +0 -0
  174. /package/src/{code/prompts → agents/prompts/native}/toolDescriptions/write.js +0 -0
  175. /package/src/{code/prompts → agents/prompts/native}/ufoo.js +0 -0
  176. /package/src/{group → agents/prompts}/promptProfiles.js +0 -0
  177. /package/src/{agent → agents/providers}/claudeEventTranslator.js +0 -0
  178. /package/src/{agent → agents/providers}/claudeOauthTokenReader.js +0 -0
  179. /package/src/{agent → agents/providers}/claudeSessionFiles.js +0 -0
  180. /package/src/{agent → agents/providers}/codexEventTranslator.js +0 -0
  181. /package/src/{agent → agents/providers}/credentials/claude.js +0 -0
  182. /package/src/{agent → agents/providers}/credentials/codex.js +0 -0
  183. /package/src/{agent → agents/providers}/credentials/index.js +0 -0
  184. /package/src/{chat → app/chat}/agentBar.js +0 -0
  185. /package/src/{chat → app/chat}/agentDirectory.js +0 -0
  186. /package/src/{chat → app/chat}/cronScheduler.js +0 -0
  187. /package/src/{chat → app/chat}/daemonCoordinator.js +0 -0
  188. /package/src/{chat → app/chat}/daemonReconnect.js +0 -0
  189. /package/src/{chat → app/chat}/daemonTransport.js +0 -0
  190. /package/src/{chat → app/chat}/daemonTransportDefaults.js +0 -0
  191. /package/src/{chat → app/chat}/inputMath.js +0 -0
  192. /package/src/{chat → app/chat}/projectCloseController.js +0 -0
  193. /package/src/{chat → app/chat}/rawKeyMap.js +0 -0
  194. /package/src/{chat → app/chat}/settingsController.js +0 -0
  195. /package/src/{chat → app/chat}/shellCommand.js +0 -0
  196. /package/src/{chat → app/chat}/text.js +0 -0
  197. /package/src/{chat → app/chat}/transientAgentState.js +0 -0
  198. /package/src/{cli → app/cli}/busCoreCommands.js +0 -0
  199. /package/src/{skills/index.js → app/cli/features/skills.js} +0 -0
  200. /package/src/{bus → coordination/bus}/nickname.js +0 -0
  201. /package/src/{bus → coordination/bus}/queue.js +0 -0
  202. /package/src/{context → coordination/context}/decisions.js +0 -0
  203. /package/src/{context → coordination/context}/doctor.js +0 -0
  204. /package/src/{context → coordination/context}/index.js +0 -0
  205. /package/src/{context → coordination/context}/sync.js +0 -0
  206. /package/src/{ufoo → coordination/state}/agentRegistryDiagnostics.js +0 -0
  207. /package/src/{ufoo → coordination/state}/agentsStore.js +0 -0
  208. /package/src/{ufoo → coordination/state}/paths.js +0 -0
  209. /package/src/{controller → orchestration/controller}/launchRouting.js +0 -0
  210. /package/src/{controller → orchestration/controller}/routerFastPath.js +0 -0
  211. /package/src/{controller → orchestration/controller}/routerFinalize.js +0 -0
  212. /package/src/{group → orchestration/groups}/diagram.js +0 -0
  213. /package/src/{group → orchestration/groups}/templateValidation.js +0 -0
  214. /package/src/{solo → orchestration/solo}/commands.js +0 -0
  215. /package/src/{shared → runtime/contracts}/eventContract.js +0 -0
  216. /package/src/{shared → runtime/contracts}/ptySocketContract.js +0 -0
  217. /package/src/{providerapi → runtime/privacy}/redactor.js +0 -0
  218. /package/src/{providerapi → runtime/privacy}/shadowDiff.js +0 -0
  219. /package/src/{utils → runtime/process}/nodeExecutable.js +0 -0
  220. /package/src/{projects → runtime/projects}/identity.js +0 -0
  221. /package/src/{projects → runtime/projects}/index.js +0 -0
  222. /package/src/{projects → runtime/projects}/projectId.js +0 -0
  223. /package/src/{projects → runtime/projects}/runtimes.js +0 -0
  224. /package/src/{terminal → runtime/terminal}/adapterContract.js +0 -0
  225. /package/src/{terminal → runtime/terminal}/adapters/externalAdapter.js +0 -0
  226. /package/src/{terminal → runtime/terminal}/adapters/hostAdapter.js +0 -0
  227. /package/src/{terminal → runtime/terminal}/adapters/internalQueueAdapter.js +0 -0
  228. /package/src/{terminal → runtime/terminal}/adapters/terminalAdapter.js +0 -0
  229. /package/src/{terminal → runtime/terminal}/adapters/tmuxAdapter.js +0 -0
  230. /package/src/{terminal → runtime/terminal}/detect.js +0 -0
  231. /package/src/{terminal → runtime/terminal}/index.js +0 -0
  232. /package/src/{terminal → runtime/terminal}/iterm2.js +0 -0
  233. /package/src/{utils → ui/format}/banner.js +0 -0
  234. /package/src/{shared → ui/format}/markdownRenderer.js +0 -0
  235. /package/src/ui/{components → ink}/InkDemo.js +0 -0
@@ -1,10 +1,10 @@
1
1
  const { spawn, spawnSync } = require("child_process");
2
2
  const fs = require("fs");
3
3
  const path = require("path");
4
- const { loadConfig } = require("../config");
5
- const { getUfooPaths } = require("../ufoo/paths");
6
- const { loadAgentsData, saveAgentsData } = require("../ufoo/agentsStore");
7
- const { isAgentPidAlive, getTtyProcessInfo } = require("../bus/utils");
4
+ const { loadConfig } = require("../../config");
5
+ const { getUfooPaths } = require("../../coordination/state/paths");
6
+ const { loadAgentsData, saveAgentsData } = require("../../coordination/state/agentsStore");
7
+ const { isAgentPidAlive, getTtyProcessInfo } = require("../../coordination/bus/utils");
8
8
  const { isITerm2 } = require("../terminal/detect");
9
9
  const { createTerminalAdapterRouter } = require("../terminal/adapterRouter");
10
10
  const {
@@ -14,13 +14,14 @@ const {
14
14
  const {
15
15
  createSession: createHostSession,
16
16
  } = require("../terminal/adapters/hostAdapter");
17
- const { resolveDefaultManualBootstrap } = require("../agent/defaultBootstrap");
18
- const { detectLaunchEnvironment } = require("../agent/launchEnvironment");
17
+ const { resolveDefaultManualBootstrap } = require("../../agents/prompts/defaultBootstrap");
18
+ const { detectLaunchEnvironment } = require("../../agents/launch/launchEnvironment");
19
19
 
20
20
  function normalizeLaunchAgent(agent = "") {
21
21
  const value = String(agent || "").trim().toLowerCase();
22
22
  if (value === "codex") return "codex";
23
23
  if (value === "claude" || value === "claude-code") return "claude";
24
+ if (value === "agy" || value === "antigravity") return "agy";
24
25
  if (value === "ufoo" || value === "ucode" || value === "ufoo-code") return "ufoo";
25
26
  return "";
26
27
  }
@@ -28,6 +29,7 @@ function normalizeLaunchAgent(agent = "") {
28
29
  function toBusAgentType(agent = "") {
29
30
  if (agent === "codex") return "codex";
30
31
  if (agent === "claude") return "claude-code";
32
+ if (agent === "agy") return "agy";
31
33
  if (agent === "ufoo") return "ufoo-code";
32
34
  return "";
33
35
  }
@@ -35,6 +37,7 @@ function toBusAgentType(agent = "") {
35
37
  function toTerminalBinary(agent = "") {
36
38
  if (agent === "codex") return "ucodex";
37
39
  if (agent === "claude") return "uclaude";
40
+ if (agent === "agy") return "uagy";
38
41
  if (agent === "ufoo") return "ucode";
39
42
  return "";
40
43
  }
@@ -42,6 +45,7 @@ function toTerminalBinary(agent = "") {
42
45
  function toTmuxBinary(agent = "") {
43
46
  if (agent === "codex") return "ucodex";
44
47
  if (agent === "claude") return "uclaude";
48
+ if (agent === "agy") return "uagy";
45
49
  if (agent === "ufoo") return "ucode";
46
50
  return "";
47
51
  }
@@ -84,7 +88,7 @@ function applyDefaultManagedBootstrap(projectRoot, normalizedAgent, args = [], e
84
88
  }
85
89
 
86
90
  function resolveUfooRunnerPath() {
87
- return path.resolve(__dirname, "../../bin/ufoo.js");
91
+ return path.resolve(__dirname, "../../../bin/ufoo.js");
88
92
  }
89
93
 
90
94
  function normalizeLaunchScope(value, fallback = "inplace") {
@@ -165,7 +169,7 @@ function resolveNativeTerminalApp(options = {}) {
165
169
 
166
170
  function resolveConfiguredLaunchMode(configuredMode = "", options = {}) {
167
171
  const mode = normalizeOptionalString(configuredMode);
168
- if (mode === "internal" || mode === "internal-pty" || mode === "tmux" || mode === "terminal" || mode === "host") {
172
+ if (mode === "internal" || mode === "tmux" || mode === "terminal" || mode === "host") {
169
173
  return mode;
170
174
  }
171
175
  // Auto mode: defer to the unified detector. Daemon ops differs from the
@@ -462,8 +466,8 @@ function buildResumeCommand(projectRoot, agent, sessionId) {
462
466
  }
463
467
  const args = buildResumeArgs(agent, sessionId);
464
468
  const argText = args.length > 0 ? ` ${args.map(shellEscape).join(" ")}` : "";
465
- const skipProbeEnv = "UFOO_SKIP_SESSION_PROBE=1 ";
466
- return `cd ${shellEscape(projectRoot)} && ${skipProbeEnv}${binary}${argText}`;
469
+ const skipSessionResolveEnv = "UFOO_SKIP_SESSION_RESOLVE=1 ";
470
+ return `cd ${shellEscape(projectRoot)} && ${skipSessionResolveEnv}${binary}${argText}`;
467
471
  }
468
472
 
469
473
  async function tryReuseTerminal(projectRoot, subscriberId, meta, agent, sessionId) {
@@ -474,7 +478,7 @@ async function tryReuseTerminal(projectRoot, subscriberId, meta, agent, sessionI
474
478
  const baseCmd = buildResumeCommand(projectRoot, agent, sessionId);
475
479
  const command = titleCmd ? `${titleCmd} && ${baseCmd}` : baseCmd;
476
480
  try {
477
- const EventBus = require("../bus");
481
+ const EventBus = require("../../coordination/bus");
478
482
  const bus = new EventBus(projectRoot);
479
483
  bus.ensureBus();
480
484
  await bus.inject(subscriberId, command);
@@ -541,7 +545,6 @@ async function spawnManagedHostAgent(
541
545
  }
542
546
 
543
547
  const hostContext = resolveHostLaunchContext(hostOptions);
544
- const requireActivityMonitor = hostContext.requireActivityMonitor === true;
545
548
  if (!hostContext.hostDaemonSock) {
546
549
  throw new Error("host launch requires UFOO_HOST_DAEMON_SOCK");
547
550
  }
@@ -555,7 +558,7 @@ async function spawnManagedHostAgent(
555
558
 
556
559
  // Pre-register subscriber on the bus so waitForNewSubscriber resolves immediately
557
560
  const crypto = require("crypto");
558
- const EventBus = require("../bus");
561
+ const EventBus = require("../../coordination/bus");
559
562
  const existing = listSubscribers(projectRoot, agentType);
560
563
  let subscriberId = "";
561
564
  let preRegistrationError = null;
@@ -584,15 +587,11 @@ async function spawnManagedHostAgent(
584
587
  const argText = args.length > 0 ? ` ${args.map(shellEscape).join(" ")}` : "";
585
588
 
586
589
  const titleCmd = buildTitleCmd(nickname);
587
- const hasPreRegisteredSubscriber = !!subscriberId;
588
590
 
589
591
  // Pass env vars to Horizon via the env parameter (Horizon will set them for the child process)
590
592
  const env = {
591
593
  UFOO_LAUNCH_MODE: "host",
592
594
  };
593
- if (requireActivityMonitor) {
594
- env.UFOO_FORCE_PTY = "1";
595
- }
596
595
  if (subscriberId) {
597
596
  env.UFOO_SUBSCRIBER_ID = subscriberId;
598
597
  }
@@ -608,32 +607,18 @@ async function spawnManagedHostAgent(
608
607
  }
609
608
  }
610
609
 
611
- let runCmd;
612
- if (hasPreRegisteredSubscriber) {
613
- // Group mode: use ufoo launcher for activity_state monitoring
614
- // This enables ReadyDetector and bootstrap to work correctly
615
- const ufooRunner = resolveUfooRunnerPath();
616
- const launchCmd = `${shellEscape(process.execPath)} ${shellEscape(ufooRunner)} agent-pty-runner ${shellEscape(normalizedAgent)}${argText}`.trim();
617
- runCmd = titleCmd
618
- ? `cd ${shellEscape(projectRoot)} && ${titleCmd} && ${launchCmd}`
619
- : `cd ${shellEscape(projectRoot)} && ${launchCmd}`;
620
- // Force PTY wrapper so ReadyDetector + ActivityDetector work for activity_state monitoring.
621
- // Horizon sets UFOO_DISABLE_PTY=1 unconditionally; UFOO_FORCE_PTY=1 takes priority over it.
622
- env.UFOO_FORCE_PTY = "1";
623
- } else {
624
- if (preRegistrationError) {
625
- console.error(
626
- `[host-launch] pre-registration failed for ${nickname || agentType}: ${preRegistrationError.message || String(preRegistrationError)}`
627
- );
628
- }
629
- // Fallback launch still goes through the regular agent launcher binary.
630
- // For group/bootstrap-monitored flows we also force the PTY wrapper so
631
- // activity_state can progress out of "starting" after self-registration.
632
- const directCmd = `${binary}${argText}`;
633
- runCmd = titleCmd
634
- ? `cd ${shellEscape(projectRoot)} && ${titleCmd} && ${directCmd}`
635
- : `cd ${shellEscape(projectRoot)} && ${directCmd}`;
610
+ // Launch agent binary directly; launcher.js creates inject.sock and
611
+ // handles activity_state monitoring internally via its own PTY wrapper.
612
+ if (preRegistrationError) {
613
+ console.error(
614
+ `[host-launch] pre-registration failed for ${nickname || agentType}: ${preRegistrationError.message || String(preRegistrationError)}`
615
+ );
636
616
  }
617
+ env.UFOO_FORCE_PTY = "1";
618
+ const directCmd = `${binary}${argText}`;
619
+ const runCmd = titleCmd
620
+ ? `cd ${shellEscape(projectRoot)} && ${titleCmd} && ${directCmd}`
621
+ : `cd ${shellEscape(projectRoot)} && ${directCmd}`;
637
622
  createOptions.command = runCmd;
638
623
  createOptions.env = env;
639
624
 
@@ -671,7 +656,7 @@ async function spawnInternalAgent(
671
656
  fs.mkdirSync(logDir, { recursive: true });
672
657
 
673
658
  const crypto = require("crypto");
674
- const EventBus = require("../bus");
659
+ const EventBus = require("../../coordination/bus");
675
660
  const children = [];
676
661
  const subscriberIds = [];
677
662
 
@@ -707,10 +692,7 @@ async function spawnInternalAgent(
707
692
  ? (count > 1 ? `${nickname}-${i + 1}` : nickname)
708
693
  : "";
709
694
  const providerSessionId = typeof options.providerSessionId === "string" ? options.providerSessionId.trim() : "";
710
- const usePty = typeof options.usePty === "boolean"
711
- ? options.usePty
712
- : process.env.UFOO_INTERNAL_PTY !== "0";
713
- const launchMode = usePty ? "internal-pty" : "internal";
695
+ const launchMode = "internal";
714
696
 
715
697
  // 传递 launch_mode 和 parent PID 到 join
716
698
  const joinResult = await bus.subscriberManager.join(sessionId, agentType, requestedNickname, {
@@ -722,10 +704,9 @@ async function spawnInternalAgent(
722
704
  bus.saveBusData();
723
705
 
724
706
  const managedBootstrap = applyDefaultManagedBootstrap(projectRoot, normalizedAgent, extraArgs, extraEnv);
725
- const runnerCmd = usePty ? "agent-pty-runner" : "agent-runner";
707
+ const runnerCmd = "agent-runner";
726
708
  const args = managedBootstrap.args;
727
709
  const child = spawn(process.execPath, [runner, runnerCmd, agent, ...args], {
728
- // 关键改动:不使用 detached,daemon 作为父进程
729
710
  detached: false,
730
711
  stdio: ["ignore", errLog, errLog],
731
712
  cwd: projectRoot,
@@ -733,17 +714,16 @@ async function spawnInternalAgent(
733
714
  ...process.env,
734
715
  ...(managedBootstrap.extraEnv && typeof managedBootstrap.extraEnv === "object" ? managedBootstrap.extraEnv : {}),
735
716
  UFOO_INTERNAL_AGENT: "1",
736
- UFOO_INTERNAL_PTY: usePty ? "1" : "0",
737
- UFOO_SUBSCRIBER_ID: subscriberId, // 直接传递 subscriber ID
717
+ UFOO_SUBSCRIBER_ID: subscriberId,
738
718
  UFOO_NICKNAME: finalNickname,
739
- UFOO_LAUNCH_MODE: usePty ? "internal-pty" : "internal",
719
+ UFOO_LAUNCH_MODE: "internal",
740
720
  UFOO_PARENT_PID: String(originalPid),
741
721
  ...(providerSessionId ? { UFOO_PROVIDER_SESSION_ID: providerSessionId } : {}),
742
722
  },
743
723
  });
744
724
 
745
725
  // Update bus data with the actual child PID so isMetaActive
746
- // can detect when the ptyRunner process dies.
726
+ // can detect when the runner process dies.
747
727
  try {
748
728
  bus.loadBusData();
749
729
  if (bus.busData.agents && bus.busData.agents[subscriberId]) {
@@ -953,8 +933,7 @@ async function launchAgent(projectRoot, agent, count = 1, nickname = "", process
953
933
  throw new Error(`unsupported agent type: ${agent}`);
954
934
  }
955
935
 
956
- if (mode === "internal" || mode === "internal-pty") {
957
- const usePty = mode === "internal-pty";
936
+ if (mode === "internal") {
958
937
  const result = await spawnInternalAgent(
959
938
  projectRoot,
960
939
  normalizedAgent,
@@ -963,7 +942,7 @@ async function launchAgent(projectRoot, agent, count = 1, nickname = "", process
963
942
  processManager,
964
943
  launchEnvObject,
965
944
  extraArgs,
966
- { usePty }
945
+ {}
967
946
  );
968
947
  return { mode, launchScope, subscriberIds: result.subscriberIds };
969
948
  }
@@ -1100,6 +1079,9 @@ function buildResumeArgs(agent, sessionId) {
1100
1079
  if (!sessionId) return [];
1101
1080
  if (agent === "codex") return ["resume", sessionId];
1102
1081
  if (agent === "claude") return ["--session-id", sessionId];
1082
+ // Agy resumes by conversation UUID; bin/uagy.js de-duplicates if the same
1083
+ // flag is already injected via provider_session_id readback.
1084
+ if (agent === "agy") return [`--conversation=${sessionId}`];
1103
1085
  return [];
1104
1086
  }
1105
1087
 
@@ -1152,7 +1134,7 @@ function collectRecoverableAgents(projectRoot, target = "") {
1152
1134
  continue;
1153
1135
  }
1154
1136
  const agent = normalizeAgentType(meta.agent_type);
1155
- if (agent !== "codex" && agent !== "claude") {
1137
+ if (agent !== "codex" && agent !== "claude" && agent !== "agy") {
1156
1138
  skipped.push({ id, reason: "unsupported agent type" });
1157
1139
  continue;
1158
1140
  }
@@ -1196,7 +1178,7 @@ async function resumeAgents(projectRoot, target = "", processManager = null) {
1196
1178
  const args = buildResumeArgs(item.agent, sessionId);
1197
1179
  let reused = false;
1198
1180
  let resumedId = item.id;
1199
- if (mode === "internal" || mode === "internal-pty") {
1181
+ if (mode === "internal") {
1200
1182
  // Internal agents have no terminal/pane to reattach. Start a fresh
1201
1183
  // daemon-managed runner and replace the old recoverable registration.
1202
1184
  // The provider session is still reused via the normal provider args.
@@ -1207,9 +1189,9 @@ async function resumeAgents(projectRoot, target = "", processManager = null) {
1207
1189
  1,
1208
1190
  nickname,
1209
1191
  processManager,
1210
- { UFOO_SKIP_SESSION_PROBE: "1" },
1192
+ { UFOO_SKIP_SESSION_RESOLVE: "1" },
1211
1193
  args,
1212
- { replaceAgentId: item.id, providerSessionId: sessionId, usePty: mode === "internal-pty" }
1194
+ { replaceAgentId: item.id, providerSessionId: sessionId }
1213
1195
  );
1214
1196
  resumedId = launchResult.subscriberIds && launchResult.subscriberIds[0]
1215
1197
  ? launchResult.subscriberIds[0]
@@ -1217,7 +1199,7 @@ async function resumeAgents(projectRoot, target = "", processManager = null) {
1217
1199
  } else {
1218
1200
  reused = await tryReuseTerminal(projectRoot, item.id, item.meta, item.agent, sessionId);
1219
1201
  if (!reused) {
1220
- const envPrefix = "UFOO_SKIP_SESSION_PROBE=1";
1202
+ const envPrefix = "UFOO_SKIP_SESSION_RESOLVE=1";
1221
1203
  if (mode === "tmux") {
1222
1204
  // eslint-disable-next-line no-await-in-loop
1223
1205
  await spawnTmuxWindow(projectRoot, item.agent, nickname, args, envPrefix);
@@ -1334,5 +1316,10 @@ module.exports = {
1334
1316
  resolveConfiguredLaunchMode,
1335
1317
  resolveHostLaunchContext,
1336
1318
  resolveNativeTerminalApp,
1319
+ normalizeLaunchAgent,
1320
+ toBusAgentType,
1321
+ toTerminalBinary,
1322
+ toTmuxBinary,
1323
+ buildResumeArgs,
1337
1324
  },
1338
1325
  };
@@ -1,4 +1,4 @@
1
- const { finalizeRouterPayload } = require("../controller/routerFinalize");
1
+ const { finalizeRouterPayload } = require("../../orchestration/controller/routerFinalize");
2
2
 
3
3
  function normalizePayload(payload) {
4
4
  if (!payload || typeof payload !== "object") {
@@ -1,34 +1,34 @@
1
1
  "use strict";
2
2
 
3
- const { IPC_RESPONSE_TYPES } = require("../shared/eventContract");
3
+ const { IPC_RESPONSE_TYPES } = require("../contracts/eventContract");
4
4
  const {
5
5
  listControllerInboxEntries,
6
6
  consumeControllerInboxEntries,
7
- } = require("../report/store");
7
+ } = require("../../coordination/report/store");
8
8
  const { isGlobalControllerProjectRoot } = require("../projects");
9
9
  const {
10
10
  resolveGateRouterConfig,
11
11
  shouldUseGateRouter,
12
- } = require("../controller/gateRouter");
12
+ } = require("../../orchestration/controller/gateRouter");
13
13
  const {
14
14
  CONTROLLER_MODES,
15
15
  applyControllerModeForMessage,
16
16
  resolveControllerMode,
17
- } = require("../controller/flags");
17
+ } = require("../../orchestration/controller/flags");
18
18
  const {
19
19
  resolveLoopRuntimeOptions,
20
20
  runPromptWithControllerLoop,
21
- } = require("../agent/loopRuntime");
21
+ } = require("../../agents/controller/loopRuntime");
22
22
  const {
23
23
  appendShadowDiff,
24
24
  createLoopObserver,
25
- } = require("../agent/loopObservability");
25
+ } = require("../../agents/controller/loopObservability");
26
26
  const {
27
27
  DEFAULT_SHADOW_SAMPLING_RATE,
28
28
  createShadowBudgetBreaker,
29
29
  createShadowGuard,
30
30
  shouldSampleShadow,
31
- } = require("../controller/shadowGuard");
31
+ } = require("../../orchestration/controller/shadowGuard");
32
32
 
33
33
  function normalizeProjectRoute(route) {
34
34
  if (!route || typeof route !== "object") return null;
@@ -0,0 +1,230 @@
1
+ const fs = require("fs");
2
+ const os = require("os");
3
+ const path = require("path");
4
+ const { loadAgentsData, saveAgentsData } = require("../../coordination/state/agentsStore");
5
+ const { getUfooPaths } = require("../../coordination/state/paths");
6
+
7
+ function persistProviderSession(projectRoot, subscriberId, payload) {
8
+ const filePath = getUfooPaths(projectRoot).agentsFile;
9
+ const data = loadAgentsData(filePath);
10
+ const meta = data.agents[subscriberId] || {};
11
+ data.agents[subscriberId] = {
12
+ ...meta,
13
+ provider_session_id: payload.sessionId || "",
14
+ provider_session_source: payload.source || "",
15
+ provider_session_updated_at: new Date().toISOString(),
16
+ };
17
+ saveAgentsData(filePath, data);
18
+ }
19
+
20
+ function loadProviderSessionCache(projectRoot) {
21
+ const filePath = getUfooPaths(projectRoot).agentsFile;
22
+ const data = loadAgentsData(filePath);
23
+ const cache = new Map();
24
+ for (const [id, meta] of Object.entries(data.agents || {})) {
25
+ if (meta && meta.provider_session_id) {
26
+ cache.set(id, {
27
+ sessionId: meta.provider_session_id,
28
+ source: meta.provider_session_source || "",
29
+ updated_at: meta.provider_session_updated_at || "",
30
+ });
31
+ }
32
+ }
33
+ return cache;
34
+ }
35
+
36
+ /**
37
+ * Resolve Claude Code session ID directly from session file.
38
+ * Claude writes ~/.claude/sessions/<pid>.json with { sessionId, pid, cwd, ... }
39
+ */
40
+ function resolveClaudeSessionFromFile(pid) {
41
+ if (!pid) return null;
42
+ const filePath = path.join(os.homedir(), ".claude", "sessions", `${pid}.json`);
43
+ try {
44
+ if (!fs.existsSync(filePath)) return null;
45
+ const data = JSON.parse(fs.readFileSync(filePath, "utf8"));
46
+ const sessionId = data.sessionId || data.session_id || "";
47
+ if (!sessionId) return null;
48
+ return { sessionId, source: filePath };
49
+ } catch {
50
+ return null;
51
+ }
52
+ }
53
+
54
+ /**
55
+ * Resolve Codex session ID from session rollout files.
56
+ * Codex writes ~/.codex/sessions/YYYY/MM/DD/rollout-<ts>-<id>.jsonl
57
+ * First line contains { type: "session_meta", payload: { id, cwd, ... } }
58
+ */
59
+ function resolveCodexSessionFromFile(cwd) {
60
+ if (!cwd) return null;
61
+ try {
62
+ const now = new Date();
63
+ // Check today and yesterday (session may have started before midnight)
64
+ const dates = [now];
65
+ const yesterday = new Date(now);
66
+ yesterday.setDate(yesterday.getDate() - 1);
67
+ dates.push(yesterday);
68
+
69
+ let bestMatch = null;
70
+ let bestMtime = 0;
71
+
72
+ for (const d of dates) {
73
+ const yyyy = String(d.getFullYear());
74
+ const mm = String(d.getMonth() + 1).padStart(2, "0");
75
+ const dd = String(d.getDate()).padStart(2, "0");
76
+ const dir = path.join(os.homedir(), ".codex", "sessions", yyyy, mm, dd);
77
+ if (!fs.existsSync(dir)) continue;
78
+
79
+ const files = fs.readdirSync(dir)
80
+ .filter((f) => f.startsWith("rollout-") && f.endsWith(".jsonl"));
81
+
82
+ for (const file of files) {
83
+ const filePath = path.join(dir, file);
84
+ try {
85
+ const stat = fs.statSync(filePath);
86
+ if (stat.mtimeMs <= bestMtime) continue;
87
+
88
+ // Read first line for session_meta
89
+ const fd = fs.openSync(filePath, "r");
90
+ const buf = Buffer.alloc(4096);
91
+ const bytesRead = fs.readSync(fd, buf, 0, 4096, 0);
92
+ fs.closeSync(fd);
93
+ const firstLine = buf.toString("utf8", 0, bytesRead).split("\n")[0];
94
+ if (!firstLine) continue;
95
+
96
+ const record = JSON.parse(firstLine);
97
+ const payload = record.payload || record;
98
+ const sessionCwd = payload.cwd || "";
99
+ const sessionId = payload.id || "";
100
+
101
+ if (sessionId && sessionCwd === cwd && stat.mtimeMs > bestMtime) {
102
+ bestMatch = { sessionId, source: filePath };
103
+ bestMtime = stat.mtimeMs;
104
+ }
105
+ } catch {
106
+ continue;
107
+ }
108
+ }
109
+ }
110
+ return bestMatch;
111
+ } catch {
112
+ return null;
113
+ }
114
+ }
115
+
116
+ /**
117
+ * Resolve provider session ID directly from session files.
118
+ * @param {string} agentType - "claude-code" or "codex"
119
+ * @param {object} opts - { pid, cwd }
120
+ */
121
+ function resolveSessionFromFile(agentType, opts = {}) {
122
+ if (agentType === "claude-code") {
123
+ return resolveClaudeSessionFromFile(opts.pid);
124
+ }
125
+ if (agentType === "codex") {
126
+ return resolveCodexSessionFromFile(opts.cwd);
127
+ }
128
+ return null;
129
+ }
130
+
131
+ /**
132
+ * Retry reading session file (agent may not have written it yet)
133
+ */
134
+ async function resolveSessionFromFileWithRetries(agentType, opts = {}, attempts = 10, intervalMs = 1000) {
135
+ for (let i = 0; i < attempts; i += 1) {
136
+ const resolved = resolveSessionFromFile(agentType, opts);
137
+ if (resolved && resolved.sessionId) return resolved;
138
+ // eslint-disable-next-line no-await-in-loop
139
+ await new Promise((r) => setTimeout(r, intervalMs));
140
+ }
141
+ return null;
142
+ }
143
+
144
+ /**
145
+ * Schedule provider session resolution.
146
+ * Uses provider session files only. This intentionally avoids injecting
147
+ * `/ufoo <nickname>` / `$ufoo <nickname>` into agent terminals.
148
+ *
149
+ * @param {Object} options
150
+ * @param {string} options.projectRoot - Project root directory
151
+ * @param {string} options.subscriberId - Subscriber ID (e.g., "claude-code:abc123")
152
+ * @param {string} options.agentType - Agent type ("claude-code" or "codex")
153
+ * @param {number} options.agentPid - Agent child process PID (for claude-code)
154
+ * @param {string} options.agentCwd - Agent working directory (for codex)
155
+ * @param {number} options.delayMs - Delay before starting resolution
156
+ * @param {number} options.fileAttempts - File read retry attempts
157
+ * @param {number} options.fileIntervalMs - File read retry interval
158
+ * @param {Function} options.onResolved - Callback when session ID is found
159
+ */
160
+ function scheduleProviderSessionResolve({
161
+ projectRoot,
162
+ subscriberId,
163
+ agentType,
164
+ agentPid = 0,
165
+ agentCwd = "",
166
+ delayMs = 3000,
167
+ fileAttempts = 10,
168
+ fileIntervalMs = 1000,
169
+ onResolved = null,
170
+ }) {
171
+ if (!subscriberId || !agentType) return null;
172
+ if (agentType !== "codex" && agentType !== "claude-code") return null;
173
+
174
+ let executed = false;
175
+ let cancelled = false;
176
+ let timer = null;
177
+
178
+ const execute = async () => {
179
+ if (executed || cancelled) return;
180
+ executed = true;
181
+ if (timer) {
182
+ clearTimeout(timer);
183
+ timer = null;
184
+ }
185
+
186
+ // 1. Try direct file read (fast, non-invasive)
187
+ const fileOpts = { pid: agentPid, cwd: agentCwd || projectRoot };
188
+ const fileResolved = await resolveSessionFromFileWithRetries(
189
+ agentType, fileOpts, fileAttempts, fileIntervalMs,
190
+ );
191
+ if (cancelled) return;
192
+ if (fileResolved && fileResolved.sessionId) {
193
+ persistProviderSession(projectRoot, subscriberId, fileResolved);
194
+ if (typeof onResolved === "function") {
195
+ onResolved(subscriberId, fileResolved);
196
+ }
197
+ return;
198
+ }
199
+
200
+ // No terminal injection fallback. Session IDs are resolved from provider files only.
201
+ };
202
+
203
+ // Schedule delayed execution
204
+ timer = setTimeout(execute, delayMs);
205
+
206
+ // Return handle for early trigger or cancellation
207
+ return {
208
+ subscriberId,
209
+ triggerNow: execute,
210
+ cancel: () => {
211
+ cancelled = true;
212
+ executed = true;
213
+ if (timer) {
214
+ clearTimeout(timer);
215
+ timer = null;
216
+ }
217
+ },
218
+ };
219
+ }
220
+
221
+ module.exports = {
222
+ scheduleProviderSessionResolve,
223
+ resolveSessionFromFile,
224
+ persistProviderSession,
225
+ loadProviderSessionCache,
226
+ __private: {
227
+ resolveClaudeSessionFromFile,
228
+ resolveCodexSessionFromFile,
229
+ },
230
+ };
@@ -1,14 +1,14 @@
1
1
  const fs = require("fs");
2
- const EventBus = require("../bus");
3
- const { BUS_STATUS_PHASES } = require("../shared/eventContract");
2
+ const EventBus = require("../../coordination/bus");
3
+ const { BUS_STATUS_PHASES } = require("../contracts/eventContract");
4
4
  const {
5
5
  REPORT_PHASES,
6
6
  normalizeReportInput,
7
7
  appendReport,
8
8
  updateReportState,
9
9
  appendControllerInboxEntry,
10
- } = require("../report/store");
11
- const { getUfooPaths } = require("../ufoo/paths");
10
+ } = require("../../coordination/report/store");
11
+ const { getUfooPaths } = require("../../coordination/state/paths");
12
12
  const { resolveDisplayNickname } = require("./nicknameScope");
13
13
 
14
14
  function resolveAgentDisplayName(projectRoot, agentId) {
@@ -1,7 +1,7 @@
1
1
  const path = require("path");
2
2
  const { startDaemon, stopDaemon, isRunning } = require("./index");
3
- const { loadConfig, defaultAgentModelForProvider } = require("../config");
4
- const { resolveNodeExecutable } = require("../utils/nodeExecutable");
3
+ const { loadConfig, defaultAgentModelForProvider } = require("../../config");
4
+ const { resolveNodeExecutable } = require("../process/nodeExecutable");
5
5
 
6
6
  function runDaemonCli(argv) {
7
7
  const cmd = argv[1] || "start";
@@ -20,7 +20,7 @@ function runDaemonCli(argv) {
20
20
  if (isRunning(projectRoot)) return;
21
21
  if (!process.env.UFOO_DAEMON_CHILD) {
22
22
  const { spawn } = require("child_process");
23
- const child = spawn(resolveNodeExecutable(), [path.join(__dirname, "..", "..", "bin", "ufoo.js"), "daemon", "start"], {
23
+ const child = spawn(resolveNodeExecutable(), [path.join(__dirname, "..", "..", "..", "bin", "ufoo.js"), "daemon", "start"], {
24
24
  detached: true,
25
25
  stdio: "ignore",
26
26
  env: { ...process.env, UFOO_DAEMON_CHILD: "1" },
@@ -57,7 +57,7 @@ function runDaemonCli(argv) {
57
57
  if (!process.env.UFOO_DAEMON_CHILD) {
58
58
  const { spawn } = require("child_process");
59
59
  const childEnv = { ...process.env, UFOO_DAEMON_CHILD: "1" };
60
- const child = spawn(resolveNodeExecutable(), [path.join(__dirname, "..", "..", "bin", "ufoo.js"), "daemon", "start"], {
60
+ const child = spawn(resolveNodeExecutable(), [path.join(__dirname, "..", "..", "..", "bin", "ufoo.js"), "daemon", "start"], {
61
61
  detached: true,
62
62
  stdio: "ignore",
63
63
  env: childEnv,
@@ -1,24 +1,24 @@
1
1
  "use strict";
2
2
 
3
3
  const path = require("path");
4
- const EventBus = require("../bus");
5
- const { prepareUcodeBootstrap } = require("../agent/ucodeBootstrap");
6
- const { isMetaActive } = require("../bus/utils");
7
- const { getUfooPaths } = require("../ufoo/paths");
4
+ const EventBus = require("../../coordination/bus");
5
+ const { prepareUcodeBootstrap } = require("../../code/launcher/ucodeBootstrap");
6
+ const { isMetaActive } = require("../../coordination/bus/utils");
7
+ const { getUfooPaths } = require("../../coordination/state/paths");
8
8
  const {
9
9
  applyProjectNicknamePrefix,
10
10
  resolveDisplayNickname,
11
11
  resolveScopedNickname,
12
12
  } = require("./nicknameScope");
13
- const { loadAgentsData, saveAgentsData } = require("../ufoo/agentsStore");
13
+ const { loadAgentsData, saveAgentsData } = require("../../coordination/state/agentsStore");
14
14
  const {
15
15
  loadPromptProfileRegistry,
16
16
  resolvePromptProfileReference,
17
- } = require("../group/promptProfiles");
17
+ } = require("../../orchestration/groups/promptProfiles");
18
18
  const {
19
19
  buildSoloPromptMetadata,
20
20
  composeSoloBootstrapPrompt,
21
- } = require("../group/bootstrap");
21
+ } = require("../../orchestration/groups/bootstrap");
22
22
 
23
23
  function sleep(ms) {
24
24
  return new Promise((resolve) => setTimeout(resolve, ms));