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
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
const fs = require("fs");
|
|
2
2
|
const path = require("path");
|
|
3
|
-
const { getUfooPaths } = require("
|
|
4
|
-
const { isMetaActive } = require("
|
|
3
|
+
const { getUfooPaths } = require("../../coordination/state/paths");
|
|
4
|
+
const { isMetaActive } = require("../../coordination/bus/utils");
|
|
5
5
|
const { resolveDisplayNickname, resolveScopedNickname } = require("./nicknameScope");
|
|
6
|
-
const { readReportSummary, countControllerInboxEntries } = require("
|
|
7
|
-
const { readRecentLoopSummary } = require("
|
|
6
|
+
const { readReportSummary, countControllerInboxEntries } = require("../../coordination/report/store");
|
|
7
|
+
const { readRecentLoopSummary } = require("../../agents/controller/loopObservability");
|
|
8
8
|
|
|
9
9
|
function readBus(projectRoot) {
|
|
10
10
|
const busPath = getUfooPaths(projectRoot).agentsFile;
|
|
@@ -16,7 +16,7 @@ function readBus(projectRoot) {
|
|
|
16
16
|
}
|
|
17
17
|
|
|
18
18
|
function readDecisions(projectRoot) {
|
|
19
|
-
const DecisionsManager = require("
|
|
19
|
+
const DecisionsManager = require("../../coordination/context/decisions");
|
|
20
20
|
const manager = new DecisionsManager(projectRoot);
|
|
21
21
|
const dir = manager.decisionsDir;
|
|
22
22
|
let open = 0;
|
|
@@ -2,7 +2,7 @@ const fs = require("fs");
|
|
|
2
2
|
const os = require("os");
|
|
3
3
|
const path = require("path");
|
|
4
4
|
const { canonicalProjectRoot, buildProjectId, trimTrailingSlashes } = require("./projectId");
|
|
5
|
-
const { getUfooPaths } = require("
|
|
5
|
+
const { getUfooPaths } = require("../../coordination/state/paths");
|
|
6
6
|
|
|
7
7
|
const DEFAULT_STALE_TTL_MS = 30 * 1000;
|
|
8
8
|
const DEFAULT_TMP_CLEANUP_AGE_MS = 5 * 60 * 1000;
|
|
@@ -5,7 +5,6 @@ const {
|
|
|
5
5
|
const { createTerminalAdapter } = require("./adapters/terminalAdapter");
|
|
6
6
|
const { createTmuxAdapter } = require("./adapters/tmuxAdapter");
|
|
7
7
|
const { createInternalQueueAdapter } = require("./adapters/internalQueueAdapter");
|
|
8
|
-
const { createInternalPtyAdapter } = require("./adapters/internalPtyAdapter");
|
|
9
8
|
const { createHostAdapter } = require("./adapters/hostAdapter");
|
|
10
9
|
|
|
11
10
|
function createTerminalAdapterRouter(options = {}) {
|
|
@@ -65,15 +64,6 @@ function createTerminalAdapterRouter(options = {}) {
|
|
|
65
64
|
});
|
|
66
65
|
}
|
|
67
66
|
|
|
68
|
-
if (launchMode === "internal-pty") {
|
|
69
|
-
return createInternalPtyAdapter({
|
|
70
|
-
sendRaw,
|
|
71
|
-
sendResize,
|
|
72
|
-
requestSnapshot,
|
|
73
|
-
createAdapter,
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
|
|
77
67
|
if (launchMode === "internal") {
|
|
78
68
|
return createInternalQueueAdapter({
|
|
79
69
|
sendRaw,
|
|
@@ -1,10 +1,6 @@
|
|
|
1
|
-
const { createInternalPtyAdapter } = require("./internalPtyAdapter");
|
|
2
1
|
const { createInternalQueueAdapter } = require("./internalQueueAdapter");
|
|
3
2
|
|
|
4
3
|
function createInternalAdapter(options = {}) {
|
|
5
|
-
if (options.usePty) {
|
|
6
|
-
return createInternalPtyAdapter(options);
|
|
7
|
-
}
|
|
8
4
|
return createInternalQueueAdapter(options);
|
|
9
5
|
}
|
|
10
6
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
const MemoryManager = require("../../memory");
|
|
2
|
-
const { estimateTokens } = require("../../memory");
|
|
3
|
-
const { searchHistory } = require("../../memory/historySearch");
|
|
1
|
+
const MemoryManager = require("../../coordination/memory");
|
|
2
|
+
const { estimateTokens } = require("../../coordination/memory");
|
|
3
|
+
const { searchHistory } = require("../../coordination/memory/historySearch");
|
|
4
4
|
const { buildToolError, extractAuditFields, requireSubscriber } = require("./common");
|
|
5
5
|
|
|
6
6
|
const BANNED_TIME_PATTERNS = [
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const DecisionsManager = require("../../context/decisions");
|
|
1
|
+
const DecisionsManager = require("../../coordination/context/decisions");
|
|
2
2
|
|
|
3
3
|
function readOpenDecisionsHandler(ctx = {}, args = {}) {
|
|
4
4
|
const limit = Number.isFinite(Number(args.limit)) && Number(args.limit) > 0
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
const fs = require("fs");
|
|
2
2
|
const path = require("path");
|
|
3
3
|
|
|
4
|
-
const { buildStatus } = require("../../daemon/status");
|
|
5
|
-
const { getUfooPaths } = require("../../
|
|
4
|
+
const { buildStatus } = require("../../runtime/daemon/status");
|
|
5
|
+
const { getUfooPaths } = require("../../coordination/state/paths");
|
|
6
6
|
|
|
7
7
|
function clipPromptText(value = "", maxChars = 240) {
|
|
8
8
|
const text = String(value || "").replace(/\s+/g, " ").trim();
|
|
@@ -456,7 +456,7 @@ const LAUNCH_AGENT_SCHEMA = Object.freeze({
|
|
|
456
456
|
properties: Object.freeze({
|
|
457
457
|
agent: Object.freeze({
|
|
458
458
|
type: "string",
|
|
459
|
-
enum: Object.freeze(["codex", "claude", "ucode"]),
|
|
459
|
+
enum: Object.freeze(["codex", "claude", "ucode", "agy"]),
|
|
460
460
|
}),
|
|
461
461
|
count: Object.freeze({ type: "integer", minimum: 1 }),
|
|
462
462
|
nickname: Object.freeze({ type: "string" }),
|
package/src/ui/MIGRATION.md
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# Ink TUI Migration Plan
|
|
2
2
|
|
|
3
|
-
Status: Ink is the
|
|
4
|
-
|
|
3
|
+
Status: Ink is the only TUI for chat and ucode. The legacy blessed renderer
|
|
4
|
+
has been removed after the parity close-out.
|
|
5
5
|
|
|
6
6
|
## Why
|
|
7
7
|
|
|
8
|
-
The legacy chat, ucode and internal-agent TUIs
|
|
9
|
-
an unmaintained imperative widget tree with no modern equivalent of
|
|
10
|
-
component model, and it
|
|
11
|
-
redraws, no useful test harness).
|
|
8
|
+
The removed legacy chat, ucode and internal-agent TUIs used blessed. Blessed
|
|
9
|
+
is an unmaintained imperative widget tree with no modern equivalent of
|
|
10
|
+
React's component model, and it was awkward to extend (manual layout math,
|
|
11
|
+
manual redraws, no useful test harness).
|
|
12
12
|
|
|
13
13
|
ink (the React-for-terminals library, what Claude Code, Codex CLI fronts
|
|
14
14
|
and the Gemini CLI all use) gives us declarative components, flexbox
|
|
@@ -16,11 +16,10 @@ layout, hooks, and proper isolation of pure logic from rendering.
|
|
|
16
16
|
|
|
17
17
|
## Approach
|
|
18
18
|
|
|
19
|
-
- Ink is the
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
- Components live in `src/ui/components/`, written in plain JS via
|
|
19
|
+
- Ink is the renderer for both chat and ucode.
|
|
20
|
+
- Pure helpers live in `src/ui/format/`, so behaviour parity is enforced by
|
|
21
|
+
test rather than copy/paste.
|
|
22
|
+
- Components live in `src/ui/ink/`, written in plain JS via
|
|
24
23
|
`React.createElement` (no JSX, no build step) so jest stays vanilla.
|
|
25
24
|
- ink is loaded through `src/ui/runInk.js`, a thin CJS→ESM bridge so the
|
|
26
25
|
rest of the codebase stays CommonJS.
|
|
@@ -61,7 +60,6 @@ layout, hooks, and proper isolation of pure logic from rendering.
|
|
|
61
60
|
|
|
62
61
|
```sh
|
|
63
62
|
./bin/ucode.js
|
|
64
|
-
# fallback: UFOO_TUI=blessed ./bin/ucode.js
|
|
65
63
|
```
|
|
66
64
|
|
|
67
65
|
### Editor
|
|
@@ -129,25 +127,18 @@ layout, hooks, and proper isolation of pure logic from rendering.
|
|
|
129
127
|
|
|
130
128
|
## P2 dropped, folded into P3
|
|
131
129
|
|
|
132
|
-
The internal-agent view in chat is not an independent program
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
flipping `screen.grabKeys`. There is no clean seam to mount an isolated
|
|
136
|
-
ink subtree inside a still-blessed chat host, so attempting P2 in
|
|
137
|
-
isolation would force us to build a stdout-arbitration layer we'd throw
|
|
138
|
-
away once chat itself is on ink. P3.6 ports the agent view as a chat
|
|
139
|
-
sub-mode instead.
|
|
130
|
+
The internal-agent view in chat is not an independent program. It is now
|
|
131
|
+
an Ink chat sub-mode, so the earlier plan to mount a separate subtree was
|
|
132
|
+
folded into P3.6.
|
|
140
133
|
|
|
141
134
|
## P3 audit (chat TUI surface)
|
|
142
135
|
|
|
143
|
-
Source: `src/
|
|
144
|
-
`src/chat/`. Highlights:
|
|
136
|
+
Source: the current Ink host in `src/ui/ink/ChatApp.js`, with
|
|
137
|
+
shared daemon and command helpers under `src/app/chat/`. Highlights:
|
|
145
138
|
|
|
146
139
|
### Lifecycle
|
|
147
140
|
- Public entrypoint `runChat(projectRoot, { globalMode })` from
|
|
148
|
-
`src/chat/index.js
|
|
149
|
-
forever; exit goes through `process.exit(0)` from a screen `destroy`
|
|
150
|
-
hook.
|
|
141
|
+
`src/app/chat/index.js`; it delegates directly to the Ink ChatApp.
|
|
151
142
|
- Runners injected via closures: `daemonCoordinator.send`,
|
|
152
143
|
`executeCommand`, `inputSubmitHandler.handleSubmit`,
|
|
153
144
|
`daemonMessageRouter.handleMessage`.
|
|
@@ -187,19 +178,10 @@ Source: `src/chat/index.js` (2215 lines) + ~30 controllers in
|
|
|
187
178
|
- `daemonReconnect.restartDaemonFlow()` provides a per-project lock for
|
|
188
179
|
daemon restarts.
|
|
189
180
|
|
|
190
|
-
###
|
|
181
|
+
### Shared helpers
|
|
191
182
|
- `cronScheduler` — `/cron start|stop|list` + the cron dashboard view.
|
|
192
183
|
- `settingsController` — launch mode / agent provider,
|
|
193
184
|
with daemon restart on mode/provider change. `autoResume` stays config/command-driven.
|
|
194
|
-
- `chatLogController` — log buffer + history file replay
|
|
195
|
-
(`loadHistory`, `appendHistory`, `markStreamStart`,
|
|
196
|
-
`setHistoryTarget`, `resetViewState`).
|
|
197
|
-
- `statusLineController` — debounced status line with background-task
|
|
198
|
-
suffix (e.g. `(ufoo-agent processing)`); `queueStatusLine`,
|
|
199
|
-
`resolveStatusLine`, `enqueueBusStatus`, `resolveBusStatus`.
|
|
200
|
-
- `streamTracker` — per-publisher stream state + markdown rendering
|
|
201
|
-
(`beginStream`, `appendStreamDelta`, `finalizeStream`,
|
|
202
|
-
`markPendingDelivery`, `consumePendingDelivery`).
|
|
203
185
|
- `transientAgentState` — TTL-bounded `working / waiting_input /
|
|
204
186
|
blocked` markers per agent.
|
|
205
187
|
- `projectCloseController` — `requestCloseProject(index)` runs daemon
|
|
@@ -207,31 +189,20 @@ Source: `src/chat/index.js` (2215 lines) + ~30 controllers in
|
|
|
207
189
|
- `agentDirectory` — agent label resolution + window clamping (pure).
|
|
208
190
|
- `internalAgentLogHistory` — bus log replay for internal agents.
|
|
209
191
|
|
|
210
|
-
### Internal-agent sub-view
|
|
211
|
-
-
|
|
212
|
-
|
|
213
|
-
`
|
|
214
|
-
|
|
215
|
-
`exitAgentView`, `sendRawToAgent`, `sendResizeToAgent`,
|
|
216
|
-
`requestAgentSnapshot`, `writeToAgentTerm`, `placeAgentCursor`,
|
|
217
|
-
`handleBusAgentKey`, `handleResizeInAgentView`, `refreshAgentView`.
|
|
218
|
-
- Two render modes inside it: PTY mirror (raw ANSI passthrough +
|
|
219
|
-
cursor placement, `agentSockets.connectOutput/Input`,
|
|
220
|
-
`requestSnapshot`) and an embedded bus subview (own input value,
|
|
221
|
-
cursor, log, animated status indicator).
|
|
222
|
-
- `agentBar.computeAgentBar` renders the agent strip across both
|
|
223
|
-
modes.
|
|
192
|
+
### Internal-agent sub-view
|
|
193
|
+
- Ink owns the agent sub-view inside ChatApp.
|
|
194
|
+
- PTY mirror mode uses `agentSockets.connectOutput/Input` and
|
|
195
|
+
`requestSnapshot`.
|
|
196
|
+
- Embedded bus mode keeps its own input value, cursor, log and status.
|
|
224
197
|
- `agentSockets.createAgentSockets` owns the PTY/bus socket
|
|
225
198
|
lifecycle.
|
|
226
|
-
- Exit/restore reattaches `screen.children`, restores scroll region
|
|
227
|
-
and unfreezes `screen.render`.
|
|
228
199
|
|
|
229
|
-
### Layout (
|
|
230
|
-
-
|
|
231
|
-
|
|
232
|
-
-
|
|
233
|
-
|
|
234
|
-
|
|
200
|
+
### Layout (Ink)
|
|
201
|
+
- `ChatApp` owns the chat surface as a React tree under
|
|
202
|
+
`src/ui/ink/`.
|
|
203
|
+
- Dashboard, log, status, completion, internal-agent panes and input are
|
|
204
|
+
rendered from React state with ink flex layout. No blessed widget geometry
|
|
205
|
+
or controller layer remains.
|
|
235
206
|
|
|
236
207
|
### Commands
|
|
237
208
|
`/bus`, `/ctx`, `/daemon`, `/doctor`, `/cron`, `/group`, `/init`,
|
|
@@ -243,45 +214,30 @@ and `shouldEchoCommandInChat(text)` are pure.
|
|
|
243
214
|
|
|
244
215
|
### Cross-cutting
|
|
245
216
|
- `text.js`: `escapeBlessed`, `stripBlessedTags`, `stripAnsi`,
|
|
246
|
-
`truncateAnsi`, `decodeEscapedNewlines`.
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
217
|
+
`truncateAnsi`, `decodeEscapedNewlines`. The blessed-tag helpers are now
|
|
218
|
+
compatibility shims for older daemon/router log strings; ink call sites
|
|
219
|
+
strip or normalize those tags before rendering. The ANSI helpers stay
|
|
220
|
+
relevant.
|
|
250
221
|
- `rawKeyMap.keyToRaw(ch, key)`: converts ink-style key events to
|
|
251
222
|
PTY bytes for the agent view. Stays as-is.
|
|
252
223
|
- `transport.js`: `startDaemon`, `stopDaemon`, `connectWithRetry`.
|
|
253
224
|
Framework-agnostic, no migration needed.
|
|
254
225
|
|
|
255
|
-
###
|
|
256
|
-
1. **Entry**:
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
wrap the message router in a `useEffect` subscription that pumps
|
|
264
|
-
into `dispatch`.
|
|
265
|
-
5. **Side controllers**: keep the controllers as plain modules;
|
|
266
|
-
`useEffect` subscribes/unsubscribes instead of attaching to
|
|
267
|
-
blessed events.
|
|
268
|
-
6. **Agent view**: ink can't render arbitrary ANSI inside a `<Box>`,
|
|
269
|
-
but it can yield stdout to a "raw mode" component that writes
|
|
270
|
-
straight through during PTY mirror; we'll model it with
|
|
271
|
-
`<Static>`-style raw write or by suspending ink's render and
|
|
272
|
-
passing stdout through, then re-mount on exit.
|
|
273
|
-
7. **Layout**: replace `height: "100%-N"` with flexbox + `flexGrow`.
|
|
274
|
-
8. **Commands**: long-running commands run on a serialised promise
|
|
275
|
-
chain like ucode's `runChainRef`.
|
|
276
|
-
9. **Cross-cutting**: drop blessed-tag helpers from ink call sites;
|
|
277
|
-
ANSI/text helpers stay.
|
|
226
|
+
### Removal notes
|
|
227
|
+
1. **Entry**: `src/app/chat/index.js` delegates directly to `runChatInk()`.
|
|
228
|
+
2. **ucode**: `src/code/tui.js` is a compatibility export wrapper around
|
|
229
|
+
`src/ui/format/` and `runUcodeInkTui()`.
|
|
230
|
+
3. **Controllers**: the blessed widget controllers and their tests were
|
|
231
|
+
removed with the fallback path.
|
|
232
|
+
4. **Markup**: old brace-tag helpers remain only where shared daemon/chat
|
|
233
|
+
helpers still emit or sanitize legacy log markup.
|
|
278
234
|
|
|
279
235
|
### P3 phase plan
|
|
280
236
|
|
|
281
237
|
| Step | Goal | Status |
|
|
282
238
|
|---|---|---|
|
|
283
239
|
| P3.1 | This audit | ✅ |
|
|
284
|
-
| P3.2 |
|
|
240
|
+
| P3.2 | Ink-only `runChat()` entrypoint | ✅ |
|
|
285
241
|
| P3.3 | ChatApp shell (banner + log + input + status) | ✅ |
|
|
286
242
|
| P3.4 | Five dashboard views as React components | ✅ |
|
|
287
243
|
| P3.5 | Daemon connection + PROMPT/BUS_SEND wiring | ✅ |
|
|
@@ -317,7 +273,6 @@ and `shouldEchoCommandInChat(text)` are pure.
|
|
|
317
273
|
```sh
|
|
318
274
|
./bin/ufoo.js chat # project mode
|
|
319
275
|
./bin/ufoo.js chat --global # global controller mode
|
|
320
|
-
# fallback: UFOO_TUI=blessed ./bin/ufoo.js chat
|
|
321
276
|
```
|
|
322
277
|
|
|
323
278
|
### Layout
|
|
@@ -366,8 +321,7 @@ and `shouldEchoCommandInChat(text)` are pure.
|
|
|
366
321
|
with daemon stop/start/restart, cron IPC, project switching and agent
|
|
367
322
|
activation callbacks.
|
|
368
323
|
- **Input history persistence** — `<projectRoot>/.ufoo/chat/input-history.jsonl`
|
|
369
|
-
is loaded on mount and appended on every submit
|
|
370
|
-
blessed inputHistoryController.
|
|
324
|
+
is loaded on mount and appended on every submit.
|
|
371
325
|
- **Daemon message routing** — Ink routes daemon envelopes through
|
|
372
326
|
`daemonMessageRouter`, including BUS phase status, transient states,
|
|
373
327
|
pending delivery markers, streams, close/launch refreshes and loop
|
package/src/ui/format/index.js
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Pure formatting + input-math helpers
|
|
5
|
-
*
|
|
6
|
-
* src/ui/components/. No blessed import allowed in this module.
|
|
7
|
-
*
|
|
8
|
-
* Anything that touches a blessed widget (escapeBlessedLiteral, the blessed
|
|
9
|
-
* banner builder, resolveLogContentWidth) stays in src/code/tui.js.
|
|
4
|
+
* Pure formatting + input-math helpers for the ink-based TUIs under
|
|
5
|
+
* src/ui/ink/. No terminal widget import is allowed in this module.
|
|
10
6
|
*/
|
|
11
7
|
|
|
12
8
|
const chalk = require("chalk");
|
|
@@ -72,24 +68,6 @@ function displayCellWidth(text = "") {
|
|
|
72
68
|
);
|
|
73
69
|
}
|
|
74
70
|
|
|
75
|
-
// NOTE: returns a blessed-flavoured tag string ("{cyan-bg}{white-fg}...").
|
|
76
|
-
// Used by the legacy blessed TUI; ink callers should not render this directly
|
|
77
|
-
// (the tags would show up as literal text). When P1 needs the same output for
|
|
78
|
-
// ink, add a sibling helper that emits chalk/ANSI instead.
|
|
79
|
-
function formatHighlightedUserInput(text = "", {
|
|
80
|
-
width = 80,
|
|
81
|
-
escapeText = (value) => String(value || ""),
|
|
82
|
-
} = {}) {
|
|
83
|
-
const plain = String(text || "").trim();
|
|
84
|
-
if (!plain) return "";
|
|
85
|
-
const targetWidth = Math.max(1, Math.floor(Number(width) || 80) - 1);
|
|
86
|
-
const prefix = " → ";
|
|
87
|
-
const suffix = " ";
|
|
88
|
-
const contentWidth = displayCellWidth(`${prefix}${plain}${suffix}`);
|
|
89
|
-
const pad = " ".repeat(Math.max(0, targetWidth - contentWidth));
|
|
90
|
-
return `{cyan-bg}{white-fg}${prefix}${escapeText(plain)}${suffix}${pad}{/white-fg}{/cyan-bg}`;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
71
|
class StreamBuffer {
|
|
94
72
|
constructor(writer, options = {}) {
|
|
95
73
|
this.writer = writer;
|
|
@@ -254,7 +232,7 @@ function loadActiveAgents(workspaceRoot) {
|
|
|
254
232
|
}
|
|
255
233
|
|
|
256
234
|
function renderLogLinesWithMarkdown(text = "", state = {}, escapeFn = (value) => String(value || "")) {
|
|
257
|
-
const { renderMarkdownLines } = require("
|
|
235
|
+
const { renderMarkdownLines } = require("./markdownRenderer");
|
|
258
236
|
return renderMarkdownLines(text, state, escapeFn);
|
|
259
237
|
}
|
|
260
238
|
|
|
@@ -331,7 +309,7 @@ function moveCursorToVisualLineBoundary({
|
|
|
331
309
|
boundary = "start",
|
|
332
310
|
strWidth,
|
|
333
311
|
} = {}) {
|
|
334
|
-
const inputMath = require("../../chat/inputMath");
|
|
312
|
+
const inputMath = require("../../app/chat/inputMath");
|
|
335
313
|
const text = String(inputValue || "");
|
|
336
314
|
const normalizedWidth = Number.isFinite(width) ? Math.max(1, Math.floor(width)) : 1;
|
|
337
315
|
const pos = clampCursorPos(cursorPos, text);
|
|
@@ -350,7 +328,7 @@ function moveCursorVertically({
|
|
|
350
328
|
preferredCol = null,
|
|
351
329
|
strWidth,
|
|
352
330
|
} = {}) {
|
|
353
|
-
const inputMath = require("../../chat/inputMath");
|
|
331
|
+
const inputMath = require("../../app/chat/inputMath");
|
|
354
332
|
const text = String(inputValue || "");
|
|
355
333
|
const normalizedWidth = Number.isFinite(width) ? Math.max(1, Math.floor(width)) : 1;
|
|
356
334
|
const pos = clampCursorPos(cursorPos, text);
|
|
@@ -974,7 +952,6 @@ module.exports = {
|
|
|
974
952
|
findLogicalLineEnd,
|
|
975
953
|
findLogicalLineStart,
|
|
976
954
|
findTrailingEscapeTagPrefix,
|
|
977
|
-
formatHighlightedUserInput,
|
|
978
955
|
formatPendingElapsed,
|
|
979
956
|
loadActiveAgents,
|
|
980
957
|
moveCursorByWord,
|