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
package/bin/ufoo.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/* eslint-disable no-console */
|
|
3
|
-
const { runCli } = require("../src/cli");
|
|
4
|
-
const { runDaemonCli } = require("../src/daemon/run");
|
|
5
|
-
const { runChat } = require("../src/chat");
|
|
6
|
-
const { runInternalRunner } = require("../src/
|
|
7
|
-
const {
|
|
8
|
-
const { resolveGlobalControllerProjectRoot } = require("../src/projects");
|
|
3
|
+
const { runCli } = require("../src/app/cli/run");
|
|
4
|
+
const { runDaemonCli } = require("../src/runtime/daemon/run");
|
|
5
|
+
const { runChat } = require("../src/app/chat");
|
|
6
|
+
const { runInternalRunner } = require("../src/agents/internal/internalRunner");
|
|
7
|
+
const { resolveGlobalControllerProjectRoot } = require("../src/runtime/projects");
|
|
9
8
|
|
|
10
9
|
const rawArgv = process.argv.slice(2);
|
|
11
10
|
|
|
@@ -33,23 +32,6 @@ async function main() {
|
|
|
33
32
|
await runInternalRunner({ projectRoot: process.cwd(), agentType, extraArgs });
|
|
34
33
|
return;
|
|
35
34
|
}
|
|
36
|
-
if (cmd === "agent-pty-runner") {
|
|
37
|
-
const agentType = argv[1] || "codex";
|
|
38
|
-
const extraArgs = argv.slice(2);
|
|
39
|
-
try {
|
|
40
|
-
await runPtyRunner({ projectRoot: process.cwd(), agentType, extraArgs });
|
|
41
|
-
} catch (err) {
|
|
42
|
-
const normalized = String(agentType || "").trim().toLowerCase();
|
|
43
|
-
if (normalized === "ufoo" || normalized === "ucode" || normalized === "ufoo-code") {
|
|
44
|
-
throw err;
|
|
45
|
-
}
|
|
46
|
-
// Fallback to headless runner if PTY is unavailable
|
|
47
|
-
// eslint-disable-next-line no-console
|
|
48
|
-
console.error(`[pty-runner] ${err.message || err}. Falling back to headless internal runner.`);
|
|
49
|
-
await runInternalRunner({ projectRoot: process.cwd(), agentType, extraArgs });
|
|
50
|
-
}
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
35
|
if (cmd === "chat") {
|
|
54
36
|
await runChat(chatProjectRoot, { globalMode });
|
|
55
37
|
return;
|
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
|
|
4
4
|
> **Default: do not write a decision.** Record one only for important, plan-level knowledge that should constrain future work: architectural choices, trade-off analysis, cross-agent coordination, or precedent-setting integration contracts. NOT for routine findings, simple fixes, or because the user asked for a plan/evaluation/recommendation. Durable project facts belong in shared memory, not decisions. → `ufoo ctx decisions new "Title"` BEFORE acting only when that high bar is met.
|
|
5
5
|
> **Read shared memory before writing it.** Durable facts live in `.ufoo/memory/`; use `ufoo memory list/show`, `recall`, `search_memory`, or redacted `search_history` evidence before `remember` / `edit_memory`.
|
|
6
|
-
> **Auto-execute bus messages.** On `ubus`: execute tasks immediately,
|
|
6
|
+
> **Auto-execute bus messages.** On `ubus`: execute tasks immediately, then `ufoo bus ack`. Never ask the user.
|
|
7
7
|
> **Full protocol**: `/ufoo` skill (auto-loaded on session start). Docs: `.ufoo/docs/`
|
|
8
8
|
<!-- /ufoo -->
|
|
@@ -120,7 +120,7 @@ ufoo bus ack "$SUBSCRIBER"
|
|
|
120
120
|
|
|
121
121
|
**This is critical** - if you don't ack, the daemon will keep injecting `/ubus` commands.
|
|
122
122
|
|
|
123
|
-
If there's nothing to do (no actionable task), just ack
|
|
123
|
+
**Default behavior is ack-only, no reply.** If there's nothing to do (no actionable task, no question to answer, no follow-up the sender genuinely needs), just ack and stop. Silence is a valid response — see "Handling Received Messages" below for when a reply IS warranted.
|
|
124
124
|
|
|
125
125
|
### 6. Routing Override
|
|
126
126
|
|
|
@@ -164,15 +164,40 @@ ufoo bus nick <subscriber-id> "new-nickname"
|
|
|
164
164
|
|
|
165
165
|
## Handling Received Messages
|
|
166
166
|
|
|
167
|
-
When receiving targeted messages
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
167
|
+
When receiving targeted messages, the default flow is **execute → ack → stop**.
|
|
168
|
+
Replies are the exception, not the default.
|
|
169
|
+
|
|
170
|
+
1. **Understand request** — Read message content.
|
|
171
|
+
2. **Execute task** — If the message delegates a task, do it.
|
|
172
|
+
3. **`ufoo bus ack "$SUBSCRIBER"`** — Always ack, even when not replying.
|
|
173
|
+
4. **Reply ONLY when substantive.** Send `ufoo bus send` to the sender only if at least one of the following is true:
|
|
174
|
+
- The sender asked a question → reply with the answer.
|
|
175
|
+
- The sender delegated a task → reply with the result / artifact / status.
|
|
176
|
+
- You discovered something the sender needs to proceed → reply with that fact.
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
# Use this only when the criteria above are met.
|
|
180
|
+
ufoo bus send "<sender-id>" "<substantive-reply>"
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### Anti-pattern: greet / ack loops
|
|
184
|
+
|
|
185
|
+
If the inbound message is itself just a greeting, an acknowledgment, or a
|
|
186
|
+
pleasantry, **do not reply**. Acking is enough. A bare-acknowledgment reply
|
|
187
|
+
will be auto-injected on the other side, triggering them to reply in kind,
|
|
188
|
+
and the two of you will ping-pong forever.
|
|
189
|
+
|
|
190
|
+
| Inbound | Reply? |
|
|
191
|
+
|---|---|
|
|
192
|
+
| `👋` / `hi` / `hello` / `你好` | ❌ ack only |
|
|
193
|
+
| `👍` / `ok` / `收到` / `thanks` / `noted` | ❌ ack only |
|
|
194
|
+
| `已完成 / done / finished` (without a result the sender asked for) | ❌ ack only |
|
|
195
|
+
| `请把 src/foo.ts 改成 ...` (task) | ✅ reply with result |
|
|
196
|
+
| `这个 bug 的根因是什么?` (question) | ✅ reply with answer |
|
|
197
|
+
| `我帮你找到了 X,需要你做 Y` (request) | ✅ reply with status |
|
|
198
|
+
|
|
199
|
+
When in doubt: ack and wait. If the sender genuinely needs something
|
|
200
|
+
from you, they will follow up with a concrete question or task.
|
|
176
201
|
|
|
177
202
|
## Sending Messages
|
|
178
203
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "u-foo",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "Multi-Agent Workspace Protocol. Just add u. claude → uclaude, codex → ucodex.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"homepage": "https://ufoo.dev",
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
"ufoo": "bin/ufoo.js",
|
|
20
20
|
"uclaude": "bin/uclaude.js",
|
|
21
21
|
"ucodex": "bin/ucodex.js",
|
|
22
|
+
"uagy": "bin/uagy.js",
|
|
22
23
|
"ucode": "bin/ucode.js",
|
|
23
24
|
"ucode-core": "bin/ucode-core.js"
|
|
24
25
|
},
|
|
@@ -49,16 +50,15 @@
|
|
|
49
50
|
"dependencies": {
|
|
50
51
|
"@anthropic-ai/claude-agent-sdk": "^0.2.138",
|
|
51
52
|
"@openai/codex-sdk": "^0.130.0",
|
|
52
|
-
"
|
|
53
|
+
"@xterm/addon-serialize": "^0.14.0",
|
|
54
|
+
"@xterm/headless": "^6.0.0",
|
|
53
55
|
"chalk": "^4.1.2",
|
|
54
56
|
"commander": "^13.1.0",
|
|
55
57
|
"gray-matter": "^4.0.3",
|
|
56
58
|
"ink": "^5.2.1",
|
|
57
59
|
"node-pty": "^1.1.0",
|
|
58
60
|
"react": "^18.3.1",
|
|
59
|
-
"ws": "^8.19.0"
|
|
60
|
-
"xterm-addon-serialize": "^0.11.0",
|
|
61
|
-
"xterm-headless": "^5.3.0"
|
|
61
|
+
"ws": "^8.19.0"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
64
|
"jest": "^30.2.0"
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
const fs = require("fs");
|
|
4
4
|
const path = require("path");
|
|
5
5
|
const { spawn, spawnSync } = require("child_process");
|
|
6
|
-
const UfooInit = require("../src/init");
|
|
7
|
-
const { socketPath, isRunning } = require("../src/daemon");
|
|
8
|
-
const { connectWithRetry } = require("../src/chat/transport");
|
|
9
|
-
const { createDaemonTransport } = require("../src/chat/daemonTransport");
|
|
10
|
-
const { createDaemonCoordinator } = require("../src/chat/daemonCoordinator");
|
|
6
|
+
const UfooInit = require("../src/app/cli/features/init");
|
|
7
|
+
const { socketPath, isRunning } = require("../src/runtime/daemon");
|
|
8
|
+
const { connectWithRetry } = require("../src/app/chat/transport");
|
|
9
|
+
const { createDaemonTransport } = require("../src/app/chat/daemonTransport");
|
|
10
|
+
const { createDaemonCoordinator } = require("../src/app/chat/daemonCoordinator");
|
|
11
11
|
|
|
12
12
|
function sleep(ms) {
|
|
13
13
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
package/scripts/ink-demo.js
CHANGED
package/scripts/ink-smoke.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* BLOCKED ----+
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
const { isTranscriptActive } = require("
|
|
13
|
+
const { isTranscriptActive } = require("../providers/claudeSessionFiles");
|
|
14
14
|
|
|
15
15
|
const ACTIVITY_STATES = {
|
|
16
16
|
starting: "starting",
|
|
@@ -46,6 +46,27 @@ const INPUT_PATTERNS = {
|
|
|
46
46
|
/\[Y\/n\]/, // Bracket-style prompt
|
|
47
47
|
/\by\/n\b/i, // y/n prompt (common in confirmation dialogs)
|
|
48
48
|
],
|
|
49
|
+
// agy (Antigravity CLI) shows ink-style menus and y/n approvals.
|
|
50
|
+
agy: [
|
|
51
|
+
/Use arrow keys to navigate, Enter to select/, // Any agy menu selector
|
|
52
|
+
/Select login method:/, // Initial OAuth login picker
|
|
53
|
+
/Yes, and run (?:in|without) sandbox/i, // Terminal command approval (sandbox toggle)
|
|
54
|
+
/\bn\b\s*-\s*Don't run/i, // y/n/edit confirmation
|
|
55
|
+
],
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// Agent-specific FATAL patterns that immediately move the agent into BLOCKED
|
|
59
|
+
// state (no quiet-window/timeout waiting). Reserved for hard backend errors
|
|
60
|
+
// the user can't resolve by waiting — e.g. agy's account-eligibility / region
|
|
61
|
+
// check failure, which returns 400 from the backend and the conversation
|
|
62
|
+
// never advances.
|
|
63
|
+
const FATAL_PATTERNS = {
|
|
64
|
+
agy: [
|
|
65
|
+
/Eligibility check failed/, // 18+/region not allowed
|
|
66
|
+
/User location is not supported/, // Geo restriction
|
|
67
|
+
/Account ineligible/, // Generic account-state failure
|
|
68
|
+
/FAILED_PRECONDITION/, // gRPC backend precondition reject
|
|
69
|
+
],
|
|
49
70
|
};
|
|
50
71
|
|
|
51
72
|
const COMMON_PATTERNS = [
|
|
@@ -80,7 +101,7 @@ class ActivityDetector {
|
|
|
80
101
|
/**
|
|
81
102
|
* @param {string} agentType - e.g. "claude-code", "codex"
|
|
82
103
|
* @param {object} [options]
|
|
83
|
-
* @param {string} [options.mode] - launch mode ("
|
|
104
|
+
* @param {string} [options.mode] - launch mode ("terminal"/"tmux"/"iterm2"/"pty-runner")
|
|
84
105
|
* @param {number} [options.bufferSize=4000] - rolling buffer size in chars
|
|
85
106
|
* @param {number} [options.tailLines=10] - number of tail lines used for quiet-time prompt detection
|
|
86
107
|
* @param {boolean} [options.startOnOutput=false] - allow STARTING -> WORKING on first output
|
|
@@ -259,6 +280,22 @@ class ActivityDetector {
|
|
|
259
280
|
|
|
260
281
|
const tailBuffer = this._tailWindow();
|
|
261
282
|
|
|
283
|
+
// Fatal-pattern check first: these go straight to BLOCKED with no
|
|
284
|
+
// recovery timer. Used for backend errors the user can't wait out.
|
|
285
|
+
const fatalPatterns = FATAL_PATTERNS[this.agentType] || [];
|
|
286
|
+
for (const pattern of fatalPatterns) {
|
|
287
|
+
const match = pattern.exec(tailBuffer);
|
|
288
|
+
if (!match) continue;
|
|
289
|
+
const matchedText = String(match[0] || "");
|
|
290
|
+
const matchIndex = Number.isFinite(match.index)
|
|
291
|
+
? match.index
|
|
292
|
+
: Math.max(0, tailBuffer.length - matchedText.length);
|
|
293
|
+
if (this._hasDeniedContext(tailBuffer, matchIndex, matchedText.length)) continue;
|
|
294
|
+
this._clearBlockedTimer();
|
|
295
|
+
this._setState(ACTIVITY_STATES.blocked, `fatal:${pattern.source}`);
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
|
|
262
299
|
// Check agent-specific patterns only after output has stabilized.
|
|
263
300
|
const agentPatterns = INPUT_PATTERNS[this.agentType] || [];
|
|
264
301
|
const allPatterns = [...agentPatterns, ...COMMON_PATTERNS];
|
|
@@ -5,7 +5,7 @@ const { writeActivityState } = require("./activityStateWriter");
|
|
|
5
5
|
/**
|
|
6
6
|
* Unified activity state publisher.
|
|
7
7
|
* Encapsulates the "write to disk + broadcast event" pattern used by
|
|
8
|
-
*
|
|
8
|
+
* launcher, notifier, and internalRunner.
|
|
9
9
|
*
|
|
10
10
|
* Dedupe key is `state|detail` so that within the same canonical state
|
|
11
11
|
* (e.g. `working`) callers can publish detail transitions like
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const fs = require("fs");
|
|
2
|
-
const { readJSON, writeJSON } = require("
|
|
3
|
-
const { appendAgentRegistryDiagnostic } = require("
|
|
2
|
+
const { readJSON, writeJSON } = require("../../coordination/bus/utils");
|
|
3
|
+
const { appendAgentRegistryDiagnostic } = require("../../coordination/state/agentRegistryDiagnostics");
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Centralized helper for writing activity_state to all-agents.json.
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* canonical activity model (`starting`/`ready`/`working`/`idle`/`waiting_input`/`blocked`)
|
|
8
8
|
* plus a short detail string (e.g. `thinking`, `tool bash`). Publishes through
|
|
9
9
|
* an injected publisher so the same tracker can be reused by internal,
|
|
10
|
-
* internal
|
|
10
|
+
* internal, or future runner shapes.
|
|
11
11
|
*
|
|
12
12
|
* Design contract:
|
|
13
13
|
* - The tracker never reads PTY text or guesses state from prose. All state
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
const EventBus = require("
|
|
4
|
-
const { getToolDefinition, CALLER_TIERS } = require("
|
|
5
|
-
const { dispatchMessageHandler } = require("
|
|
6
|
-
const { ackBusHandler } = require("
|
|
3
|
+
const EventBus = require("../../coordination/bus");
|
|
4
|
+
const { getToolDefinition, CALLER_TIERS } = require("../../tools");
|
|
5
|
+
const { dispatchMessageHandler } = require("../../tools/handlers/dispatchMessage");
|
|
6
|
+
const { ackBusHandler } = require("../../tools/handlers/ackBus");
|
|
7
7
|
|
|
8
8
|
function normalizeObjectArgs(value) {
|
|
9
9
|
if (!value) return {};
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
const fs = require("fs");
|
|
4
4
|
const path = require("path");
|
|
5
|
-
const { getUfooPaths } = require("
|
|
6
|
-
const { redactSecrets } = require("
|
|
5
|
+
const { getUfooPaths } = require("../../coordination/state/paths");
|
|
6
|
+
const { redactSecrets } = require("../../runtime/privacy/redactor");
|
|
7
7
|
|
|
8
8
|
const LOOP_EVENT_SCHEMA_VERSION = 1;
|
|
9
9
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
const { executeControllerTool } = require("./controllerToolExecutor");
|
|
4
4
|
const { createLoopObserver } = require("./loopObservability");
|
|
5
|
-
const { finalizeRouterPayload } = require("
|
|
5
|
+
const { finalizeRouterPayload } = require("../../orchestration/controller/routerFinalize");
|
|
6
6
|
|
|
7
7
|
const DEFAULT_LOOP_OPTIONS = {
|
|
8
8
|
enabled: false,
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
const fs = require("fs");
|
|
2
2
|
const path = require("path");
|
|
3
|
-
const { buildStatus } = require("
|
|
4
|
-
const { getUfooPaths } = require("
|
|
5
|
-
const { normalizeGateRouterResult } = require("
|
|
6
|
-
const { normalizeProvider, sendUpstreamPrompt } = require("
|
|
7
|
-
const { normalizeAgentTypeAlias } = require("
|
|
8
|
-
const { buildCachedMemoryPrefix } = require("
|
|
9
|
-
const { listProjectRuntimes, isGlobalControllerProjectRoot } = require("
|
|
10
|
-
const { assignMissingLaunchNicknames } = require("
|
|
3
|
+
const { buildStatus } = require("../../runtime/daemon/status");
|
|
4
|
+
const { getUfooPaths } = require("../../coordination/state/paths");
|
|
5
|
+
const { normalizeGateRouterResult } = require("../../orchestration/controller/gateRouter");
|
|
6
|
+
const { normalizeProvider, sendUpstreamPrompt } = require("../providers/upstreamTransport");
|
|
7
|
+
const { normalizeAgentTypeAlias } = require("../../coordination/bus/utils");
|
|
8
|
+
const { buildCachedMemoryPrefix } = require("../../coordination/memory");
|
|
9
|
+
const { listProjectRuntimes, isGlobalControllerProjectRoot } = require("../../runtime/projects");
|
|
10
|
+
const { assignMissingLaunchNicknames } = require("../../orchestration/controller/launchRouting");
|
|
11
11
|
const {
|
|
12
12
|
CONTROLLER_MODES,
|
|
13
13
|
resolveControllerMode,
|
|
14
|
-
} = require("
|
|
14
|
+
} = require("../../orchestration/controller/flags");
|
|
15
15
|
|
|
16
16
|
function loadSessionState(projectRoot) {
|
|
17
17
|
const dir = getUfooPaths(projectRoot).agentDir;
|
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
const fs = require("fs");
|
|
2
2
|
const path = require("path");
|
|
3
|
-
const { getUfooPaths } = require("
|
|
3
|
+
const { getUfooPaths } = require("../../coordination/state/paths");
|
|
4
4
|
const { spawnSync } = require("child_process");
|
|
5
|
-
const EventBus = require("
|
|
6
|
-
const { readJSON, writeJSON } = require("
|
|
7
|
-
const { createActivityStatePublisher } = require("
|
|
8
|
-
const { createActivityTracker } = require("
|
|
9
|
-
const { loadConfig, normalizeCodexInternalThreadMode } = require("
|
|
10
|
-
const { createCodexThreadProvider } = require("
|
|
11
|
-
const { createClaudeThreadProvider } = require("
|
|
12
|
-
const { resolveClaudeUpstreamCredentials } = require("
|
|
13
|
-
const { buildUpstreamAuthFromCredential } = require("
|
|
14
|
-
const { listToolsForCallerTier, CALLER_TIERS } = require("
|
|
15
|
-
const { redactToolCallPayload, redactSecrets } = require("
|
|
16
|
-
const { buildCachedMemoryPrefix } = require("
|
|
17
|
-
const { shouldForwardStreamToPublisher } = require("
|
|
18
|
-
const { appendAgentRegistryDiagnostic } = require("
|
|
5
|
+
const EventBus = require("../../coordination/bus");
|
|
6
|
+
const { readJSON, writeJSON } = require("../../coordination/bus/utils");
|
|
7
|
+
const { createActivityStatePublisher } = require("../activity/activityStatePublisher");
|
|
8
|
+
const { createActivityTracker } = require("../activity/activityTracker");
|
|
9
|
+
const { loadConfig, normalizeCodexInternalThreadMode } = require("../../config");
|
|
10
|
+
const { createCodexThreadProvider } = require("../providers/codexThreadProvider");
|
|
11
|
+
const { createClaudeThreadProvider } = require("../providers/claudeThreadProvider");
|
|
12
|
+
const { resolveClaudeUpstreamCredentials } = require("../providers/credentials/claude");
|
|
13
|
+
const { buildUpstreamAuthFromCredential } = require("../providers/credentials");
|
|
14
|
+
const { listToolsForCallerTier, CALLER_TIERS } = require("../../tools");
|
|
15
|
+
const { redactToolCallPayload, redactSecrets } = require("../../runtime/privacy/redactor");
|
|
16
|
+
const { buildCachedMemoryPrefix } = require("../../coordination/memory");
|
|
17
|
+
const { normalizePublisher, shouldForwardStreamToPublisher } = require("../launch/publisherRouting");
|
|
18
|
+
const { appendAgentRegistryDiagnostic } = require("../../coordination/state/agentRegistryDiagnostics");
|
|
19
19
|
const {
|
|
20
20
|
buildDefaultStartupBootstrapPrompt,
|
|
21
21
|
isValueForCodexOption,
|
|
22
|
-
} = require("
|
|
22
|
+
} = require("../prompts/defaultBootstrap");
|
|
23
|
+
const { buildPromptInjectionText } = require("../../coordination/bus/promptEnvelope");
|
|
23
24
|
|
|
24
25
|
function sleep(ms) {
|
|
25
26
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
@@ -161,6 +162,21 @@ function buildMemoryPrefix(projectRoot, limit = 50) {
|
|
|
161
162
|
}
|
|
162
163
|
}
|
|
163
164
|
|
|
165
|
+
function readAgentsMap(projectRoot) {
|
|
166
|
+
try {
|
|
167
|
+
const data = readJSON(getUfooPaths(projectRoot).agentsFile, null);
|
|
168
|
+
return data && data.agents && typeof data.agents === "object" ? data.agents : {};
|
|
169
|
+
} catch {
|
|
170
|
+
return {};
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
function buildInternalPromptMessage(projectRoot, subscriber, evt = {}) {
|
|
175
|
+
const message = String((evt.data && evt.data.message) || "");
|
|
176
|
+
if (evt.__agentViewRaw) return message;
|
|
177
|
+
return buildPromptInjectionText(evt, subscriber, readAgentsMap(projectRoot));
|
|
178
|
+
}
|
|
179
|
+
|
|
164
180
|
function createBusSender(projectRoot, subscriber) {
|
|
165
181
|
const eventBus = new EventBus(projectRoot);
|
|
166
182
|
let sendQueue = Promise.resolve();
|
|
@@ -187,11 +203,20 @@ function createBusSender(projectRoot, subscriber) {
|
|
|
187
203
|
|
|
188
204
|
function isChatUiSource(source = "") {
|
|
189
205
|
const value = String(source || "").trim();
|
|
190
|
-
return value === "chat-direct"
|
|
206
|
+
return value === "chat-direct"
|
|
207
|
+
|| value === "chat-agent-view"
|
|
208
|
+
|| value === "chat-internal-agent-view";
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
function isUfooAgentDispatchSource(source = "") {
|
|
212
|
+
const value = String(source || "").trim();
|
|
213
|
+
return value === "ufoo-agent" || value === "ufoo-agent-gate-router";
|
|
191
214
|
}
|
|
192
215
|
|
|
193
216
|
function shouldStreamReplyToPublisher(projectRoot, publisher, evt = {}) {
|
|
194
|
-
|
|
217
|
+
const source = evt && evt.data ? evt.data.source : "";
|
|
218
|
+
if (isChatUiSource(source)) return true;
|
|
219
|
+
if (normalizePublisher(publisher) === "ufoo-agent" && isUfooAgentDispatchSource(source)) return true;
|
|
195
220
|
return shouldForwardStreamToPublisher(projectRoot, publisher);
|
|
196
221
|
}
|
|
197
222
|
|
|
@@ -311,7 +336,8 @@ async function handleEvent(
|
|
|
311
336
|
) {
|
|
312
337
|
if (!evt || !evt.data || !evt.data.message) return;
|
|
313
338
|
const memoryPrefix = buildMemoryPrefix(projectRoot);
|
|
314
|
-
const
|
|
339
|
+
const promptMessage = buildInternalPromptMessage(projectRoot, subscriber, evt);
|
|
340
|
+
const prompt = [bootstrapText, memoryPrefix, promptMessage]
|
|
315
341
|
.map((item) => String(item || "").trim())
|
|
316
342
|
.filter(Boolean)
|
|
317
343
|
.join("\n\n");
|
|
@@ -732,9 +758,6 @@ async function runInternalRunner({ projectRoot, agentType = "codex", extraArgs =
|
|
|
732
758
|
const queueDir = path.join(getUfooPaths(projectRoot).busQueuesDir, safeSubscriber(subscriber));
|
|
733
759
|
const queueFile = path.join(queueDir, "pending.jsonl");
|
|
734
760
|
const normalizedAgentType = String(agentType || "").trim().toLowerCase();
|
|
735
|
-
if (normalizedAgentType === "ufoo" || normalizedAgentType === "ucode" || normalizedAgentType === "ufoo-code") {
|
|
736
|
-
throw new Error("ufoo core is not supported by headless internal runner; use internal-pty");
|
|
737
|
-
}
|
|
738
761
|
const provider = normalizedAgentType === "codex" ? "codex-cli" : "claude-cli";
|
|
739
762
|
const model = process.env.UFOO_AGENT_MODEL || "";
|
|
740
763
|
const bootstrap = resolveInternalBootstrap({
|