u-foo 2.3.32 → 2.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 +63 -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}/daemonReconnect.js +3 -0
  54. package/src/{chat → app/chat}/dashboardView.js +2 -1
  55. package/src/app/chat/index.js +6 -0
  56. package/src/{chat → app/chat}/inputSubmitHandler.js +4 -13
  57. package/src/{chat → app/chat}/internalAgentLogHistory.js +1 -1
  58. package/src/app/chat/multiWindow/index.js +268 -0
  59. package/src/app/chat/multiWindow/paneLayout.js +84 -0
  60. package/src/app/chat/multiWindow/paneManager.js +299 -0
  61. package/src/app/chat/multiWindow/renderer.js +384 -0
  62. package/src/app/chat/multiWindow/virtualTerminal.js +327 -0
  63. package/src/{chat → app/chat}/transport.js +1 -1
  64. package/src/{cli → app/cli}/ctxCoreCommands.js +3 -3
  65. package/src/{doctor/index.js → app/cli/features/doctor.js} +1 -1
  66. package/src/{init/index.js → app/cli/features/init.js} +14 -32
  67. package/src/{cli → app/cli}/groupCoreCommands.js +2 -2
  68. package/src/app/cli/index.js +9 -0
  69. package/src/{cli → app/cli}/onlineCoreCommands.js +5 -5
  70. package/src/{cli.js → app/cli/run.js} +59 -57
  71. package/src/app/index.js +6 -0
  72. package/src/code/agent.js +10 -9
  73. package/src/code/index.js +2 -0
  74. package/src/code/launcher/index.js +9 -0
  75. package/src/{agent → code/launcher}/ucode.js +7 -8
  76. package/src/{agent → code/launcher}/ucodeBootstrap.js +3 -3
  77. package/src/{agent → code/launcher}/ucodeBuild.js +2 -2
  78. package/src/{agent → code/launcher}/ucodeDoctor.js +2 -2
  79. package/src/{agent → code/launcher}/ucodeRuntimeConfig.js +1 -2
  80. package/src/code/nativeRunner.js +4 -4
  81. package/src/code/tui.js +3 -1454
  82. package/src/config.js +15 -2
  83. package/src/{bus → coordination/bus}/activate.js +2 -2
  84. package/src/{bus → coordination/bus}/daemon.js +15 -5
  85. package/src/coordination/bus/envelope.js +173 -0
  86. package/src/{bus → coordination/bus}/index.js +7 -3
  87. package/src/{bus → coordination/bus}/inject.js +11 -3
  88. package/src/{bus → coordination/bus}/message.js +1 -1
  89. package/src/coordination/bus/messageMeta.js +130 -0
  90. package/src/coordination/bus/promptEnvelope.js +65 -0
  91. package/src/{bus → coordination/bus}/shake.js +1 -1
  92. package/src/{bus → coordination/bus}/store.js +3 -3
  93. package/src/{bus → coordination/bus}/subscriber.js +2 -2
  94. package/src/{bus → coordination/bus}/utils.js +2 -2
  95. package/src/{history → coordination/history}/inputTimeline.js +5 -5
  96. package/src/coordination/index.js +10 -0
  97. package/src/{memory → coordination/memory}/historySearch.js +1 -1
  98. package/src/{memory → coordination/memory}/index.js +3 -3
  99. package/src/{report → coordination/report}/store.js +2 -2
  100. package/src/{status → coordination/status}/index.js +3 -3
  101. package/src/online/bridge.js +2 -2
  102. package/src/{controller → orchestration/controller}/flags.js +1 -1
  103. package/src/{controller → orchestration/controller}/gateRouter.js +1 -1
  104. package/src/orchestration/controller/index.js +10 -0
  105. package/src/{controller → orchestration/controller}/shadowGuard.js +1 -1
  106. package/src/orchestration/groups/bootstrap.js +3 -0
  107. package/src/orchestration/groups/index.js +10 -0
  108. package/src/orchestration/groups/promptProfiles.js +3 -0
  109. package/src/{group → orchestration/groups}/templates.js +1 -1
  110. package/src/{group → orchestration/groups}/validateTemplate.js +1 -1
  111. package/src/orchestration/index.js +7 -0
  112. package/src/orchestration/solo/index.js +3 -0
  113. package/src/{daemon → runtime/daemon}/agentProcessManager.js +1 -1
  114. package/src/{daemon → runtime/daemon}/cronOps.js +3 -2
  115. package/src/{daemon → runtime/daemon}/groupOrchestrator.js +26 -9
  116. package/src/{daemon → runtime/daemon}/index.js +105 -53
  117. package/src/{daemon → runtime/daemon}/ipcServer.js +1 -1
  118. package/src/{daemon → runtime/daemon}/nicknameScope.js +6 -3
  119. package/src/{daemon → runtime/daemon}/ops.js +48 -61
  120. package/src/{daemon → runtime/daemon}/promptLoop.js +1 -1
  121. package/src/{daemon → runtime/daemon}/promptRequest.js +7 -7
  122. package/src/runtime/daemon/providerSessions.js +230 -0
  123. package/src/{daemon → runtime/daemon}/reporting.js +4 -4
  124. package/src/{daemon → runtime/daemon}/run.js +4 -4
  125. package/src/{daemon → runtime/daemon}/soloBootstrap.js +7 -7
  126. package/src/{daemon → runtime/daemon}/status.js +5 -5
  127. package/src/runtime/index.js +10 -0
  128. package/src/{projects → runtime/projects}/registry.js +1 -1
  129. package/src/{terminal → runtime/terminal}/adapterRouter.js +0 -10
  130. package/src/{terminal → runtime/terminal}/adapters/internalAdapter.js +0 -4
  131. package/src/tools/handlers/common.js +1 -1
  132. package/src/tools/handlers/listAgents.js +1 -1
  133. package/src/tools/handlers/memory.js +3 -3
  134. package/src/tools/handlers/readBusSummary.js +1 -1
  135. package/src/tools/handlers/readOpenDecisions.js +1 -1
  136. package/src/tools/handlers/readProjectRegistry.js +1 -1
  137. package/src/tools/handlers/readPromptHistory.js +2 -2
  138. package/src/tools/schemaFixtures.js +1 -1
  139. package/src/ui/MIGRATION.md +42 -88
  140. package/src/ui/format/index.js +5 -28
  141. package/src/ui/index.js +1 -1
  142. package/src/ui/{components → ink}/ChatApp.js +812 -88
  143. package/src/ui/ink/DashboardBar.js +685 -0
  144. package/src/ui/{components → ink}/MultilineInput.js +230 -5
  145. package/src/ui/{components → ink}/UcodeApp.js +16 -7
  146. package/src/ui/{components → ink}/agentMirror.js +24 -19
  147. package/src/ui/{components → ink}/chatReducer.js +29 -7
  148. package/src/bus/messageMeta.js +0 -52
  149. package/src/chat/agentViewController.js +0 -1072
  150. package/src/chat/chatLogController.js +0 -138
  151. package/src/chat/completionController.js +0 -533
  152. package/src/chat/dashboardKeyController.js +0 -533
  153. package/src/chat/index.js +0 -2222
  154. package/src/chat/inputHistoryController.js +0 -135
  155. package/src/chat/inputListenerController.js +0 -470
  156. package/src/chat/layout.js +0 -186
  157. package/src/chat/pasteController.js +0 -81
  158. package/src/chat/statusLineController.js +0 -223
  159. package/src/chat/streamTracker.js +0 -156
  160. package/src/code/config +0 -0
  161. package/src/daemon/providerSessions.js +0 -488
  162. package/src/terminal/adapters/internalPtyAdapter.js +0 -42
  163. package/src/ui/components/DashboardBar.js +0 -417
  164. /package/src/{code/prompts → agents/prompts/native}/actions.js +0 -0
  165. /package/src/{code/prompts → agents/prompts/native}/efficiency.js +0 -0
  166. /package/src/{code/prompts → agents/prompts/native}/environment.js +0 -0
  167. /package/src/{code/prompts → agents/prompts/native}/identity.js +0 -0
  168. /package/src/{code/prompts → agents/prompts/native}/safety.js +0 -0
  169. /package/src/{code/prompts → agents/prompts/native}/sections.js +0 -0
  170. /package/src/{code/prompts → agents/prompts/native}/system.js +0 -0
  171. /package/src/{code/prompts → agents/prompts/native}/tasks.js +0 -0
  172. /package/src/{code/prompts → agents/prompts/native}/toolDescriptions/bash.js +0 -0
  173. /package/src/{code/prompts → agents/prompts/native}/toolDescriptions/edit.js +0 -0
  174. /package/src/{code/prompts → agents/prompts/native}/toolDescriptions/read.js +0 -0
  175. /package/src/{code/prompts → agents/prompts/native}/toolDescriptions/write.js +0 -0
  176. /package/src/{code/prompts → agents/prompts/native}/ufoo.js +0 -0
  177. /package/src/{group → agents/prompts}/promptProfiles.js +0 -0
  178. /package/src/{agent → agents/providers}/claudeEventTranslator.js +0 -0
  179. /package/src/{agent → agents/providers}/claudeOauthTokenReader.js +0 -0
  180. /package/src/{agent → agents/providers}/claudeSessionFiles.js +0 -0
  181. /package/src/{agent → agents/providers}/codexEventTranslator.js +0 -0
  182. /package/src/{agent → agents/providers}/credentials/claude.js +0 -0
  183. /package/src/{agent → agents/providers}/credentials/codex.js +0 -0
  184. /package/src/{agent → agents/providers}/credentials/index.js +0 -0
  185. /package/src/{chat → app/chat}/agentBar.js +0 -0
  186. /package/src/{chat → app/chat}/agentDirectory.js +0 -0
  187. /package/src/{chat → app/chat}/cronScheduler.js +0 -0
  188. /package/src/{chat → app/chat}/daemonCoordinator.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
