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,533 +0,0 @@
1
- const DEFAULT_MODE_OPTIONS = ["auto", "host", "terminal", "tmux", "internal-pty", "internal"];
2
-
3
- function createDashboardKeyController(options = {}) {
4
- const {
5
- state,
6
- globalMode = false,
7
- existsSync = () => false,
8
- getInjectSockPath = () => "",
9
- getAgentAdapter = () => null,
10
- activateAgent = () => {},
11
- requestCloseAgent = () => {},
12
- enterAgentView = () => {},
13
- exitAgentView = () => {},
14
- setAgentBarVisible = () => {},
15
- requestAgentSnapshot = () => {},
16
- clearTargetAgent = () => {},
17
- restoreTargetFromSelection = () => {},
18
- exitDashboardMode = () => {},
19
- setLaunchMode = () => {},
20
- setAgentProvider = () => {},
21
- clampAgentWindow = () => {},
22
- clampAgentWindowWithSelection = () => {},
23
- requestProjectSwitch = () => {},
24
- requestCloseProject = () => {},
25
- requestCron = () => {},
26
- setGlobalScope = () => {},
27
- getGlobalScope = () => "",
28
- renderDashboard = () => {},
29
- renderAgentDashboard = () => {},
30
- renderScreen = () => {},
31
- setScreenGrabKeys = () => {},
32
- modeOptions = DEFAULT_MODE_OPTIONS,
33
- } = options;
34
-
35
- if (!state || typeof state !== "object") {
36
- throw new Error("createDashboardKeyController requires a mutable state object");
37
- }
38
-
39
- function renderDashboardAndScreen() {
40
- renderDashboard();
41
- renderScreen();
42
- }
43
-
44
- function getAgentCapabilities(agentId) {
45
- const adapter = getAgentAdapter(agentId);
46
- return adapter && adapter.capabilities ? adapter.capabilities : null;
47
- }
48
-
49
- function supportsActivate(agentId) {
50
- const caps = getAgentCapabilities(agentId);
51
- return Boolean(caps && caps.supportsActivate);
52
- }
53
-
54
- function supportsSocket(agentId) {
55
- const caps = getAgentCapabilities(agentId);
56
- return Boolean(caps && caps.supportsSocketProtocol);
57
- }
58
-
59
- function supportsInternalQueue(agentId) {
60
- const caps = getAgentCapabilities(agentId);
61
- return Boolean(caps && caps.supportsInternalQueueLoop);
62
- }
63
-
64
- function withAgentInputFocus() {
65
- state.focusMode = "input";
66
- state.agentOutputSuppressed = false;
67
- setAgentBarVisible(true);
68
- }
69
-
70
- function activateExternalAgent(agentId) {
71
- try {
72
- activateAgent(agentId);
73
- } catch {
74
- // Activation is best-effort.
75
- }
76
- }
77
-
78
- function switchAgentView(agentId) {
79
- withAgentInputFocus();
80
- enterAgentView(agentId, { useBus: supportsInternalQueue(agentId) && !supportsSocket(agentId) });
81
- }
82
-
83
- function exitAgentDashboardToInput() {
84
- withAgentInputFocus();
85
- renderAgentDashboard();
86
- requestAgentSnapshot();
87
- }
88
-
89
- function handleAgentDashboardKey(key) {
90
- const totalItems = 1 + state.activeAgents.length;
91
-
92
- if (key.name === "left") {
93
- if (state.selectedAgentIndex > 0) {
94
- state.selectedAgentIndex -= 1;
95
- }
96
- clampAgentWindowWithSelection(state.selectedAgentIndex > 0 ? state.selectedAgentIndex - 1 : -1);
97
- renderAgentDashboard();
98
- return true;
99
- }
100
-
101
- if (key.name === "right") {
102
- if (state.selectedAgentIndex < totalItems - 1) {
103
- state.selectedAgentIndex += 1;
104
- }
105
- clampAgentWindowWithSelection(state.selectedAgentIndex > 0 ? state.selectedAgentIndex - 1 : -1);
106
- renderAgentDashboard();
107
- return true;
108
- }
109
-
110
- if (key.name === "enter" || key.name === "return") {
111
- if (state.selectedAgentIndex === 0) {
112
- exitAgentView();
113
- return true;
114
- }
115
-
116
- const agentId = state.activeAgents[state.selectedAgentIndex - 1];
117
- if (!agentId) {
118
- return true;
119
- }
120
-
121
- if (agentId === state.viewingAgent) {
122
- exitAgentDashboardToInput();
123
- return true;
124
- }
125
-
126
- if (supportsActivate(agentId)) {
127
- exitAgentView();
128
- activateExternalAgent(agentId);
129
- return true;
130
- }
131
-
132
- switchAgentView(agentId);
133
- return true;
134
- }
135
-
136
- if (key.name === "up") {
137
- exitAgentDashboardToInput();
138
- return true;
139
- }
140
-
141
- if (key.name === "x" && key.ctrl) {
142
- if (state.selectedAgentIndex <= 0 || state.selectedAgentIndex > state.activeAgents.length) {
143
- return true;
144
- }
145
-
146
- const agentId = state.activeAgents[state.selectedAgentIndex - 1];
147
- const remaining = state.activeAgents.filter((id) => id !== agentId);
148
- const nextIndex = remaining.length > 0
149
- ? Math.min(state.selectedAgentIndex - 1, remaining.length - 1)
150
- : -1;
151
- const nextAgent = nextIndex >= 0 ? remaining[nextIndex] : null;
152
-
153
- if (agentId === state.viewingAgent) {
154
- if (nextAgent) {
155
- if (supportsActivate(nextAgent)) {
156
- exitAgentView();
157
- activateExternalAgent(nextAgent);
158
- } else {
159
- withAgentInputFocus();
160
- state.selectedAgentIndex = nextIndex + 1;
161
- enterAgentView(nextAgent, { useBus: supportsInternalQueue(nextAgent) && !supportsSocket(nextAgent) });
162
- }
163
- } else {
164
- exitAgentView();
165
- }
166
- } else if (nextAgent) {
167
- state.selectedAgentIndex = nextIndex + 1;
168
- renderAgentDashboard();
169
- } else {
170
- state.selectedAgentIndex = 0;
171
- renderAgentDashboard();
172
- }
173
-
174
- requestCloseAgent(agentId);
175
- return true;
176
- }
177
-
178
- return true;
179
- }
180
-
181
- function handleModeKey(key) {
182
- if (key.name === "left") {
183
- state.selectedModeIndex = state.selectedModeIndex <= 0 ? modeOptions.length - 1 : state.selectedModeIndex - 1;
184
- renderDashboardAndScreen();
185
- return true;
186
- }
187
-
188
- if (key.name === "right") {
189
- state.selectedModeIndex = state.selectedModeIndex >= modeOptions.length - 1 ? 0 : state.selectedModeIndex + 1;
190
- renderDashboardAndScreen();
191
- return true;
192
- }
193
-
194
- if (key.name === "down") {
195
- state.dashboardView = "provider";
196
- state.selectedProviderIndex = Math.max(0, (state.providerOptions || []).findIndex((opt) => opt.value === state.agentProvider));
197
- renderDashboardAndScreen();
198
- return true;
199
- }
200
-
201
- if (key.name === "up") {
202
- state.dashboardView = "agents";
203
- restoreTargetFromSelection();
204
- renderDashboardAndScreen();
205
- return true;
206
- }
207
-
208
- if (key.name === "enter" || key.name === "return") {
209
- const mode = modeOptions[state.selectedModeIndex];
210
- if (mode) setLaunchMode(mode);
211
- exitDashboardMode(false);
212
- return true;
213
- }
214
-
215
- if (key.name === "escape") {
216
- exitDashboardMode(false);
217
- return true;
218
- }
219
-
220
- return true;
221
- }
222
-
223
- function handleProviderKey(key) {
224
- if (key.name === "left") {
225
- state.selectedProviderIndex = state.selectedProviderIndex <= 0
226
- ? state.providerOptions.length - 1
227
- : state.selectedProviderIndex - 1;
228
- renderDashboardAndScreen();
229
- return true;
230
- }
231
-
232
- if (key.name === "right") {
233
- state.selectedProviderIndex = state.selectedProviderIndex >= state.providerOptions.length - 1
234
- ? 0
235
- : state.selectedProviderIndex + 1;
236
- renderDashboardAndScreen();
237
- return true;
238
- }
239
-
240
- if (key.name === "down") {
241
- state.dashboardView = "cron";
242
- const cronTasks = Array.isArray(state.cronTasks) ? state.cronTasks : [];
243
- state.selectedCronIndex = cronTasks.length > 0 ? 0 : -1;
244
- renderDashboardAndScreen();
245
- return true;
246
- }
247
-
248
- if (key.name === "up") {
249
- state.dashboardView = "mode";
250
- renderDashboardAndScreen();
251
- return true;
252
- }
253
-
254
- if (key.name === "enter" || key.name === "return") {
255
- const selected = state.providerOptions[state.selectedProviderIndex];
256
- if (selected) setAgentProvider(selected.value);
257
- exitDashboardMode(false);
258
- return true;
259
- }
260
-
261
- if (key.name === "escape") {
262
- exitDashboardMode(false);
263
- return true;
264
- }
265
-
266
- return true;
267
- }
268
-
269
- function handleCronKey(key) {
270
- const cronTasks = Array.isArray(state.cronTasks) ? state.cronTasks : [];
271
- const maxIndex = cronTasks.length - 1;
272
-
273
- if (key.name === "left") {
274
- if (maxIndex >= 0 && state.selectedCronIndex > 0) {
275
- state.selectedCronIndex -= 1;
276
- renderDashboardAndScreen();
277
- }
278
- return true;
279
- }
280
-
281
- if (key.name === "right") {
282
- if (maxIndex >= 0 && state.selectedCronIndex < maxIndex) {
283
- state.selectedCronIndex += 1;
284
- renderDashboardAndScreen();
285
- }
286
- return true;
287
- }
288
-
289
- if (key.name === "up") {
290
- state.dashboardView = "provider";
291
- renderDashboardAndScreen();
292
- return true;
293
- }
294
-
295
- if (key.name === "x" && key.ctrl) {
296
- if (maxIndex >= 0 && state.selectedCronIndex >= 0 && state.selectedCronIndex <= maxIndex) {
297
- const task = cronTasks[state.selectedCronIndex];
298
- const id = task && task.id ? String(task.id).trim() : "";
299
- if (id) {
300
- requestCron({ operation: "stop", id });
301
- return true;
302
- }
303
- }
304
- exitDashboardMode(false);
305
- return true;
306
- }
307
-
308
- if (key.name === "escape" || key.name === "enter" || key.name === "return") {
309
- exitDashboardMode(false);
310
- return true;
311
- }
312
-
313
- return true;
314
- }
315
-
316
- function handleProjectsKey(key) {
317
- const projects = Array.isArray(state.projects) ? state.projects : [];
318
- if (projects.length === 0) {
319
- if (key.name === "up" || key.name === "enter" || key.name === "return" || key.name === "escape") {
320
- exitDashboardMode(false);
321
- }
322
- return true;
323
- }
324
-
325
- if (key.name === "x" && key.ctrl) {
326
- const current = Number.isFinite(state.selectedProjectIndex) ? state.selectedProjectIndex : 0;
327
- if (current >= 0 && current < projects.length) {
328
- requestCloseProject(current);
329
- }
330
- return true;
331
- }
332
-
333
- if (key.name === "down") {
334
- state.dashboardView = "agents";
335
- if (!Array.isArray(state.activeAgents) || state.activeAgents.length === 0) {
336
- state.selectedAgentIndex = -1;
337
- } else if (!Number.isFinite(state.selectedAgentIndex) || state.selectedAgentIndex < 0) {
338
- state.selectedAgentIndex = 0;
339
- } else if (state.selectedAgentIndex >= state.activeAgents.length) {
340
- state.selectedAgentIndex = state.activeAgents.length - 1;
341
- }
342
- clampAgentWindow();
343
- syncTargetFromSelection();
344
- renderDashboardAndScreen();
345
- return true;
346
- }
347
-
348
- if (key.name === "left") {
349
- const current = Number.isFinite(state.selectedProjectIndex) ? state.selectedProjectIndex : 0;
350
- if (current > 0) {
351
- const next = current - 1;
352
- state.selectedProjectIndex = next;
353
- renderDashboardAndScreen();
354
- if (getGlobalScope() === "project") {
355
- requestProjectSwitch(next);
356
- }
357
- }
358
- return true;
359
- }
360
-
361
- if (key.name === "right") {
362
- const current = Number.isFinite(state.selectedProjectIndex) ? state.selectedProjectIndex : 0;
363
- if (current < projects.length - 1) {
364
- const next = current + 1;
365
- state.selectedProjectIndex = next;
366
- renderDashboardAndScreen();
367
- if (getGlobalScope() === "project") {
368
- requestProjectSwitch(next);
369
- }
370
- }
371
- return true;
372
- }
373
-
374
- if (key.name === "up") {
375
- exitDashboardMode(false);
376
- return true;
377
- }
378
-
379
- if (key.name === "escape") {
380
- if (getGlobalScope() === "project") {
381
- setGlobalScope("controller");
382
- }
383
- exitDashboardMode(false);
384
- return true;
385
- }
386
-
387
- if (key.name === "enter" || key.name === "return") {
388
- const current = Number.isFinite(state.selectedProjectIndex) ? state.selectedProjectIndex : 0;
389
- if (current >= 0 && current < projects.length) {
390
- const selectedRow = projects[current];
391
- const selectedProjectRoot = String((selectedRow && selectedRow.project_root) || "");
392
- if (selectedProjectRoot) {
393
- setGlobalScope("project", selectedProjectRoot);
394
- }
395
- }
396
- exitDashboardMode(false);
397
- return true;
398
- }
399
-
400
- return true;
401
- }
402
-
403
- function handleAgentsKey(key) {
404
- if (key.name === "left") {
405
- if (state.activeAgents.length > 0 && state.selectedAgentIndex > 0) {
406
- state.selectedAgentIndex -= 1;
407
- clampAgentWindow();
408
- syncTargetFromSelection();
409
- renderDashboardAndScreen();
410
- }
411
- return true;
412
- }
413
-
414
- if (key.name === "right") {
415
- if (state.activeAgents.length > 0 && state.selectedAgentIndex < state.activeAgents.length - 1) {
416
- state.selectedAgentIndex += 1;
417
- clampAgentWindow();
418
- syncTargetFromSelection();
419
- renderDashboardAndScreen();
420
- }
421
- return true;
422
- }
423
-
424
- if (key.name === "down") {
425
- clearTargetAgent();
426
- state.dashboardView = "mode";
427
- const launchModeIndex = modeOptions.indexOf(state.launchMode);
428
- state.selectedModeIndex = launchModeIndex >= 0 ? launchModeIndex : 0;
429
- renderDashboardAndScreen();
430
- return true;
431
- }
432
-
433
- if (key.name === "up") {
434
- clearTargetAgent();
435
- if (globalMode) {
436
- state.dashboardView = "projects";
437
- renderDashboardAndScreen();
438
- return true;
439
- }
440
- exitDashboardMode(false);
441
- return true;
442
- }
443
-
444
- if (key.name === "escape") {
445
- clearTargetAgent();
446
- exitDashboardMode(false);
447
- return true;
448
- }
449
-
450
- if (key.name === "x" && key.ctrl) {
451
- if (state.selectedAgentIndex >= 0 && state.selectedAgentIndex < state.activeAgents.length) {
452
- const agentId = state.activeAgents[state.selectedAgentIndex];
453
- requestCloseAgent(agentId);
454
- clearTargetAgent();
455
- exitDashboardMode(false);
456
- }
457
- return true;
458
- }
459
-
460
- if (key.name === "enter" || key.name === "return") {
461
- if (state.selectedAgentIndex >= 0 && state.selectedAgentIndex < state.activeAgents.length) {
462
- const agentId = state.activeAgents[state.selectedAgentIndex];
463
- if (supportsActivate(agentId)) {
464
- clearTargetAgent();
465
- exitDashboardMode(false);
466
- activateExternalAgent(agentId);
467
- return true;
468
- }
469
-
470
- const sockPath = getInjectSockPath(agentId);
471
- if (supportsSocket(agentId) && existsSync(sockPath)) {
472
- clearTargetAgent();
473
- state.focusMode = "input";
474
- state.dashboardView = "agents";
475
- state.selectedAgentIndex = -1;
476
- setScreenGrabKeys(false);
477
- enterAgentView(agentId);
478
- return true;
479
- }
480
-
481
- if (supportsInternalQueue(agentId)) {
482
- clearTargetAgent();
483
- state.focusMode = "input";
484
- state.dashboardView = "agents";
485
- state.selectedAgentIndex = -1;
486
- setScreenGrabKeys(false);
487
- enterAgentView(agentId, { useBus: true });
488
- return true;
489
- }
490
- }
491
-
492
- exitDashboardMode(false);
493
- return true;
494
- }
495
-
496
- return false;
497
- }
498
-
499
- function syncTargetFromSelection() {
500
- if (typeof options.syncTargetFromSelection === "function") {
501
- options.syncTargetFromSelection();
502
- }
503
- }
504
-
505
- function handleDashboardKey(key) {
506
- if (!key || state.focusMode !== "dashboard") return false;
507
-
508
- if (state.currentView === "agent") {
509
- return handleAgentDashboardKey(key);
510
- }
511
-
512
- if (globalMode && state.dashboardView === "projects") {
513
- return handleProjectsKey(key);
514
- }
515
- if (!globalMode && state.dashboardView === "projects") {
516
- return true;
517
- }
518
-
519
- if (state.dashboardView === "mode") return handleModeKey(key);
520
- if (state.dashboardView === "provider") return handleProviderKey(key);
521
- if (state.dashboardView === "cron") return handleCronKey(key);
522
-
523
- return handleAgentsKey(key);
524
- }
525
-
526
- return {
527
- handleDashboardKey,
528
- };
529
- }
530
-
531
- module.exports = {
532
- createDashboardKeyController,
533
- };