u-foo 1.0.3 → 1.1.9
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 +110 -11
- package/README.zh-CN.md +9 -7
- package/SKILLS/ufoo/SKILL.md +132 -0
- package/SKILLS/uinit/SKILL.md +78 -0
- package/SKILLS/ustatus/SKILL.md +36 -0
- package/bin/uclaude.js +13 -0
- package/bin/ucode-core.js +15 -0
- package/bin/ucode.js +125 -0
- package/bin/ucodex.js +13 -0
- package/bin/ufoo +9 -31
- package/bin/ufoo-assistant-agent.js +5 -0
- package/bin/ufoo-engine.js +25 -0
- package/bin/ufoo.js +17 -0
- package/modules/AGENTS.template.md +29 -11
- package/modules/bus/README.md +33 -25
- package/modules/bus/SKILLS/ubus/SKILL.md +19 -8
- package/modules/context/README.md +18 -40
- package/modules/context/SKILLS/uctx/SKILL.md +63 -1
- package/modules/online/SKILLS/ufoo-online/SKILL.md +144 -0
- package/package.json +25 -4
- package/scripts/import-pi-mono.js +124 -0
- package/scripts/postinstall.js +30 -0
- package/scripts/sync-claude-skills.sh +21 -0
- package/src/agent/cliRunner.js +554 -33
- package/src/agent/internalRunner.js +150 -56
- package/src/agent/launcher.js +754 -0
- package/src/agent/normalizeOutput.js +1 -1
- package/src/agent/notifier.js +340 -0
- package/src/agent/ptyRunner.js +847 -0
- package/src/agent/ptyWrapper.js +379 -0
- package/src/agent/readyDetector.js +175 -0
- package/src/agent/ucode.js +443 -0
- package/src/agent/ucodeBootstrap.js +113 -0
- package/src/agent/ucodeBuild.js +67 -0
- package/src/agent/ucodeDoctor.js +184 -0
- package/src/agent/ucodeRuntimeConfig.js +129 -0
- package/src/agent/ufooAgent.js +46 -42
- package/src/assistant/agent.js +260 -0
- package/src/assistant/bridge.js +172 -0
- package/src/assistant/engine.js +252 -0
- package/src/assistant/stdio.js +58 -0
- package/src/assistant/ufooEngineCli.js +306 -0
- package/src/bus/activate.js +172 -0
- package/src/bus/daemon.js +436 -0
- package/src/bus/index.js +842 -0
- package/src/bus/inject.js +315 -0
- package/src/bus/message.js +430 -0
- package/src/bus/nickname.js +88 -0
- package/src/bus/queue.js +136 -0
- package/src/bus/shake.js +26 -0
- package/src/bus/store.js +189 -0
- package/src/bus/subscriber.js +312 -0
- package/src/bus/utils.js +363 -0
- package/src/chat/agentBar.js +117 -0
- package/src/chat/agentDirectory.js +88 -0
- package/src/chat/agentSockets.js +225 -0
- package/src/chat/agentViewController.js +298 -0
- package/src/chat/chatLogController.js +115 -0
- package/src/chat/commandExecutor.js +700 -0
- package/src/chat/commands.js +132 -0
- package/src/chat/completionController.js +414 -0
- package/src/chat/cronScheduler.js +160 -0
- package/src/chat/daemonConnection.js +166 -0
- package/src/chat/daemonCoordinator.js +64 -0
- package/src/chat/daemonMessageRouter.js +257 -0
- package/src/chat/daemonReconnect.js +41 -0
- package/src/chat/daemonTransport.js +36 -0
- package/src/chat/daemonTransportDefaults.js +10 -0
- package/src/chat/dashboardKeyController.js +480 -0
- package/src/chat/dashboardView.js +154 -0
- package/src/chat/index.js +1011 -1392
- package/src/chat/inputHistoryController.js +105 -0
- package/src/chat/inputListenerController.js +304 -0
- package/src/chat/inputMath.js +104 -0
- package/src/chat/inputSubmitHandler.js +171 -0
- package/src/chat/layout.js +165 -0
- package/src/chat/pasteController.js +81 -0
- package/src/chat/rawKeyMap.js +42 -0
- package/src/chat/settingsController.js +132 -0
- package/src/chat/statusLineController.js +177 -0
- package/src/chat/streamTracker.js +138 -0
- package/src/chat/text.js +70 -0
- package/src/chat/transport.js +61 -0
- package/src/cli/busCoreCommands.js +59 -0
- package/src/cli/ctxCoreCommands.js +199 -0
- package/src/cli/onlineCoreCommands.js +379 -0
- package/src/cli.js +1162 -96
- package/src/code/README.md +29 -0
- package/src/code/UCODE_PROMPT.md +32 -0
- package/src/code/agent.js +1651 -0
- package/src/code/cli.js +158 -0
- package/src/code/config +0 -0
- package/src/code/dispatch.js +42 -0
- package/src/code/index.js +70 -0
- package/src/code/nativeRunner.js +1213 -0
- package/src/code/runtime.js +154 -0
- package/src/code/sessionStore.js +162 -0
- package/src/code/taskDecomposer.js +269 -0
- package/src/code/tools/bash.js +53 -0
- package/src/code/tools/common.js +42 -0
- package/src/code/tools/edit.js +70 -0
- package/src/code/tools/read.js +44 -0
- package/src/code/tools/write.js +35 -0
- package/src/code/tui.js +1580 -0
- package/src/config.js +56 -3
- package/src/context/decisions.js +324 -0
- package/src/context/doctor.js +183 -0
- package/src/context/index.js +55 -0
- package/src/context/sync.js +127 -0
- package/src/daemon/agentProcessManager.js +74 -0
- package/src/daemon/cronOps.js +241 -0
- package/src/daemon/index.js +998 -170
- package/src/daemon/ipcServer.js +99 -0
- package/src/daemon/ops.js +630 -48
- package/src/daemon/promptLoop.js +319 -0
- package/src/daemon/promptRequest.js +101 -0
- package/src/daemon/providerSessions.js +306 -0
- package/src/daemon/reporting.js +90 -0
- package/src/daemon/run.js +31 -1
- package/src/daemon/status.js +48 -8
- package/src/doctor/index.js +50 -0
- package/src/init/index.js +318 -0
- package/src/online/bridge.js +663 -0
- package/src/online/client.js +245 -0
- package/src/online/runner.js +253 -0
- package/src/online/server.js +992 -0
- package/src/online/tokens.js +103 -0
- package/src/report/store.js +331 -0
- package/src/shared/eventContract.js +35 -0
- package/src/shared/ptySocketContract.js +21 -0
- package/src/skills/index.js +159 -0
- package/src/status/index.js +285 -0
- package/src/terminal/adapterContract.js +87 -0
- package/src/terminal/adapterRouter.js +84 -0
- package/src/terminal/adapters/externalAdapter.js +14 -0
- package/src/terminal/adapters/internalAdapter.js +13 -0
- package/src/terminal/adapters/internalPtyAdapter.js +42 -0
- package/src/terminal/adapters/internalQueueAdapter.js +37 -0
- package/src/terminal/adapters/terminalAdapter.js +31 -0
- package/src/terminal/adapters/tmuxAdapter.js +30 -0
- package/src/terminal/detect.js +64 -0
- package/src/terminal/index.js +8 -0
- package/src/terminal/iterm2.js +126 -0
- package/src/ufoo/agentsStore.js +107 -0
- package/src/ufoo/paths.js +46 -0
- package/src/utils/banner.js +76 -0
- package/bin/uclaude +0 -65
- package/bin/ucodex +0 -65
- package/modules/bus/scripts/bus-alert.sh +0 -185
- package/modules/bus/scripts/bus-listen.sh +0 -117
- package/modules/context/ASSUMPTIONS.md +0 -7
- package/modules/context/CONSTRAINTS.md +0 -7
- package/modules/context/CONTEXT-STRUCTURE.md +0 -49
- package/modules/context/DECISION-PROTOCOL.md +0 -62
- package/modules/context/HANDOFF.md +0 -33
- package/modules/context/RULES.md +0 -15
- package/modules/context/SKILLS/README.md +0 -14
- package/modules/context/SYSTEM.md +0 -18
- package/modules/context/TEMPLATES/assumptions.md +0 -4
- package/modules/context/TEMPLATES/constraints.md +0 -4
- package/modules/context/TEMPLATES/decision.md +0 -16
- package/modules/context/TEMPLATES/project-context-readme.md +0 -6
- package/modules/context/TEMPLATES/system.md +0 -3
- package/modules/context/TEMPLATES/terminology.md +0 -4
- package/modules/context/TERMINOLOGY.md +0 -10
- package/scripts/banner.sh +0 -89
- package/scripts/bus-alert.sh +0 -6
- package/scripts/bus-autotrigger.sh +0 -6
- package/scripts/bus-daemon.sh +0 -231
- package/scripts/bus-inject.sh +0 -144
- package/scripts/bus-listen.sh +0 -6
- package/scripts/bus.sh +0 -984
- package/scripts/context-decisions.sh +0 -167
- package/scripts/context-doctor.sh +0 -72
- package/scripts/context-lint.sh +0 -110
- package/scripts/doctor.sh +0 -22
- package/scripts/init.sh +0 -247
- package/scripts/skills.sh +0 -113
- package/scripts/status.sh +0 -125
package/README.md
CHANGED
|
@@ -6,7 +6,9 @@ Multi-agent AI collaboration toolkit for Claude Code and OpenAI Codex.
|
|
|
6
6
|
|
|
7
7
|
- **Event Bus** - Real-time inter-agent messaging (`ufoo bus`)
|
|
8
8
|
- **Context Sharing** - Shared decisions and project context (`ufoo ctx`)
|
|
9
|
-
- **Agent Wrappers** - Auto-initialization for Claude Code (`uclaude`)
|
|
9
|
+
- **Agent Wrappers** - Auto-initialization for Claude Code (`uclaude`), Codex (`ucodex`), and ufoo core (`ucode`)
|
|
10
|
+
- **PTY Wrapper** - Intelligent terminal emulation with ready detection
|
|
11
|
+
- **Smart Probe Injection** - Waits for agent initialization before injecting commands
|
|
10
12
|
- **Skills System** - Extensible agent capabilities (`ufoo skills`)
|
|
11
13
|
|
|
12
14
|
## Quick Start
|
|
@@ -23,8 +25,46 @@ ufoo init
|
|
|
23
25
|
# Or use agent wrappers (auto-init + bus join)
|
|
24
26
|
uclaude # instead of 'claude'
|
|
25
27
|
ucodex # instead of 'codex'
|
|
28
|
+
ucode # ufoo self-developed coding agent entry
|
|
26
29
|
```
|
|
27
30
|
|
|
31
|
+
To import a local `pi-mono` checkout as a reference snapshot (reference-only):
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm run import:pi-mono -- /path/to/pi-mono
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Native self-developed implementation lives under `src/code`.
|
|
38
|
+
|
|
39
|
+
Prepare and verify `ucode` runtime wiring:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
ufoo ucode doctor
|
|
43
|
+
ufoo ucode prepare
|
|
44
|
+
ufoo ucode build
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Try native core queue runtime (WIP):
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
ucode-core submit --tool read --args-json '{"path":"README.md"}'
|
|
51
|
+
ucode-core run-once --json
|
|
52
|
+
ucode-core list --json
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Configure `ucode` provider/model/API in `.ufoo/config.json` (ufoo-managed):
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"ucodeProvider": "openai",
|
|
60
|
+
"ucodeModel": "gpt-5.1-codex",
|
|
61
|
+
"ucodeBaseUrl": "https://api.openai.com/v1",
|
|
62
|
+
"ucodeApiKey": "sk-***"
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
`ucode` writes these into a dedicated runtime directory (`.ufoo/agent/ucode/pi-agent`) and uses them for native planner/engine calls.
|
|
67
|
+
|
|
28
68
|
## Architecture
|
|
29
69
|
|
|
30
70
|
```
|
|
@@ -45,6 +85,8 @@ ucodex # instead of 'codex'
|
|
|
45
85
|
└─────────────┘ └───────┘ └─────────────┘
|
|
46
86
|
```
|
|
47
87
|
|
|
88
|
+
Bus state lives in `.ufoo/agent/all-agents.json` (metadata), `.ufoo/bus/*` (queues/events), and `.ufoo/daemon/*` (bus daemon runtime).
|
|
89
|
+
|
|
48
90
|
## Commands
|
|
49
91
|
|
|
50
92
|
| Command | Description |
|
|
@@ -53,7 +95,8 @@ ucodex # instead of 'codex'
|
|
|
53
95
|
| `ufoo status` | Show banner, unread bus messages, open decisions |
|
|
54
96
|
| `ufoo daemon --start|--stop|--status` | Manage ufoo daemon |
|
|
55
97
|
| `ufoo chat` | Launch ufoo chat UI (also default when no args) |
|
|
56
|
-
| `ufoo
|
|
98
|
+
| `ufoo resume [nickname]` | Resume agent sessions (optional nickname) |
|
|
99
|
+
| `ufoo bus join` | Join event bus (auto by uclaude/ucodex/ucode) |
|
|
57
100
|
| `ufoo bus send <id> <msg>` | Send message to agent |
|
|
58
101
|
| `ufoo bus check <id>` | Check pending messages |
|
|
59
102
|
| `ufoo bus status` | Show bus status |
|
|
@@ -73,14 +116,15 @@ ufoo/
|
|
|
73
116
|
│ ├── ufoo # Main CLI entry (bash)
|
|
74
117
|
│ ├── ufoo.js # Node wrapper
|
|
75
118
|
│ ├── uclaude # Claude Code wrapper
|
|
76
|
-
│
|
|
119
|
+
│ ├── ucodex # Codex wrapper
|
|
120
|
+
│ └── ucode # ufoo core wrapper
|
|
77
121
|
├── SKILLS/ # Global skills (uinit, ustatus)
|
|
78
|
-
├──
|
|
79
|
-
│ ├── bus
|
|
80
|
-
│ ├──
|
|
81
|
-
│ ├──
|
|
82
|
-
│
|
|
83
|
-
|
|
122
|
+
├── src/
|
|
123
|
+
│ ├── bus/ # Event bus implementation (JS)
|
|
124
|
+
│ ├── daemon/ # Daemon + chat bridge
|
|
125
|
+
│ ├── agent/ # Agent launch/runtime
|
|
126
|
+
│ └── code/ # Native ucode core implementation
|
|
127
|
+
├── scripts/ # Legacy helpers (bash, deprecated)
|
|
84
128
|
├── modules/
|
|
85
129
|
│ ├── context/ # Decision/context protocol
|
|
86
130
|
│ ├── bus/ # Bus module resources
|
|
@@ -101,8 +145,9 @@ your-project/
|
|
|
101
145
|
│ │ ├── queues/ # Per-agent message queues
|
|
102
146
|
│ │ └── offsets/ # Read position tracking
|
|
103
147
|
│ └── context/
|
|
104
|
-
│
|
|
105
|
-
|
|
148
|
+
│ ├── decisions/ # Decision records
|
|
149
|
+
│ └── decisions.jsonl # Decision index
|
|
150
|
+
├── scripts/ # Legacy symlink (optional)
|
|
106
151
|
├── AGENTS.md # Injected protocol blocks
|
|
107
152
|
└── CLAUDE.md # → AGENTS.md
|
|
108
153
|
```
|
|
@@ -162,3 +207,57 @@ ufoo --help
|
|
|
162
207
|
## License
|
|
163
208
|
|
|
164
209
|
UNLICENSED (Private)
|
|
210
|
+
|
|
211
|
+
## Recent Changes
|
|
212
|
+
|
|
213
|
+
### 🚀 Smart Ready Detection & PTY Wrapper (2026-02-06)
|
|
214
|
+
|
|
215
|
+
Added intelligent agent initialization detection for reliable probe injection:
|
|
216
|
+
|
|
217
|
+
**Features:**
|
|
218
|
+
- **ReadyDetector** - Monitors PTY output to detect when agents are ready
|
|
219
|
+
- **Smart Probe Timing** - Injects session probe after agent initialization (not before)
|
|
220
|
+
- **Multi-layer Fallback** - 10s ready detection + 8s fallback + 15 retries
|
|
221
|
+
- **Performance Metrics** - Tracks detection time and buffer usage (`UFOO_DEBUG=1`)
|
|
222
|
+
|
|
223
|
+
**Benefits:**
|
|
224
|
+
- ✅ No more premature probe injection (was 2s, now waits for prompt)
|
|
225
|
+
- ✅ Reliable session ID capture (39 tests, 100% pass)
|
|
226
|
+
- ✅ Production-ready error handling and logging
|
|
227
|
+
|
|
228
|
+
**Technical Details:**
|
|
229
|
+
- `src/agent/readyDetector.js` - PTY output analysis
|
|
230
|
+
- `src/agent/ptyWrapper.js` - Terminal emulation with monitoring
|
|
231
|
+
- `src/daemon/providerSessions.js` - Early probe triggering support
|
|
232
|
+
|
|
233
|
+
See `.ufoo/plans/ready-detection-production-checklist.md` for full details.
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
### 🎉 Bash to JavaScript Migration (2026-02-04)
|
|
238
|
+
|
|
239
|
+
We've successfully migrated **80% of the codebase** from Bash to JavaScript for better maintainability and cross-platform support!
|
|
240
|
+
|
|
241
|
+
**What Changed:**
|
|
242
|
+
- ✅ EventBus core (986 lines) → 8 JavaScript modules
|
|
243
|
+
- ✅ Daemon & inject → Pure JavaScript
|
|
244
|
+
- ✅ status, skills, init → JavaScript modules
|
|
245
|
+
- ⏸️ Context management scripts remain in Bash (complex text processing)
|
|
246
|
+
|
|
247
|
+
**Impact:**
|
|
248
|
+
- **CLI commands unchanged** - All commands work exactly as before
|
|
249
|
+
- **Performance:** 51ms/message (vs 45ms in Bash, +13%)
|
|
250
|
+
- **Testing:** 20/20 integration tests passing
|
|
251
|
+
- **Quality:** Better error handling, testing, and IDE support
|
|
252
|
+
|
|
253
|
+
**Learn More:**
|
|
254
|
+
- See [MIGRATION_LOG.md](MIGRATION_LOG.md) for full details
|
|
255
|
+
- View archived scripts in `scripts/.archived/migrated-to-js/`
|
|
256
|
+
- Performance benchmarks in test reports
|
|
257
|
+
|
|
258
|
+
**Why This Matters:**
|
|
259
|
+
- 🎯 Unified JavaScript tech stack
|
|
260
|
+
- 🧪 Easier to test and maintain
|
|
261
|
+
- 🌍 Cross-platform potential (Windows/Linux)
|
|
262
|
+
- 💡 Better IDE support and refactoring
|
|
263
|
+
- 🚀 Foundation for future enhancements
|
package/README.zh-CN.md
CHANGED
|
@@ -45,6 +45,8 @@ ucodex # 代替 'codex'
|
|
|
45
45
|
└─────────────┘ └───────┘ └─────────────┘
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
+
Bus 状态存放于 `.ufoo/agent/all-agents.json`(元数据)、`.ufoo/bus/*`(队列/事件)以及 `.ufoo/daemon/*`(bus daemon 运行态)。
|
|
49
|
+
|
|
48
50
|
## 命令列表
|
|
49
51
|
|
|
50
52
|
| 命令 | 说明 |
|
|
@@ -53,6 +55,7 @@ ucodex # 代替 'codex'
|
|
|
53
55
|
| `ufoo status` | 显示 banner、未读消息和未处理决策 |
|
|
54
56
|
| `ufoo daemon --start|--stop|--status` | 管理 ufoo 守护进程 |
|
|
55
57
|
| `ufoo chat` | 启动 ufoo 交互界面(无参数默认进入) |
|
|
58
|
+
| `ufoo resume [nickname]` | 恢复 agent 会话(可选昵称) |
|
|
56
59
|
| `ufoo bus join` | 加入事件总线(uclaude/ucodex 自动完成)|
|
|
57
60
|
| `ufoo bus send <id> <msg>` | 发送消息给Agent |
|
|
58
61
|
| `ufoo bus check <id>` | 检查待处理消息 |
|
|
@@ -75,12 +78,11 @@ ufoo/
|
|
|
75
78
|
│ ├── uclaude # Claude Code 包装器
|
|
76
79
|
│ └── ucodex # Codex 包装器
|
|
77
80
|
├── SKILLS/ # 全局技能(uinit, ustatus)
|
|
78
|
-
├──
|
|
79
|
-
│ ├── bus
|
|
80
|
-
│ ├──
|
|
81
|
-
│
|
|
82
|
-
|
|
83
|
-
│ └── skills.sh # 技能管理
|
|
81
|
+
├── src/
|
|
82
|
+
│ ├── bus/ # 事件总线实现(JS)
|
|
83
|
+
│ ├── daemon/ # Daemon + chat bridge
|
|
84
|
+
│ └── agent/ # Agent 启动/运行
|
|
85
|
+
├── scripts/ # 历史遗留(bash,已弃用)
|
|
84
86
|
├── modules/
|
|
85
87
|
│ ├── context/ # 决策/上下文协议
|
|
86
88
|
│ ├── bus/ # 总线模块资源
|
|
@@ -102,7 +104,7 @@ your-project/
|
|
|
102
104
|
│ │ └── offsets/ # 读取位置跟踪
|
|
103
105
|
│ └── context/
|
|
104
106
|
│ └── DECISIONS/ # 决策记录
|
|
105
|
-
├── scripts/ #
|
|
107
|
+
├── scripts/ # 软链接(历史遗留,可选)
|
|
106
108
|
├── AGENTS.md # 注入的协议块
|
|
107
109
|
└── CLAUDE.md # → AGENTS.md
|
|
108
110
|
```
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ufoo
|
|
3
|
+
description: |
|
|
4
|
+
Unified ufoo agent protocol: context decisions, event bus, and initialization.
|
|
5
|
+
Use when: (1) input starts with "/ufoo" or "$ufoo", (2) agent session startup, (3) any ufoo-related operation.
|
|
6
|
+
Combines uctx (decisions), ubus (messaging), and uinit (initialization).
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# ufoo — Unified Agent Protocol
|
|
10
|
+
|
|
11
|
+
ufoo is the multi-agent coordination layer. It provides three capabilities:
|
|
12
|
+
|
|
13
|
+
1. **Context Decisions** — Persistent knowledge log shared across agents
|
|
14
|
+
2. **Event Bus** — Inter-agent messaging
|
|
15
|
+
3. **Initialization** — Project setup for ufoo modules
|
|
16
|
+
|
|
17
|
+
## Session Marker
|
|
18
|
+
|
|
19
|
+
When you see a probe marker command like `/ufoo <marker>` (Claude) or `$ufoo <marker>` (Codex), this is daemon session tracking. **Do not reply.** Silently ignore it and wait for the next user input.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## 1. Context Decisions (uctx)
|
|
24
|
+
|
|
25
|
+
### When to Record
|
|
26
|
+
|
|
27
|
+
**"If it has information value, write it down."**
|
|
28
|
+
|
|
29
|
+
Record a decision whenever your work produces knowledge that would be useful to your future self, other agents, or the user. The threshold is LOW — when in doubt, record it.
|
|
30
|
+
|
|
31
|
+
- **Always record**: architectural choices, trade-off analysis, research findings, non-obvious gotchas, naming/convention changes, external API behavior discovered, performance observations, bug root causes
|
|
32
|
+
- **Also record**: open questions you couldn't resolve, assumptions you made, approaches you considered and rejected (with reasons), edge cases noticed but not handled
|
|
33
|
+
- **Write the decision BEFORE acting on it** — if your session dies, the knowledge survives
|
|
34
|
+
- **Granularity**: one sentence or multi-page analysis — match the depth to the information value
|
|
35
|
+
|
|
36
|
+
### Commands
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
ufoo ctx decisions -l # List all decisions
|
|
40
|
+
ufoo ctx decisions -s open # Check open decisions
|
|
41
|
+
ufoo ctx decisions -n 1 # Show latest decision
|
|
42
|
+
ufoo ctx decisions new "Title" # Create new decision
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Decision Format
|
|
46
|
+
|
|
47
|
+
Decisions live at: `.ufoo/context/decisions/`
|
|
48
|
+
|
|
49
|
+
```yaml
|
|
50
|
+
---
|
|
51
|
+
status: open
|
|
52
|
+
---
|
|
53
|
+
# DECISION NNNN: <Title>
|
|
54
|
+
|
|
55
|
+
Date: YYYY-MM-DD
|
|
56
|
+
Author: <agent>
|
|
57
|
+
|
|
58
|
+
Context:
|
|
59
|
+
What led to this decision?
|
|
60
|
+
|
|
61
|
+
Decision:
|
|
62
|
+
What is now considered true?
|
|
63
|
+
|
|
64
|
+
Implications:
|
|
65
|
+
What must follow from this?
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Handling Open Decisions
|
|
69
|
+
|
|
70
|
+
1. **Read and understand** — sync other agents' knowledge
|
|
71
|
+
2. **Check if action needed** — does it require implementation?
|
|
72
|
+
3. **Execute if needed** — do the work
|
|
73
|
+
4. **Resolve** — update frontmatter: `status: resolved`, `resolved_by:`, `resolved_at:`
|
|
74
|
+
|
|
75
|
+
**NEVER resolve blindly.** Reading the title is not enough.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## 2. Event Bus (ubus)
|
|
80
|
+
|
|
81
|
+
### Commands
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
ufoo bus check "$UFOO_SUBSCRIBER_ID" # Check pending messages
|
|
85
|
+
ufoo bus ack "$UFOO_SUBSCRIBER_ID" # Acknowledge after handling
|
|
86
|
+
ufoo bus send "<target>" "<message>" # Send message
|
|
87
|
+
ufoo bus broadcast "<message>" # Broadcast to all
|
|
88
|
+
ufoo bus status # Show bus status
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Runtime Report (Unified for assistant/ucodex/uclaude)
|
|
92
|
+
|
|
93
|
+
Use the same report contract for runtime progress sync:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
ufoo report start "<task>" --task <id> --agent "$UFOO_SUBSCRIBER_ID" --scope public
|
|
97
|
+
ufoo report progress "<detail>" --task <id> --agent "$UFOO_SUBSCRIBER_ID" --scope public
|
|
98
|
+
ufoo report done "<summary>" --task <id> --agent "$UFOO_SUBSCRIBER_ID" --scope public
|
|
99
|
+
ufoo report error "<reason>" --task <id> --agent "$UFOO_SUBSCRIBER_ID" --scope public
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Notes:
|
|
103
|
+
- Use `--scope private` for helper-internal reports (assistant-like private channel).
|
|
104
|
+
- `--controller ufoo-agent` routes report events to the ufoo-agent private inbox.
|
|
105
|
+
|
|
106
|
+
### Target Resolution
|
|
107
|
+
|
|
108
|
+
- Exact ID: `claude-code:abc123`
|
|
109
|
+
- Nickname: `architect`
|
|
110
|
+
- Type: `codex` (all codex agents)
|
|
111
|
+
- Wildcard: `*` (broadcast)
|
|
112
|
+
|
|
113
|
+
### CRITICAL: When you receive pending messages
|
|
114
|
+
|
|
115
|
+
**EXECUTE tasks immediately. Do NOT ask the user.**
|
|
116
|
+
|
|
117
|
+
1. Check: `ufoo bus check $UFOO_SUBSCRIBER_ID`
|
|
118
|
+
2. Execute each task
|
|
119
|
+
3. Reply: `ufoo bus send "<publisher>" "<result>"`
|
|
120
|
+
4. **Always ack**: `ufoo bus ack $UFOO_SUBSCRIBER_ID`
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## 3. Initialization (uinit)
|
|
125
|
+
|
|
126
|
+
Trigger: `/uinit` or `/ufoo init`
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
ufoo init --modules context,bus --project $(pwd)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
After init, auto-join bus if enabled.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: uinit
|
|
3
|
+
description: |
|
|
4
|
+
Initialize ufoo modules in current project.
|
|
5
|
+
Use when: (1) new project needs context/bus enabled, (2) user inputs /uinit or /ufoo init.
|
|
6
|
+
Provides interactive module selection, defaults to all selected.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# uinit
|
|
10
|
+
|
|
11
|
+
Initialize ufoo modules in current project.
|
|
12
|
+
|
|
13
|
+
## Trigger
|
|
14
|
+
|
|
15
|
+
User inputs `/uinit` or `/ufoo init`
|
|
16
|
+
|
|
17
|
+
## Execution Flow
|
|
18
|
+
|
|
19
|
+
### 1. Ask user to select modules
|
|
20
|
+
|
|
21
|
+
Use AskUserQuestion tool, provide multi-select, default all selected:
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
Please select modules to enable:
|
|
25
|
+
|
|
26
|
+
☑ context - Shared context protocol (.ufoo/context/)
|
|
27
|
+
☑ bus - Agent event bus (.ufoo/bus/ + .ufoo/agent/)
|
|
28
|
+
☐ resources - UI/Icons resources (optional)
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Options:
|
|
32
|
+
- `context` (recommended) - Shared context, decision recording, knowledge persistence
|
|
33
|
+
- `bus` (recommended) - Multi-agent communication, task delegation, message passing
|
|
34
|
+
- `resources` (optional) - UI tone guide, icon library
|
|
35
|
+
|
|
36
|
+
Default selected: context, bus
|
|
37
|
+
|
|
38
|
+
### 2. Execute initialization
|
|
39
|
+
|
|
40
|
+
Based on user selection, execute:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
ufoo init --modules <selected_modules> --project $(pwd)
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 3. If bus module selected, auto-join bus
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
SUBSCRIBER="${UFOO_SUBSCRIBER_ID:-$(ufoo bus whoami 2>/dev/null || true)}"
|
|
50
|
+
if [ -n "$SUBSCRIBER" ]; then
|
|
51
|
+
echo "Using existing subscriber ID: $SUBSCRIBER"
|
|
52
|
+
else
|
|
53
|
+
SUBSCRIBER=$(ufoo bus join | tail -1)
|
|
54
|
+
echo "Joined event bus: $SUBSCRIBER"
|
|
55
|
+
fi
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### 4. Report initialization result
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
=== ufoo initialization complete ===
|
|
62
|
+
|
|
63
|
+
Enabled modules:
|
|
64
|
+
✓ context → .ufoo/context/
|
|
65
|
+
✓ bus → .ufoo/bus/ + .ufoo/agent/
|
|
66
|
+
|
|
67
|
+
My identity: claude-code:<session-id>
|
|
68
|
+
|
|
69
|
+
Next steps:
|
|
70
|
+
- Run /ctx to check context status
|
|
71
|
+
- See AGENTS.md for protocol rules
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Notes
|
|
75
|
+
|
|
76
|
+
- If .ufoo/context, .ufoo/bus, or .ufoo/agent already exists, skip creation
|
|
77
|
+
- After initialization, reuse existing subscriber ID first, join only as fallback (if bus enabled)
|
|
78
|
+
- AGENTS.md will have protocol description block injected
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ustatus
|
|
3
|
+
description: |
|
|
4
|
+
Unified ufoo status check. Shows banner, unread bus messages, and open decisions.
|
|
5
|
+
Use when: (1) User asks for status, (2) Quick health check, (3) Before starting work.
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# ufoo Status
|
|
9
|
+
|
|
10
|
+
## What this does
|
|
11
|
+
|
|
12
|
+
Quick, unified status view:
|
|
13
|
+
- Banner
|
|
14
|
+
- Unread bus messages (unacked queues)
|
|
15
|
+
- Open decisions
|
|
16
|
+
|
|
17
|
+
## Workflow
|
|
18
|
+
|
|
19
|
+
### 1. Verify structure exists
|
|
20
|
+
|
|
21
|
+
Check `.ufoo/` exists. If missing, tell user to run `ufoo init`.
|
|
22
|
+
|
|
23
|
+
### 2. Run status command
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
ufoo status
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### 3. Report status
|
|
30
|
+
|
|
31
|
+
Briefly summarize:
|
|
32
|
+
- Unread messages count
|
|
33
|
+
- Open decisions count
|
|
34
|
+
- Any immediate action needed
|
|
35
|
+
|
|
36
|
+
If unread messages > 0, advise running `ufoo bus check <subscriber>` and `ufoo bus ack <subscriber>` after handling.
|
package/bin/uclaude.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* uclaude: Launch Claude Code and auto-join event bus
|
|
4
|
+
*
|
|
5
|
+
* Usage: uclaude [claude args...]
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const AgentLauncher = require("../src/agent/launcher");
|
|
9
|
+
|
|
10
|
+
const launcher = new AgentLauncher("claude-code", "claude");
|
|
11
|
+
const args = process.argv.slice(2);
|
|
12
|
+
|
|
13
|
+
launcher.launch(args);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { runUcodeCoreCli } = require("../src/code/cli");
|
|
4
|
+
|
|
5
|
+
(async () => {
|
|
6
|
+
const argv = process.argv.slice(2);
|
|
7
|
+
const result = await runUcodeCoreCli({ argv, projectRoot: process.cwd() });
|
|
8
|
+
if (result && typeof result.output === "string" && result.output) {
|
|
9
|
+
process.stdout.write(result.output);
|
|
10
|
+
}
|
|
11
|
+
process.exit(typeof result.exitCode === "number" ? result.exitCode : 0);
|
|
12
|
+
})().catch((err) => {
|
|
13
|
+
process.stderr.write(`${err && err.message ? err.message : "ucode-core failed"}\n`);
|
|
14
|
+
process.exit(1);
|
|
15
|
+
});
|
package/bin/ucode.js
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* ucode: Launch ufoo self-developed coding agent core
|
|
4
|
+
*
|
|
5
|
+
* Usage: ucode [core args...]
|
|
6
|
+
*
|
|
7
|
+
* Command resolution order:
|
|
8
|
+
* 1) UFOO_UCODE_CMD / UFOO_UFOO_CODE_CMD
|
|
9
|
+
* 2) .ufoo/config.json -> ucodeCommand / ufooCodeCommand
|
|
10
|
+
* 3) fallback: bundled native core entry
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const fs = require("fs");
|
|
14
|
+
const AgentLauncher = require("../src/agent/launcher");
|
|
15
|
+
const { resolveUcodeLaunch } = require("../src/agent/ucode");
|
|
16
|
+
const { prepareUcodeBootstrap } = require("../src/agent/ucodeBootstrap");
|
|
17
|
+
const { prepareUcodeRuntimeConfig } = require("../src/agent/ucodeRuntimeConfig");
|
|
18
|
+
|
|
19
|
+
function stripAppendSystemPromptArgs(args = [], targetFile = "") {
|
|
20
|
+
const normalizedTarget = String(targetFile || "").trim();
|
|
21
|
+
if (!Array.isArray(args) || args.length === 0) return { args: [], removed: false };
|
|
22
|
+
const nextArgs = [];
|
|
23
|
+
let removed = false;
|
|
24
|
+
for (let i = 0; i < args.length; i += 1) {
|
|
25
|
+
const item = String(args[i] || "");
|
|
26
|
+
if (!item) continue;
|
|
27
|
+
if (item === "--append-system-prompt") {
|
|
28
|
+
const value = String(args[i + 1] || "");
|
|
29
|
+
if (!normalizedTarget || value === normalizedTarget) {
|
|
30
|
+
removed = true;
|
|
31
|
+
i += 1;
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
nextArgs.push(item, value);
|
|
35
|
+
i += 1;
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (item.startsWith("--append-system-prompt=")) {
|
|
39
|
+
const value = item.slice("--append-system-prompt=".length);
|
|
40
|
+
if (!normalizedTarget || value === normalizedTarget) {
|
|
41
|
+
removed = true;
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
nextArgs.push(item);
|
|
46
|
+
}
|
|
47
|
+
return { args: nextArgs, removed };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function shouldPreserveAppendTarget({
|
|
51
|
+
appendTarget = "",
|
|
52
|
+
bootstrapFile = "",
|
|
53
|
+
} = {}) {
|
|
54
|
+
const append = String(appendTarget || "").trim();
|
|
55
|
+
if (!append) return false;
|
|
56
|
+
const bootstrap = String(bootstrapFile || "").trim();
|
|
57
|
+
if (!bootstrap) return fs.existsSync(append);
|
|
58
|
+
if (append === bootstrap) return false;
|
|
59
|
+
return fs.existsSync(append);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const resolved = resolveUcodeLaunch({
|
|
63
|
+
argv: process.argv.slice(2),
|
|
64
|
+
env: process.env,
|
|
65
|
+
cwd: process.cwd(),
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
if (resolved && resolved.env && typeof resolved.env === "object") {
|
|
69
|
+
for (const [key, value] of Object.entries(resolved.env)) {
|
|
70
|
+
if (!key) continue;
|
|
71
|
+
process.env[key] = String(value);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
try {
|
|
76
|
+
const runtimePrepared = prepareUcodeRuntimeConfig({
|
|
77
|
+
projectRoot: process.cwd(),
|
|
78
|
+
env: process.env,
|
|
79
|
+
});
|
|
80
|
+
if (runtimePrepared && runtimePrepared.env && typeof runtimePrepared.env === "object") {
|
|
81
|
+
for (const [key, value] of Object.entries(runtimePrepared.env)) {
|
|
82
|
+
if (!key) continue;
|
|
83
|
+
process.env[key] = String(value);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
} catch {
|
|
87
|
+
// runtime config preparation is best-effort
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
try {
|
|
91
|
+
prepareUcodeBootstrap({
|
|
92
|
+
projectRoot: process.cwd(),
|
|
93
|
+
promptFile: process.env.UFOO_UCODE_PROMPT_FILE || "",
|
|
94
|
+
targetFile: process.env.UFOO_UCODE_BOOTSTRAP_FILE || "",
|
|
95
|
+
});
|
|
96
|
+
} catch (err) {
|
|
97
|
+
const mode = String(process.env.UFOO_UCODE_APPEND_SYSTEM_PROMPT_MODE || "auto").trim().toLowerCase();
|
|
98
|
+
const bootstrapFile = String(process.env.UFOO_UCODE_BOOTSTRAP_FILE || "").trim();
|
|
99
|
+
const appendTarget = String(process.env.UFOO_UCODE_APPEND_SYSTEM_PROMPT || bootstrapFile).trim();
|
|
100
|
+
const preserveCustomAppend = shouldPreserveAppendTarget({ appendTarget, bootstrapFile });
|
|
101
|
+
if (mode !== "always" && !preserveCustomAppend) {
|
|
102
|
+
const stripped = stripAppendSystemPromptArgs(resolved.args, appendTarget);
|
|
103
|
+
resolved.args = stripped.args;
|
|
104
|
+
if (stripped.removed) {
|
|
105
|
+
console.error(`[ucode] Warning: bootstrap prepare failed; launching without --append-system-prompt (${err && err.message ? err.message : "unknown error"})`);
|
|
106
|
+
}
|
|
107
|
+
} else if (preserveCustomAppend) {
|
|
108
|
+
console.error(`[ucode] Warning: bootstrap prepare failed; preserving custom --append-system-prompt (${err && err.message ? err.message : "unknown error"})`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const mode = String(process.env.UFOO_UCODE_APPEND_SYSTEM_PROMPT_MODE || "auto").trim().toLowerCase();
|
|
113
|
+
const bootstrapFile = String(process.env.UFOO_UCODE_BOOTSTRAP_FILE || "").trim();
|
|
114
|
+
const appendTarget = String(process.env.UFOO_UCODE_APPEND_SYSTEM_PROMPT || bootstrapFile).trim();
|
|
115
|
+
const preserveCustomAppend = shouldPreserveAppendTarget({ appendTarget, bootstrapFile });
|
|
116
|
+
if (mode !== "always" && bootstrapFile && !fs.existsSync(bootstrapFile) && !preserveCustomAppend) {
|
|
117
|
+
const stripped = stripAppendSystemPromptArgs(resolved.args, appendTarget);
|
|
118
|
+
resolved.args = stripped.args;
|
|
119
|
+
if (stripped.removed) {
|
|
120
|
+
console.error("[ucode] Warning: bootstrap file missing; launching without --append-system-prompt");
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const launcher = new AgentLauncher(resolved.agentType, resolved.command);
|
|
125
|
+
launcher.launch(resolved.args);
|
package/bin/ucodex.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* ucodex: Launch Codex and auto-join event bus
|
|
4
|
+
*
|
|
5
|
+
* Usage: ucodex [codex args...]
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const AgentLauncher = require("../src/agent/launcher");
|
|
9
|
+
|
|
10
|
+
const launcher = new AgentLauncher("codex", "codex");
|
|
11
|
+
const args = process.argv.slice(2);
|
|
12
|
+
|
|
13
|
+
launcher.launch(args);
|