@@ -0,0 +1,327 @@
1
+ const DEFAULT_ATTR = { fg: 7, bg: 0, bold: false, dim: false, italic: false, underline: false, inverse: false, fgRgb: null, bgRgb: null };
2
+
3
+ function isWide(ch) {
4
+ if (!ch) return false;
5
+ const code = ch.codePointAt(0);
6
+ if (code < 0x1100) return false;
7
+ return (
8
+ (code >= 0x1100 && code <= 0x115f) ||
9
+ (code >= 0x2e80 && code <= 0xa4cf && code !== 0x303f) ||
10
+ (code >= 0xac00 && code <= 0xd7a3) ||
11
+ (code >= 0xf900 && code <= 0xfaff) ||
12
+ (code >= 0xfe10 && code <= 0xfe6f) ||
13
+ (code >= 0xff01 && code <= 0xff60) ||
14
+ (code >= 0xffe0 && code <= 0xffe6) ||
15
+ (code >= 0x20000 && code <= 0x2fffd) ||
16
+ (code >= 0x30000 && code <= 0x3fffd) ||
17
+ (code >= 0x1f300 && code <= 0x1f9ff)
18
+ );
19
+ }
20
+
21
+ function cellWidth(ch) {
22
+ return isWide(ch) ? 2 : 1;
23
+ }
24
+
25
+ function createCell(char = " ", attr = DEFAULT_ATTR, wideContinuation = false) {
26
+ return { char, attr: { ...attr }, wideContinuation };
27
+ }
28
+
29
+ function createVirtualTerminal(cols = 80, rows = 24) {
30
+ let buffer = [];
31
+ let cursorRow = 0;
32
+ let cursorCol = 0;
33
+ let savedCursor = { row: 0, col: 0 };
34
+ let currentAttr = { ...DEFAULT_ATTR };
35
+ let scrollTop = 0;
36
+ let scrollBottom = rows - 1;
37
+ let dirty = true;
38
+
39
+ function initBuffer() {
40
+ buffer = [];
41
+ for (let r = 0; r < rows; r++) {
42
+ buffer.push(createRow(cols));
43
+ }
44
+ }
45
+
46
+ function createRow(width) {
47
+ const row = [];
48
+ for (let c = 0; c < width; c++) {
49
+ row.push(createCell());
50
+ }
51
+ return row;
52
+ }
53
+
54
+ function clamp() {
55
+ if (cursorRow < 0) cursorRow = 0;
56
+ if (cursorRow >= rows) cursorRow = rows - 1;
57
+ if (cursorCol < 0) cursorCol = 0;
58
+ if (cursorCol >= cols) cursorCol = cols - 1;
59
+ }
60
+
61
+ function scrollUp(top = scrollTop, bottom = scrollBottom) {
62
+ buffer.splice(top, 1);
63
+ buffer.splice(bottom, 0, createRow(cols));
64
+ dirty = true;
65
+ }
66
+
67
+ function scrollDown(top = scrollTop, bottom = scrollBottom) {
68
+ buffer.splice(bottom, 1);
69
+ buffer.splice(top, 0, createRow(cols));
70
+ dirty = true;
71
+ }
72
+
73
+ function clearWideAt(row, col) {
74
+ const line = buffer[row];
75
+ if (!line || col < 0 || col >= cols) return;
76
+ if (line[col]?.wideContinuation && col > 0) {
77
+ line[col - 1] = createCell();
78
+ line[col] = createCell();
79
+ } else if (isWide(line[col]?.char) && col + 1 < cols && line[col + 1]?.wideContinuation) {
80
+ line[col] = createCell();
81
+ line[col + 1] = createCell();
82
+ }
83
+ }
84
+
85
+ function putChar(ch) {
86
+ const width = cellWidth(ch);
87
+ if (cursorCol >= cols || (width === 2 && cursorCol >= cols - 1)) {
88
+ cursorCol = 0;
89
+ cursorRow++;
90
+ if (cursorRow > scrollBottom) {
91
+ cursorRow = scrollBottom;
92
+ scrollUp();
93
+ }
94
+ }
95
+ if (buffer[cursorRow]) {
96
+ clearWideAt(cursorRow, cursorCol);
97
+ if (width === 2) clearWideAt(cursorRow, cursorCol + 1);
98
+ buffer[cursorRow][cursorCol] = createCell(ch, currentAttr);
99
+ if (width === 2 && cursorCol + 1 < cols) {
100
+ buffer[cursorRow][cursorCol + 1] = createCell("", currentAttr, true);
101
+ }
102
+ }
103
+ cursorCol += width;
104
+ dirty = true;
105
+ }
106
+
107
+ function eraseLine(mode, row) {
108
+ if (!buffer[row]) return;
109
+ if (mode === 0) {
110
+ for (let c = cursorCol; c < cols; c++) buffer[row][c] = createCell();
111
+ } else if (mode === 1) {
112
+ for (let c = 0; c <= cursorCol; c++) buffer[row][c] = createCell();
113
+ } else {
114
+ for (let c = 0; c < cols; c++) buffer[row][c] = createCell();
115
+ }
116
+ dirty = true;
117
+ }
118
+
119
+ function eraseDisplay(mode) {
120
+ if (mode === 0) {
121
+ eraseLine(0, cursorRow);
122
+ for (let r = cursorRow + 1; r < rows; r++) buffer[r] = createRow(cols);
123
+ } else if (mode === 1) {
124
+ for (let r = 0; r < cursorRow; r++) buffer[r] = createRow(cols);
125
+ eraseLine(1, cursorRow);
126
+ } else {
127
+ for (let r = 0; r < rows; r++) buffer[r] = createRow(cols);
128
+ cursorRow = 0;
129
+ cursorCol = 0;
130
+ }
131
+ dirty = true;
132
+ }
133
+
134
+ function applySGR(params) {
135
+ for (let i = 0; i < params.length; i++) {
136
+ const p = params[i];
137
+ if (p === 0) { Object.assign(currentAttr, DEFAULT_ATTR); }
138
+ else if (p === 1) { currentAttr.bold = true; }
139
+ else if (p === 2) { currentAttr.dim = true; }
140
+ else if (p === 3) { currentAttr.italic = true; }
141
+ else if (p === 4) { currentAttr.underline = true; }
142
+ else if (p === 7) { currentAttr.inverse = true; }
143
+ else if (p === 22) { currentAttr.bold = false; currentAttr.dim = false; }
144
+ else if (p === 23) { currentAttr.italic = false; }
145
+ else if (p === 24) { currentAttr.underline = false; }
146
+ else if (p === 27) { currentAttr.inverse = false; }
147
+ else if (p >= 30 && p <= 37) { currentAttr.fg = p - 30; currentAttr.fgRgb = null; }
148
+ else if (p === 38) {
149
+ if (params[i + 1] === 5) { currentAttr.fg = params[i + 2] || 0; currentAttr.fgRgb = null; i += 2; }
150
+ else if (params[i + 1] === 2) { currentAttr.fgRgb = [params[i + 2] || 0, params[i + 3] || 0, params[i + 4] || 0]; i += 4; }
151
+ }
152
+ else if (p === 39) { currentAttr.fg = 7; currentAttr.fgRgb = null; }
153
+ else if (p >= 40 && p <= 47) { currentAttr.bg = p - 40; currentAttr.bgRgb = null; }
154
+ else if (p === 48) {
155
+ if (params[i + 1] === 5) { currentAttr.bg = params[i + 2] || 0; currentAttr.bgRgb = null; i += 2; }
156
+ else if (params[i + 1] === 2) { currentAttr.bgRgb = [params[i + 2] || 0, params[i + 3] || 0, params[i + 4] || 0]; i += 4; }
157
+ }
158
+ else if (p === 49) { currentAttr.bg = 0; currentAttr.bgRgb = null; }
159
+ else if (p >= 90 && p <= 97) { currentAttr.fg = p - 90 + 8; currentAttr.fgRgb = null; }
160
+ else if (p >= 100 && p <= 107) { currentAttr.bg = p - 100 + 8; currentAttr.bgRgb = null; }
161
+ }
162
+ dirty = true;
163
+ }
164
+
165
+ function handleCSI(params, code) {
166
+ const p = params.length > 0 ? params : [0];
167
+ switch (code) {
168
+ case "A": cursorRow -= (p[0] || 1); break;
169
+ case "B": cursorRow += (p[0] || 1); break;
170
+ case "C": cursorCol += (p[0] || 1); break;
171
+ case "D": cursorCol -= (p[0] || 1); break;
172
+ case "E": cursorRow += (p[0] || 1); cursorCol = 0; break;
173
+ case "F": cursorRow -= (p[0] || 1); cursorCol = 0; break;
174
+ case "G": cursorCol = (p[0] || 1) - 1; break;
175
+ case "H": case "f":
176
+ cursorRow = (p[0] || 1) - 1;
177
+ cursorCol = (p.length > 1 ? (p[1] || 1) : 1) - 1;
178
+ break;
179
+ case "J": eraseDisplay(p[0] || 0); break;
180
+ case "K": eraseLine(p[0] || 0, cursorRow); break;
181
+ case "L": {
182
+ const n = p[0] || 1;
183
+ for (let i = 0; i < n; i++) scrollDown(cursorRow, scrollBottom);
184
+ break;
185
+ }
186
+ case "M": {
187
+ const n = p[0] || 1;
188
+ for (let i = 0; i < n; i++) scrollUp(cursorRow, scrollBottom);
189
+ break;
190
+ }
191
+ case "S": { const n = p[0] || 1; for (let i = 0; i < n; i++) scrollUp(); break; }
192
+ case "T": { const n = p[0] || 1; for (let i = 0; i < n; i++) scrollDown(); break; }
193
+ case "d": cursorRow = (p[0] || 1) - 1; break;
194
+ case "m": applySGR(p); break;
195
+ case "r":
196
+ scrollTop = (p[0] || 1) - 1;
197
+ scrollBottom = (p.length > 1 ? (p[1] || rows) : rows) - 1;
198
+ cursorRow = 0; cursorCol = 0;
199
+ break;
200
+ case "s": savedCursor = { row: cursorRow, col: cursorCol }; break;
201
+ case "u": cursorRow = savedCursor.row; cursorCol = savedCursor.col; break;
202
+ }
203
+ clamp();
204
+ dirty = true;
205
+ }
206
+ function write(data) {
207
+ const str = typeof data === "string" ? data : data.toString("utf8");
208
+ let i = 0;
209
+ while (i < str.length) {
210
+ const ch = str[i];
211
+ if (ch === "\x1b") {
212
+ if (str[i + 1] === "[") {
213
+ i += 2;
214
+ let paramStr = "";
215
+ while (i < str.length && str[i] >= "\x20" && str[i] <= "\x3f") {
216
+ paramStr += str[i++];
217
+ }
218
+ const code = str[i++] || "";
219
+ const params = paramStr ? paramStr.split(";").map(Number) : [];
220
+ handleCSI(params, code);
221
+ } else if (str[i + 1] === "7") {
222
+ savedCursor = { row: cursorRow, col: cursorCol };
223
+ i += 2;
224
+ } else if (str[i + 1] === "8") {
225
+ cursorRow = savedCursor.row;
226
+ cursorCol = savedCursor.col;
227
+ i += 2;
228
+ } else if (str[i + 1] === "M") {
229
+ scrollUp();
230
+ i += 2;
231
+ } else if (str[i + 1] === "D") {
232
+ cursorRow++;
233
+ if (cursorRow > scrollBottom) {
234
+ cursorRow = scrollBottom;
235
+ scrollUp();
236
+ }
237
+ i += 2;
238
+ } else if (str[i + 1] === "]" || str[i + 1] === "P" || str[i + 1] === "_") {
239
+ i += 2;
240
+ while (i < str.length) {
241
+ if (str[i] === "\x07") { i++; break; }
242
+ if (str[i] === "\x1b" && str[i + 1] === "\\") { i += 2; break; }
243
+ i++;
244
+ }
245
+ } else {
246
+ i += 2;
247
+ }
248
+ } else if (ch === "\r") {
249
+ cursorCol = 0;
250
+ i++;
251
+ } else if (ch === "\n") {
252
+ cursorRow++;
253
+ if (cursorRow > scrollBottom) {
254
+ cursorRow = scrollBottom;
255
+ scrollUp();
256
+ }
257
+ i++;
258
+ } else if (ch === "\b") {
259
+ if (cursorCol > 0) cursorCol--;
260
+ i++;
261
+ } else if (ch === "\t") {
262
+ cursorCol = Math.min(cols - 1, (Math.floor(cursorCol / 8) + 1) * 8);
263
+ i++;
264
+ } else if (ch.charCodeAt(0) < 32) {
265
+ i++;
266
+ } else {
267
+ const glyph = Array.from(str.slice(i))[0] || ch;
268
+ putChar(glyph);
269
+ i += glyph.length;
270
+ }
271
+ }
272
+ }
273
+
274
+ function getScreen() {
275
+ return { buffer, rows, cols, cursorRow, cursorCol };
276
+ }
277
+
278
+ function getLine(row) {
279
+ if (row < 0 || row >= rows) return "";
280
+ return buffer[row].map((c) => c.char).join("");
281
+ }
282
+
283
+ function getCursor() {
284
+ return { row: cursorRow, col: cursorCol };
285
+ }
286
+
287
+ function isDirty() {
288
+ return dirty;
289
+ }
290
+
291
+ function clearDirty() {
292
+ dirty = false;
293
+ }
294
+
295
+ function resize(newCols, newRows) {
296
+ const oldBuffer = buffer;
297
+ const oldRows = rows;
298
+ cols = newCols;
299
+ rows = newRows;
300
+ scrollTop = 0;
301
+ scrollBottom = rows - 1;
302
+ initBuffer();
303
+ const copyRows = Math.min(oldRows, rows);
304
+ for (let r = 0; r < copyRows; r++) {
305
+ const copyLen = Math.min(oldBuffer[r].length, cols);
306
+ for (let c = 0; c < copyLen; c++) {
307
+ buffer[r][c] = oldBuffer[r][c];
308
+ }
309
+ }
310
+ clamp();
311
+ dirty = true;
312
+ }
313
+
314
+ initBuffer();
315
+
316
+ return {
317
+ write,
318
+ getScreen,
319
+ getLine,
320
+ getCursor,
321
+ isDirty,
322
+ clearDirty,
323
+ resize,
324
+ };
325
+ }
326
+
327
+ module.exports = { createVirtualTerminal, DEFAULT_ATTR };
@@ -2,7 +2,7 @@ const net = require("net");
2
2
  const path = require("path");
