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.
- package/README.md +157 -213
- package/README.zh-CN.md +151 -197
- package/SKILLS/ufoo/SKILL.md +8 -8
- package/bin/uagy.js +69 -0
- package/bin/uclaude.js +2 -2
- package/bin/ucode.js +4 -4
- package/bin/ucodex.js +2 -2
- package/bin/ufoo.js +5 -23
- package/modules/AGENTS.template.md +1 -1
- package/modules/bus/SKILLS/ubus/SKILL.md +35 -10
- package/package.json +5 -5
- package/scripts/chat-app-smoke.js +1 -1
- package/scripts/global-chat-switch-benchmark.js +5 -5
- package/scripts/ink-demo.js +1 -1
- package/scripts/ink-smoke.js +1 -1
- package/scripts/ucode-app-smoke.js +1 -1
- package/src/{agent → agents/activity}/activityDetector.js +39 -2
- package/src/{agent → agents/activity}/activityStatePublisher.js +1 -1
- package/src/{agent → agents/activity}/activityStateWriter.js +2 -2
- package/src/{agent → agents/activity}/activityTracker.js +1 -1
- package/src/agents/activity/index.js +8 -0
- package/src/{agent → agents/controller}/controllerToolExecutor.js +4 -4
- package/src/agents/controller/index.js +8 -0
- package/src/{agent → agents/controller}/loopObservability.js +2 -2
- package/src/{agent → agents/controller}/loopRuntime.js +1 -1
- package/src/{agent → agents/controller}/ufooAgent.js +9 -9
- package/src/agents/index.js +10 -0
- package/src/agents/internal/index.js +3 -0
- package/src/{agent → agents/internal}/internalRunner.js +45 -22
- package/src/agents/launch/agyConversation.js +159 -0
- package/src/agents/launch/index.js +12 -0
- package/src/{agent → agents/launch}/launchEnvironment.js +2 -3
- package/src/{agent → agents/launch}/launcher.js +64 -21
- package/src/{agent → agents/launch}/notifier.js +23 -12
- package/src/{agent → agents/launch}/ptyRunner.js +44 -12
- package/src/{agent → agents/launch}/ptyWrapper.js +2 -2
- package/src/{agent → agents/launch}/publisherRouting.js +1 -1
- package/src/{agent → agents/launch}/readyDetector.js +23 -0
- package/src/{agent → agents/prompts}/defaultBootstrap.js +63 -4
- package/src/{group/bootstrap.js → agents/prompts/groupBootstrap.js} +41 -6
- package/src/agents/prompts/index.js +8 -0
- package/src/{code/prompts → agents/prompts/native}/index.js +1 -1
- package/src/{agent → agents/providers}/claudeThreadProvider.js +1 -1
- package/src/{agent → agents/providers}/codexThreadProvider.js +1 -1
- package/src/{agent → agents/providers}/directAuthStatus.js +184 -1
- package/src/agents/providers/index.js +13 -0
- package/src/{agent → agents/providers}/upstreamTransport.js +2 -2
- package/src/{chat → app/chat}/agentSockets.js +1 -1
- package/src/{chat → app/chat}/commandExecutor.js +50 -26
- package/src/{chat → app/chat}/commands.js +119 -5
- package/src/{chat → app/chat}/daemonConnection.js +1 -1
- package/src/{chat → app/chat}/daemonMessageRouter.js +45 -3
- package/src/{chat → app/chat}/dashboardView.js +2 -1
- package/src/app/chat/index.js +6 -0
- package/src/{chat → app/chat}/inputSubmitHandler.js +4 -13
- package/src/{chat → app/chat}/internalAgentLogHistory.js +1 -1
- package/src/app/chat/multiWindow/index.js +268 -0
- package/src/app/chat/multiWindow/paneLayout.js +84 -0
- package/src/app/chat/multiWindow/paneManager.js +299 -0
- package/src/app/chat/multiWindow/renderer.js +384 -0
- package/src/app/chat/multiWindow/virtualTerminal.js +327 -0
- package/src/{chat → app/chat}/transport.js +1 -1
- package/src/{cli → app/cli}/ctxCoreCommands.js +3 -3
- package/src/{doctor/index.js → app/cli/features/doctor.js} +1 -1
- package/src/{init/index.js → app/cli/features/init.js} +14 -32
- package/src/{cli → app/cli}/groupCoreCommands.js +2 -2
- package/src/app/cli/index.js +9 -0
- package/src/{cli → app/cli}/onlineCoreCommands.js +5 -5
- package/src/{cli.js → app/cli/run.js} +59 -57
- package/src/app/index.js +6 -0
- package/src/code/agent.js +10 -9
- package/src/code/index.js +2 -0
- package/src/code/launcher/index.js +9 -0
- package/src/{agent → code/launcher}/ucode.js +7 -8
- package/src/{agent → code/launcher}/ucodeBootstrap.js +3 -3
- package/src/{agent → code/launcher}/ucodeBuild.js +2 -2
- package/src/{agent → code/launcher}/ucodeDoctor.js +2 -2
- package/src/{agent → code/launcher}/ucodeRuntimeConfig.js +1 -2
- package/src/code/nativeRunner.js +4 -4
- package/src/code/tui.js +3 -1454
- package/src/config.js +15 -2
- package/src/{bus → coordination/bus}/activate.js +2 -2
- package/src/{bus → coordination/bus}/daemon.js +15 -5
- package/src/coordination/bus/envelope.js +173 -0
- package/src/{bus → coordination/bus}/index.js +7 -3
- package/src/{bus → coordination/bus}/inject.js +11 -3
- package/src/{bus → coordination/bus}/message.js +1 -1
- package/src/coordination/bus/messageMeta.js +130 -0
- package/src/coordination/bus/promptEnvelope.js +65 -0
- package/src/{bus → coordination/bus}/shake.js +1 -1
- package/src/{bus → coordination/bus}/store.js +3 -3
- package/src/{bus → coordination/bus}/subscriber.js +2 -2
- package/src/{bus → coordination/bus}/utils.js +2 -2
- package/src/{history → coordination/history}/inputTimeline.js +5 -5
- package/src/coordination/index.js +10 -0
- package/src/{memory → coordination/memory}/historySearch.js +1 -1
- package/src/{memory → coordination/memory}/index.js +3 -3
- package/src/{report → coordination/report}/store.js +2 -2
- package/src/{status → coordination/status}/index.js +3 -3
- package/src/online/bridge.js +2 -2
- package/src/{controller → orchestration/controller}/flags.js +1 -1
- package/src/{controller → orchestration/controller}/gateRouter.js +1 -1
- package/src/orchestration/controller/index.js +10 -0
- package/src/{controller → orchestration/controller}/shadowGuard.js +1 -1
- package/src/orchestration/groups/bootstrap.js +3 -0
- package/src/orchestration/groups/index.js +10 -0
- package/src/orchestration/groups/promptProfiles.js +3 -0
- package/src/{group → orchestration/groups}/templates.js +1 -1
- package/src/{group → orchestration/groups}/validateTemplate.js +1 -1
- package/src/orchestration/index.js +7 -0
- package/src/orchestration/solo/index.js +3 -0
- package/src/{daemon → runtime/daemon}/agentProcessManager.js +1 -1
- package/src/{daemon → runtime/daemon}/cronOps.js +3 -2
- package/src/{daemon → runtime/daemon}/groupOrchestrator.js +26 -9
- package/src/{daemon → runtime/daemon}/index.js +105 -53
- package/src/{daemon → runtime/daemon}/ipcServer.js +1 -1
- package/src/{daemon → runtime/daemon}/nicknameScope.js +6 -3
- package/src/{daemon → runtime/daemon}/ops.js +48 -61
- package/src/{daemon → runtime/daemon}/promptLoop.js +1 -1
- package/src/{daemon → runtime/daemon}/promptRequest.js +7 -7
- package/src/runtime/daemon/providerSessions.js +230 -0
- package/src/{daemon → runtime/daemon}/reporting.js +4 -4
- package/src/{daemon → runtime/daemon}/run.js +4 -4
- package/src/{daemon → runtime/daemon}/soloBootstrap.js +7 -7
- package/src/{daemon → runtime/daemon}/status.js +5 -5
- package/src/runtime/index.js +10 -0
- package/src/{projects → runtime/projects}/registry.js +1 -1
- package/src/{terminal → runtime/terminal}/adapterRouter.js +0 -10
- package/src/{terminal → runtime/terminal}/adapters/internalAdapter.js +0 -4
- package/src/tools/handlers/common.js +1 -1
- package/src/tools/handlers/listAgents.js +1 -1
- package/src/tools/handlers/memory.js +3 -3
- package/src/tools/handlers/readBusSummary.js +1 -1
- package/src/tools/handlers/readOpenDecisions.js +1 -1
- package/src/tools/handlers/readProjectRegistry.js +1 -1
- package/src/tools/handlers/readPromptHistory.js +2 -2
- package/src/tools/schemaFixtures.js +1 -1
- package/src/ui/MIGRATION.md +42 -88
- package/src/ui/format/index.js +5 -28
- package/src/ui/index.js +1 -1
- package/src/ui/{components → ink}/ChatApp.js +812 -88
- package/src/ui/ink/DashboardBar.js +685 -0
- package/src/ui/{components → ink}/MultilineInput.js +230 -5
- package/src/ui/{components → ink}/UcodeApp.js +16 -7
- package/src/ui/{components → ink}/agentMirror.js +24 -19
- package/src/ui/{components → ink}/chatReducer.js +29 -7
- package/src/bus/messageMeta.js +0 -52
- package/src/chat/agentViewController.js +0 -1072
- package/src/chat/chatLogController.js +0 -138
- package/src/chat/completionController.js +0 -533
- package/src/chat/dashboardKeyController.js +0 -533
- package/src/chat/index.js +0 -2222
- package/src/chat/inputHistoryController.js +0 -135
- package/src/chat/inputListenerController.js +0 -470
- package/src/chat/layout.js +0 -186
- package/src/chat/pasteController.js +0 -81
- package/src/chat/statusLineController.js +0 -223
- package/src/chat/streamTracker.js +0 -156
- package/src/code/config +0 -0
- package/src/daemon/providerSessions.js +0 -488
- package/src/terminal/adapters/internalPtyAdapter.js +0 -42
- package/src/ui/components/DashboardBar.js +0 -417
- /package/src/{code/prompts → agents/prompts/native}/actions.js +0 -0
- /package/src/{code/prompts → agents/prompts/native}/efficiency.js +0 -0
- /package/src/{code/prompts → agents/prompts/native}/environment.js +0 -0
- /package/src/{code/prompts → agents/prompts/native}/identity.js +0 -0
- /package/src/{code/prompts → agents/prompts/native}/safety.js +0 -0
- /package/src/{code/prompts → agents/prompts/native}/sections.js +0 -0
- /package/src/{code/prompts → agents/prompts/native}/system.js +0 -0
- /package/src/{code/prompts → agents/prompts/native}/tasks.js +0 -0
- /package/src/{code/prompts → agents/prompts/native}/toolDescriptions/bash.js +0 -0
- /package/src/{code/prompts → agents/prompts/native}/toolDescriptions/edit.js +0 -0
- /package/src/{code/prompts → agents/prompts/native}/toolDescriptions/read.js +0 -0
- /package/src/{code/prompts → agents/prompts/native}/toolDescriptions/write.js +0 -0
- /package/src/{code/prompts → agents/prompts/native}/ufoo.js +0 -0
- /package/src/{group → agents/prompts}/promptProfiles.js +0 -0
- /package/src/{agent → agents/providers}/claudeEventTranslator.js +0 -0
- /package/src/{agent → agents/providers}/claudeOauthTokenReader.js +0 -0
- /package/src/{agent → agents/providers}/claudeSessionFiles.js +0 -0
- /package/src/{agent → agents/providers}/codexEventTranslator.js +0 -0
- /package/src/{agent → agents/providers}/credentials/claude.js +0 -0
- /package/src/{agent → agents/providers}/credentials/codex.js +0 -0
- /package/src/{agent → agents/providers}/credentials/index.js +0 -0
- /package/src/{chat → app/chat}/agentBar.js +0 -0
- /package/src/{chat → app/chat}/agentDirectory.js +0 -0
- /package/src/{chat → app/chat}/cronScheduler.js +0 -0
- /package/src/{chat → app/chat}/daemonCoordinator.js +0 -0
- /package/src/{chat → app/chat}/daemonReconnect.js +0 -0
- /package/src/{chat → app/chat}/daemonTransport.js +0 -0
- /package/src/{chat → app/chat}/daemonTransportDefaults.js +0 -0
- /package/src/{chat → app/chat}/inputMath.js +0 -0
- /package/src/{chat → app/chat}/projectCloseController.js +0 -0
- /package/src/{chat → app/chat}/rawKeyMap.js +0 -0
- /package/src/{chat → app/chat}/settingsController.js +0 -0
- /package/src/{chat → app/chat}/shellCommand.js +0 -0
- /package/src/{chat → app/chat}/text.js +0 -0
- /package/src/{chat → app/chat}/transientAgentState.js +0 -0
- /package/src/{cli → app/cli}/busCoreCommands.js +0 -0
- /package/src/{skills/index.js → app/cli/features/skills.js} +0 -0
- /package/src/{bus → coordination/bus}/nickname.js +0 -0
- /package/src/{bus → coordination/bus}/queue.js +0 -0
- /package/src/{context → coordination/context}/decisions.js +0 -0
- /package/src/{context → coordination/context}/doctor.js +0 -0
- /package/src/{context → coordination/context}/index.js +0 -0
- /package/src/{context → coordination/context}/sync.js +0 -0
- /package/src/{ufoo → coordination/state}/agentRegistryDiagnostics.js +0 -0
- /package/src/{ufoo → coordination/state}/agentsStore.js +0 -0
- /package/src/{ufoo → coordination/state}/paths.js +0 -0
- /package/src/{controller → orchestration/controller}/launchRouting.js +0 -0
- /package/src/{controller → orchestration/controller}/routerFastPath.js +0 -0
- /package/src/{controller → orchestration/controller}/routerFinalize.js +0 -0
- /package/src/{group → orchestration/groups}/diagram.js +0 -0
- /package/src/{group → orchestration/groups}/templateValidation.js +0 -0
- /package/src/{solo → orchestration/solo}/commands.js +0 -0
- /package/src/{shared → runtime/contracts}/eventContract.js +0 -0
- /package/src/{shared → runtime/contracts}/ptySocketContract.js +0 -0
- /package/src/{providerapi → runtime/privacy}/redactor.js +0 -0
- /package/src/{providerapi → runtime/privacy}/shadowDiff.js +0 -0
- /package/src/{utils → runtime/process}/nodeExecutable.js +0 -0
- /package/src/{projects → runtime/projects}/identity.js +0 -0
- /package/src/{projects → runtime/projects}/index.js +0 -0
- /package/src/{projects → runtime/projects}/projectId.js +0 -0
- /package/src/{projects → runtime/projects}/runtimes.js +0 -0
- /package/src/{terminal → runtime/terminal}/adapterContract.js +0 -0
- /package/src/{terminal → runtime/terminal}/adapters/externalAdapter.js +0 -0
- /package/src/{terminal → runtime/terminal}/adapters/hostAdapter.js +0 -0
- /package/src/{terminal → runtime/terminal}/adapters/internalQueueAdapter.js +0 -0
- /package/src/{terminal → runtime/terminal}/adapters/terminalAdapter.js +0 -0
- /package/src/{terminal → runtime/terminal}/adapters/tmuxAdapter.js +0 -0
- /package/src/{terminal → runtime/terminal}/detect.js +0 -0
- /package/src/{terminal → runtime/terminal}/index.js +0 -0
- /package/src/{terminal → runtime/terminal}/iterm2.js +0 -0
- /package/src/{utils → ui/format}/banner.js +0 -0
- /package/src/{shared → ui/format}/markdownRenderer.js +0 -0
- /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("
|
|
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("
|
|
19
|
-
const ContextDoctor = require("
|
|
20
|
-
const SyncManager = require("
|
|
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": {
|
|
@@ -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("
|
|
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("
|
|
9
|
-
const { validateTemplateTarget } = require("
|
|
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();
|
|
@@ -24,7 +24,7 @@ function buildAuthHeaders(onlineAuthHeaders, opts) {
|
|
|
24
24
|
}
|
|
25
25
|
|
|
26
26
|
async function runOnlineServer(opts = {}) {
|
|
27
|
-
const OnlineServer = require("
|
|
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("
|
|
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("
|
|
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("
|
|
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("
|
|
197
|
+
const { checkInbox } = require("../../online/runner");
|
|
198
198
|
if (!nickname || nickname.startsWith("--")) {
|
|
199
199
|
throw new Error("online inbox requires <nickname>");
|
|
200
200
|
}
|