3
3
  const fs = require("fs");
4
4
  const { spawn, spawnSync } = require("child_process");
5
- const { resolveNodeExecutable } = require("../utils/nodeExecutable");
5
+ const { resolveNodeExecutable } = require("../../runtime/process/nodeExecutable");
6
6
 
7
7
  function connectSocket(sockPath, options = {}) {
8
8
  const timeoutMs = Number.isFinite(options.timeoutMs) && options.timeoutMs > 0
@@ -15,9 +15,9 @@ async function runCtxCommand(subcmd = "doctor", subargs = [], options = {}) {
15
15
  updateDecisionIndexPaths = true,
16
16
  } = options;
17
17
 
18
- const DecisionsManager = require("../context/decisions");
19
- const ContextDoctor = require("../context/doctor");
20
- const SyncManager = require("../context/sync");
18
+ const DecisionsManager = require("../../coordination/context/decisions");
19
+ const ContextDoctor = require("../../coordination/context/doctor");
20
+ const SyncManager = require("../../coordination/context/sync");
21
21
 
22
22
  switch (subcmd) {
23
23
  case "doctor": {
@@ -1,6 +1,6 @@
1
1
  const fs = require("fs");
2
2
  const path = require("path");
3
- const ContextDoctor = require("../context/doctor");
3
+ const ContextDoctor = require("../../../coordination/context/doctor");
4
4
 
5
5
  class RepoDoctor {
6
6
  constructor(repoRoot) {
@@ -27,7 +27,6 @@ class UfooInit {
27
27
  console.log();
28
28
 
29
29
  if (!controllerMode) {
30
- // 确保 AGENTS.md 和 CLAUDE.md 存在
31
30
  this.ensureAgentsFiles(project);
32
31
  }
33
32
 
@@ -35,7 +34,6 @@ class UfooInit {
35
34
  this.initCore(project, { controllerMode });
36
35
 
37
36
  if (!controllerMode) {
38
- // 初始化 AGENTS.md 模板
39
37
  this.injectAgentsTemplate(project);
40
38
  }
41
39
 
@@ -67,7 +65,6 @@ class UfooInit {
67
65
  const agentsFile = path.join(project, "AGENTS.md");
68
66
  const claudeFile = path.join(project, "CLAUDE.md");
69
67
 
70
- // 创建 AGENTS.md(如果不存在)
71
68
  if (!fs.existsSync(agentsFile)) {
72
69
  const content = `# Project Instructions
73
70
 
@@ -77,7 +74,6 @@ class UfooInit {
77
74
  fs.writeFileSync(agentsFile, content, "utf8");
78
75
  }
79
76
 
80
- // 仅在不存在时创建 CLAUDE.md;存在时保留用户文件类型(普通文件或 symlink)
81
77
  const claudeStat = this.safeLstat(claudeFile);
82
78
  if (!claudeStat) {
83
79
  fs.writeFileSync(claudeFile, "AGENTS.md\n", "utf8");
@@ -116,8 +112,16 @@ class UfooInit {
116
112
  console.log("[core] Done");
117
113
  }
118
114
 
115
+ safeLstat(filePath) {
116
+ try {
117
+ return fs.lstatSync(filePath);
118
+ } catch {
119
+ return null;
120
+ }
121
+ }
122
+
119
123
  /**
120
- * 注入 ufoo 模板到 AGENTS.md
124
+ * 注入 ufoo 模板到 AGENTS.md / CLAUDE.md
121
125
  */
122
126
  injectAgentsTemplate(project) {
123
127
  if (!fs.existsSync(this.agentsTemplate)) {
@@ -142,14 +146,6 @@ class UfooInit {
142
146
  console.log("[template] Done");
143
147
  }
144
148
 
145
- safeLstat(filePath) {
146
- try {
147
- return fs.lstatSync(filePath);
148
- } catch {
149
- return null;
150
- }
151
- }
152
-
153
149
  resolveTemplateTargets(project) {
154
150
  const agentsFile = path.resolve(path.join(project, "AGENTS.md"));
155
151
  const claudeFile = path.resolve(path.join(project, "CLAUDE.md"));
@@ -167,9 +163,7 @@ class UfooInit {
167
163
  const rawTarget = fs.readlinkSync(claudeFile);
168
164
  const sourceFile = path.resolve(path.dirname(claudeFile), rawTarget);
169
165
  const projectRoot = path.resolve(project);
170
- const inProject =
171
- sourceFile === projectRoot ||
172
- sourceFile.startsWith(`${projectRoot}${path.sep}`);
166
+ const inProject = sourceFile === projectRoot || sourceFile.startsWith(`${projectRoot}${path.sep}`);
173
167
  if (inProject) {
174
168
  targets.add(sourceFile);
175
169
  } else {
@@ -181,7 +175,6 @@ class UfooInit {
181
175
  return Array.from(targets);
182
176
  }
183
177
 
184
- // CLAUDE.md 为独立文件时,双文件都注入模板
185
178
  targets.add(claudeFile);
186
179
  return Array.from(targets);
187
180
  }
@@ -194,26 +187,17 @@ class UfooInit {
194
187
  const block = `${marker}\n${template}\n${marker}`;
195
188
 
196
189
  if (content.includes(marker)) {
197
- // Replace existing marker block in-place
198
190
  const startIdx = content.indexOf(marker);
199
191
  const endIdx = content.indexOf(marker, startIdx + marker.length);
200
192
  if (endIdx !== -1) {
201
- content =
202
- content.slice(0, startIdx) +
203
- block +
204
- content.slice(endIdx + marker.length);
193
+ content = content.slice(0, startIdx) + block + content.slice(endIdx + marker.length);
205
194
  } else {
206
- content =
207
- content.slice(0, startIdx) + block + content.slice(startIdx + marker.length);
195
+ content = content.slice(0, startIdx) + block + content.slice(startIdx + marker.length);
208
196
  }
209
197
  } else {
210
- // Insert after first heading line for visibility (not buried at end)
211
198
  const headingEnd = this.findFirstHeadingEnd(content);
212
199
  if (headingEnd !== -1) {
213
- content =
214
- content.slice(0, headingEnd) +
215
- `\n${block}\n\n` +
216
- content.slice(headingEnd);
200
+ content = content.slice(0, headingEnd) + `\n${block}\n\n` + content.slice(headingEnd);
217
201
  } else {
218
202
  content = `${block}\n\n${content}`;
219
203
  }
@@ -222,9 +206,7 @@ class UfooInit {
222
206
  }
223
207
 
224
208
  findFirstHeadingEnd(content) {
225
- // ATX heading: # ... (allow leading indentation and EOF without trailing newline)
226
209
  const atxHeading = content.match(/^(?:[ \t]{0,3})#{1,6}[ \t]*[^\n]*(?:\n|$)/m);
227
- // Setext heading: text line + underline (=== or ---)
228
210
  const setextHeading = content.match(/^[^\n]+\n(?:=+|-+)[ \t]*(?:\n|$)/m);
229
211
 
230
212
  let bestMatch = null;
@@ -270,7 +252,7 @@ class UfooInit {
270
252
  async initBus(project) {
271
253
  console.log("[bus] Initializing bus module...");
272
254
 
273
- const EventBus = require("../bus");
255
+ const EventBus = require("../../../coordination/bus");
274
256
  const bus = new EventBus(project);
275
257
 
276
258
  try {
@@ -5,8 +5,8 @@ const {
5
5
  loadTemplateRegistry,
6
6
  resolveTemplateReference,
7
7
  createTemplateFromBuiltin,
8
- } = require("../group/templates");
9
- const { validateTemplateTarget } = require("../group/templateValidation");
8
+ } = require("../../orchestration/groups/templates");
9
+ const { validateTemplateTarget } = require("../../orchestration/groups/templateValidation");
10
10
 
11
11
  function parseTemplateNewArgs(args = []) {
12
12
  const alias = String(args[0] || "").trim();
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+
3
+ module.exports = {
4
+ ...require("./run"),
5
+ ...require("./busCoreCommands"),
6
+ ...require("./ctxCoreCommands"),
7
+ ...require("./groupCoreCommands"),
8
+ ...require("./onlineCoreCommands"),
9
+ };
@@ -24,7 +24,7 @@ function buildAuthHeaders(onlineAuthHeaders, opts) {
24
24
  }
25
25
 
26
26
  async function runOnlineServer(opts = {}) {
27
- const OnlineServer = require("../online/server");
27
+ const OnlineServer = require("../../online/server");
28
28
  const host = opts.host || "127.0.0.1";
29
29
  const port = Number.isFinite(opts.port) ? opts.port : parseInt(opts.port || "8787", 10);
30
30
  const idleTimeoutMs = Number.isFinite(opts.idleTimeoutMs)
@@ -62,7 +62,7 @@ async function runOnlineToken(subscriber, opts = {}) {
62
62
  if (!subscriber) {
63
63
  throw new Error("online token requires <subscriber>");
64
64
  }
65
- const { generateToken, setToken, defaultTokensPath } = require("../online/tokens");
65
+ const { generateToken, setToken, defaultTokensPath } = require("../../online/tokens");
66
66
  const filePath = opts.file || defaultTokensPath();
67
67
  const token = generateToken();
68
68
  const entry = setToken(filePath, subscriber, token, opts.server || "https://online.ufoo.dev", {
@@ -159,7 +159,7 @@ async function runOnlineConnect(opts = {}) {
159
159
  if (!opts.nickname) {
160
160
  throw new Error("online connect requires --nickname");
161
161
  }
162
- const OnlineConnect = require("../online/bridge");
162
+ const OnlineConnect = require("../../online/bridge");
163
163
  const conn = new OnlineConnect({
164
164
  projectRoot: opts.projectRoot || process.cwd(),
165
165
  nickname: opts.nickname,
@@ -182,7 +182,7 @@ async function runOnlineConnect(opts = {}) {
182
182
  }
183
183
 
184
184
  function runOnlineSend(opts = {}) {
185
- const { send } = require("../online/runner");
185
+ const { send } = require("../../online/runner");
186
186
  if (!opts.nickname || !opts.text) {
187
187
  throw new Error("online send requires --nickname and --text");
188
188
  }
@@ -194,7 +194,7 @@ function runOnlineSend(opts = {}) {
194
194
  }
195
195
 
196
196
  function runOnlineInbox(nickname, opts = {}) {
197
- const { checkInbox } = require("../online/runner");
197
+ const { checkInbox } = require("../../online/runner");
198
198
  if (!nickname || nickname.startsWith("--")) {
199
199
  throw new Error("online inbox requires <nickname>");
200
200
  }