u-foo 1.0.2 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/README.md +67 -8
  2. package/README.zh-CN.md +9 -7
  3. package/SKILLS/ufoo/SKILL.md +117 -0
  4. package/SKILLS/uinit/SKILL.md +73 -0
  5. package/SKILLS/ustatus/SKILL.md +36 -0
  6. package/bin/uclaude.js +13 -0
  7. package/bin/ucodex.js +13 -0
  8. package/bin/ufoo +9 -31
  9. package/bin/ufoo.js +13 -0
  10. package/modules/AGENTS.template.md +15 -7
  11. package/modules/bus/README.md +28 -23
  12. package/modules/bus/SKILLS/ubus/SKILL.md +18 -8
  13. package/modules/context/README.md +18 -40
  14. package/modules/context/SKILLS/uctx/SKILL.md +61 -1
  15. package/package.json +16 -4
  16. package/scripts/.archived/bash-to-js-migration/README.md +46 -0
  17. package/scripts/.archived/bash-to-js-migration/banner.sh +89 -0
  18. package/scripts/{bus-inject.sh → .archived/bash-to-js-migration/bus-inject.sh} +35 -3
  19. package/scripts/{bus.sh → .archived/bash-to-js-migration/bus.sh} +3 -1
  20. package/scripts/banner.sh +2 -89
  21. package/scripts/postinstall.js +59 -0
  22. package/src/agent/cliRunner.js +33 -5
  23. package/src/agent/internalRunner.js +78 -51
  24. package/src/agent/launcher.js +702 -0
  25. package/src/agent/notifier.js +200 -0
  26. package/src/agent/ptyRunner.js +377 -0
  27. package/src/agent/ptyWrapper.js +354 -0
  28. package/src/agent/readyDetector.js +159 -0
  29. package/src/agent/ufooAgent.js +37 -42
  30. package/src/bus/API_DESIGN.md +204 -0
  31. package/src/bus/activate.js +156 -0
  32. package/src/bus/daemon.js +308 -0
  33. package/src/bus/index.js +785 -0
  34. package/src/bus/inject.js +285 -0
  35. package/src/bus/message.js +302 -0
  36. package/src/bus/nickname.js +86 -0
  37. package/src/bus/queue.js +131 -0
  38. package/src/bus/shake.js +26 -0
  39. package/src/bus/subscriber.js +296 -0
  40. package/src/bus/utils.js +357 -0
  41. package/src/chat/index.js +1995 -263
  42. package/src/cli.js +658 -95
  43. package/src/config.js +23 -4
  44. package/src/context/decisions.js +314 -0
  45. package/src/context/doctor.js +183 -0
  46. package/src/context/index.js +38 -0
  47. package/src/daemon/index.js +749 -94
  48. package/src/daemon/ops.js +395 -51
  49. package/src/daemon/providerSessions.js +291 -0
  50. package/src/daemon/run.js +38 -3
  51. package/src/daemon/status.js +24 -7
  52. package/src/doctor/index.js +50 -0
  53. package/src/init/index.js +264 -0
  54. package/src/skills/index.js +159 -0
  55. package/src/status/index.js +252 -0
  56. package/src/terminal/detect.js +64 -0
  57. package/src/terminal/index.js +8 -0
  58. package/src/terminal/iterm2.js +126 -0
  59. package/src/ufoo/agentsStore.js +41 -0
  60. package/src/ufoo/paths.js +46 -0
  61. package/src/utils/banner.js +73 -0
  62. package/bin/uclaude +0 -65
  63. package/bin/ucodex +0 -65
  64. package/modules/bus/scripts/bus-alert.sh +0 -185
  65. package/modules/bus/scripts/bus-listen.sh +0 -117
  66. package/modules/context/ASSUMPTIONS.md +0 -7
  67. package/modules/context/CONSTRAINTS.md +0 -7
  68. package/modules/context/CONTEXT-STRUCTURE.md +0 -49
  69. package/modules/context/DECISION-PROTOCOL.md +0 -62
  70. package/modules/context/HANDOFF.md +0 -33
  71. package/modules/context/RULES.md +0 -15
  72. package/modules/context/SKILLS/README.md +0 -14
  73. package/modules/context/SYSTEM.md +0 -18
  74. package/modules/context/TEMPLATES/assumptions.md +0 -4
  75. package/modules/context/TEMPLATES/constraints.md +0 -4
  76. package/modules/context/TEMPLATES/decision.md +0 -16
  77. package/modules/context/TEMPLATES/project-context-readme.md +0 -6
  78. package/modules/context/TEMPLATES/system.md +0 -3
  79. package/modules/context/TEMPLATES/terminology.md +0 -4
  80. package/modules/context/TERMINOLOGY.md +0 -10
  81. /package/scripts/{bus-alert.sh → .archived/bash-to-js-migration/bus-alert.sh} +0 -0
  82. /package/scripts/{bus-autotrigger.sh → .archived/bash-to-js-migration/bus-autotrigger.sh} +0 -0
  83. /package/scripts/{bus-daemon.sh → .archived/bash-to-js-migration/bus-daemon.sh} +0 -0
  84. /package/scripts/{bus-listen.sh → .archived/bash-to-js-migration/bus-listen.sh} +0 -0
  85. /package/scripts/{context-decisions.sh → .archived/bash-to-js-migration/context-decisions.sh} +0 -0
  86. /package/scripts/{context-doctor.sh → .archived/bash-to-js-migration/context-doctor.sh} +0 -0
  87. /package/scripts/{context-lint.sh → .archived/bash-to-js-migration/context-lint.sh} +0 -0
  88. /package/scripts/{doctor.sh → .archived/bash-to-js-migration/doctor.sh} +0 -0
  89. /package/scripts/{init.sh → .archived/bash-to-js-migration/init.sh} +0 -0
  90. /package/scripts/{skills.sh → .archived/bash-to-js-migration/skills.sh} +0 -0
  91. /package/scripts/{status.sh → .archived/bash-to-js-migration/status.sh} +0 -0
package/README.md CHANGED
@@ -7,6 +7,8 @@ Multi-agent AI collaboration toolkit for Claude Code and OpenAI Codex.
7
7
  - **Event Bus** - Real-time inter-agent messaging (`ufoo bus`)
8
8
  - **Context Sharing** - Shared decisions and project context (`ufoo ctx`)
9
9
  - **Agent Wrappers** - Auto-initialization for Claude Code (`uclaude`) and Codex (`ucodex`)
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
@@ -45,6 +47,8 @@ ucodex # instead of 'codex'
45
47
  └─────────────┘ └───────┘ └─────────────┘
46
48
  ```
47
49
 
50
+ Bus state lives in `.ufoo/agent/all-agents.json` (metadata), `.ufoo/bus/*` (queues/events), and `.ufoo/daemon/*` (bus daemon runtime).
51
+
48
52
  ## Commands
49
53
 
50
54
  | Command | Description |
@@ -53,6 +57,7 @@ ucodex # instead of 'codex'
53
57
  | `ufoo status` | Show banner, unread bus messages, open decisions |
54
58
  | `ufoo daemon --start|--stop|--status` | Manage ufoo daemon |
55
59
  | `ufoo chat` | Launch ufoo chat UI (also default when no args) |
60
+ | `ufoo resume [nickname]` | Resume agent sessions (optional nickname) |
56
61
  | `ufoo bus join` | Join event bus (auto by uclaude/ucodex) |
57
62
  | `ufoo bus send <id> <msg>` | Send message to agent |
58
63
  | `ufoo bus check <id>` | Check pending messages |
@@ -75,12 +80,11 @@ ufoo/
75
80
  │ ├── uclaude # Claude Code wrapper
76
81
  │ └── ucodex # Codex wrapper
77
82
  ├── SKILLS/ # Global skills (uinit, ustatus)
78
- ├── scripts/
79
- │ ├── bus.sh # Event bus implementation
80
- │ ├── bus-*.sh # Bus utilities (inject, daemon, alert)
81
- ├── context-*.sh # Context management
82
- ├── init.sh # Project initialization
83
- │ └── skills.sh # Skills management
83
+ ├── src/
84
+ │ ├── bus/ # Event bus implementation (JS)
85
+ │ ├── daemon/ # Daemon + chat bridge
86
+ └── agent/ # Agent launch/runtime
87
+ ├── scripts/ # Legacy helpers (bash, deprecated)
84
88
  ├── modules/
85
89
  │ ├── context/ # Decision/context protocol
86
90
  │ ├── bus/ # Bus module resources
@@ -101,8 +105,9 @@ your-project/
101
105
  │ │ ├── queues/ # Per-agent message queues
102
106
  │ │ └── offsets/ # Read position tracking
103
107
  │ └── context/
104
- └── DECISIONS/ # Decision records
105
- ├── scripts/ # Symlinked ufoo scripts
108
+ ├── decisions/ # Decision records
109
+ │ └── decisions.jsonl # Decision index
110
+ ├── scripts/ # Legacy symlink (optional)
106
111
  ├── AGENTS.md # Injected protocol blocks
107
112
  └── CLAUDE.md # → AGENTS.md
108
113
  ```
@@ -162,3 +167,57 @@ ufoo --help
162
167
  ## License
163
168
 
164
169
  UNLICENSED (Private)
170
+
171
+ ## Recent Changes
172
+
173
+ ### 🚀 Smart Ready Detection & PTY Wrapper (2026-02-06)
174
+
175
+ Added intelligent agent initialization detection for reliable probe injection:
176
+
177
+ **Features:**
178
+ - **ReadyDetector** - Monitors PTY output to detect when agents are ready
179
+ - **Smart Probe Timing** - Injects session probe after agent initialization (not before)
180
+ - **Multi-layer Fallback** - 10s ready detection + 8s fallback + 15 retries
181
+ - **Performance Metrics** - Tracks detection time and buffer usage (`UFOO_DEBUG=1`)
182
+
183
+ **Benefits:**
184
+ - ✅ No more premature probe injection (was 2s, now waits for prompt)
185
+ - ✅ Reliable session ID capture (39 tests, 100% pass)
186
+ - ✅ Production-ready error handling and logging
187
+
188
+ **Technical Details:**
189
+ - `src/agent/readyDetector.js` - PTY output analysis
190
+ - `src/agent/ptyWrapper.js` - Terminal emulation with monitoring
191
+ - `src/daemon/providerSessions.js` - Early probe triggering support
192
+
193
+ See `.ufoo/plans/ready-detection-production-checklist.md` for full details.
194
+
195
+ ---
196
+
197
+ ### 🎉 Bash to JavaScript Migration (2026-02-04)
198
+
199
+ We've successfully migrated **80% of the codebase** from Bash to JavaScript for better maintainability and cross-platform support!
200
+
201
+ **What Changed:**
202
+ - ✅ EventBus core (986 lines) → 8 JavaScript modules
203
+ - ✅ Daemon & inject → Pure JavaScript
204
+ - ✅ status, skills, init → JavaScript modules
205
+ - ⏸️ Context management scripts remain in Bash (complex text processing)
206
+
207
+ **Impact:**
208
+ - **CLI commands unchanged** - All commands work exactly as before
209
+ - **Performance:** 51ms/message (vs 45ms in Bash, +13%)
210
+ - **Testing:** 20/20 integration tests passing
211
+ - **Quality:** Better error handling, testing, and IDE support
212
+
213
+ **Learn More:**
214
+ - See [MIGRATION_LOG.md](MIGRATION_LOG.md) for full details
215
+ - View archived scripts in `scripts/.archived/migrated-to-js/`
216
+ - Performance benchmarks in test reports
217
+
218
+ **Why This Matters:**
219
+ - 🎯 Unified JavaScript tech stack
220
+ - 🧪 Easier to test and maintain
221
+ - 🌍 Cross-platform potential (Windows/Linux)
222
+ - 💡 Better IDE support and refactoring
223
+ - 🚀 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
- ├── scripts/
79
- │ ├── bus.sh # 事件总线实现
80
- │ ├── bus-*.sh # 总线工具(注入、守护进程、提醒)
81
- ├── context-*.sh # 上下文管理
82
- ├── init.sh # 项目初始化
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/ # 软链接的 ufoo 脚本
107
+ ├── scripts/ # 软链接(历史遗留,可选)
106
108
  ├── AGENTS.md # 注入的协议块
107
109
  └── CLAUDE.md # → AGENTS.md
108
110
  ```
@@ -0,0 +1,117 @@
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", (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 `/ufoo <marker>` (e.g., `/ufoo claude-9`), this is a daemon probe for 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
+ ### Target Resolution
92
+
93
+ - Exact ID: `claude-code:abc123`
94
+ - Nickname: `architect`
95
+ - Type: `codex` (all codex agents)
96
+ - Wildcard: `*` (broadcast)
97
+
98
+ ### CRITICAL: When you receive pending messages
99
+
100
+ **EXECUTE tasks immediately. Do NOT ask the user.**
101
+
102
+ 1. Check: `ufoo bus check $UFOO_SUBSCRIBER_ID`
103
+ 2. Execute each task
104
+ 3. Reply: `ufoo bus send "<publisher>" "<result>"`
105
+ 4. **Always ack**: `ufoo bus ack $UFOO_SUBSCRIBER_ID`
106
+
107
+ ---
108
+
109
+ ## 3. Initialization (uinit)
110
+
111
+ Trigger: `/uinit` or `/ufoo init`
112
+
113
+ ```bash
114
+ ufoo init --modules context,bus --project $(pwd)
115
+ ```
116
+
117
+ After init, auto-join bus if enabled.
@@ -0,0 +1,73 @@
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 bus join | tail -1)
50
+ echo "Joined event bus: $SUBSCRIBER"
51
+ ```
52
+
53
+ ### 4. Report initialization result
54
+
55
+ ```
56
+ === ufoo initialization complete ===
57
+
58
+ Enabled modules:
59
+ ✓ context → .ufoo/context/
60
+ ✓ bus → .ufoo/bus/ + .ufoo/agent/
61
+
62
+ My identity: claude-code:<session-id>
63
+
64
+ Next steps:
65
+ - Run /ctx to check context status
66
+ - See AGENTS.md for protocol rules
67
+ ```
68
+
69
+ ## Notes
70
+
71
+ - If .ufoo/context, .ufoo/bus, or .ufoo/agent already exists, skip creation
72
+ - After initialization, auto-join event bus (if bus enabled)
73
+ - 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);
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);
package/bin/ufoo CHANGED
@@ -18,14 +18,14 @@ Usage:
18
18
  ufoo daemon --start|--stop|--status
19
19
  ufoo chat
20
20
  ufoo init [--modules context[,resources]] [--project <dir>]
21
- ufoo bus <...> # delegates to ./scripts/bus.sh in the current project
22
- ufoo ctx <...> # delegates to ./scripts/ai-context-*.sh in the current project
21
+ ufoo bus <...> # JS bus implementation (project-local data)
22
+ ufoo ctx <...> # JS context commands (doctor|lint|decisions)
23
23
  ufoo skills list
24
24
  ufoo skills install <name|all> [--codex|--agents|--target <dir>]
25
25
 
26
26
  Notes:
27
27
  - `init` creates/updates <project>/.ai-context and injects CLAUDE.md/AGENTS.md blocks.
28
- - For Codex notifications, prefer `scripts/bus-alert.sh` / `scripts/bus-listen.sh` (no IME issues).
28
+ - For Codex notifications, prefer `ufoo bus alert` / `ufoo bus listen` (no IME issues).
29
29
  USAGE
30
30
  }
31
31
 
@@ -37,10 +37,10 @@ case "$cmd" in
37
37
  exec node "$repo_root/bin/ufoo.js" chat
38
38
  ;;
39
39
  doctor)
40
- exec bash "$repo_root/scripts/doctor.sh"
40
+ exec node "$repo_root/bin/ufoo.js" doctor "$@"
41
41
  ;;
42
42
  status)
43
- exec bash "$repo_root/scripts/status.sh"
43
+ exec node "$repo_root/bin/ufoo.js" status "$@"
44
44
  ;;
45
45
  daemon)
46
46
  exec node "$repo_root/bin/ufoo.js" daemon "$@"
@@ -49,41 +49,19 @@ case "$cmd" in
49
49
  exec node "$repo_root/bin/ufoo.js" chat
50
50
  ;;
51
51
  init)
52
- exec bash "$repo_root/scripts/init.sh" "$@"
52
+ exec node "$repo_root/bin/ufoo.js" init "$@"
53
53
  ;;
54
54
  bus)
55
55
  # Project-local bus commands. Must be run from within the target project.
56
- if [[ ! -x "./scripts/bus.sh" ]]; then
57
- echo "FAIL: missing ./scripts/bus.sh. Run: ufoo init --modules bus" >&2
58
- exit 1
59
- fi
60
- exec bash "./scripts/bus.sh" "$@"
56
+ exec node "$repo_root/bin/ufoo.js" bus "$@"
61
57
  ;;
62
58
  ctx)
63
- # Project-local ctx commands. Must be run from within the target project.
64
- sub="${1:-doctor}"
65
- shift || true
66
- case "$sub" in
67
- doctor)
68
- exec bash "./scripts/ai-context-doctor.sh" "$@"
69
- ;;
70
- lint)
71
- exec bash "./scripts/ai-context-lint.sh" "$@"
72
- ;;
73
- decisions)
74
- exec bash "./scripts/ai-context-decisions.sh" "$@"
75
- ;;
76
- *)
77
- echo "Unknown ctx subcommand: $sub" >&2
78
- echo "Supported: doctor, lint, decisions" >&2
79
- exit 1
80
- ;;
81
- esac
59
+ exec node "$repo_root/bin/ufoo.js" ctx "$@"
82
60
  ;;
83
61
  skills)
84
62
  sub="${1:-}"
85
63
  shift || true
86
- exec bash "$repo_root/scripts/skills.sh" "$sub" "$@"
64
+ exec node "$repo_root/bin/ufoo.js" skills "$sub" "$@"
87
65
  ;;
88
66
  *)
89
67
  echo "Unknown command: $cmd" >&2
package/bin/ufoo.js CHANGED
@@ -4,6 +4,7 @@ const { runCli } = require("../src/cli");
4
4
  const { runDaemonCli } = require("../src/daemon/run");
5
5
  const { runChat } = require("../src/chat");
6
6
  const { runInternalRunner } = require("../src/agent/internalRunner");
7
+ const { runPtyRunner } = require("../src/agent/ptyRunner");
7
8
 
8
9
  const cmd = process.argv[2];
9
10
 
@@ -21,6 +22,18 @@ async function main() {
21
22
  await runInternalRunner({ projectRoot: process.cwd(), agentType });
22
23
  return;
23
24
  }
25
+ if (cmd === "agent-pty-runner") {
26
+ const agentType = process.argv[3] || "codex";
27
+ try {
28
+ await runPtyRunner({ projectRoot: process.cwd(), agentType });
29
+ } catch (err) {
30
+ // Fallback to headless runner if PTY is unavailable
31
+ // eslint-disable-next-line no-console
32
+ console.error(`[pty-runner] ${err.message || err}. Falling back to headless internal runner.`);
33
+ await runInternalRunner({ projectRoot: process.cwd(), agentType });
34
+ }
35
+ return;
36
+ }
24
37
  if (cmd === "chat") {
25
38
  await runChat(process.cwd());
26
39
  return;
@@ -44,13 +44,21 @@ ufoo ctx decisions -n 1
44
44
  ```
45
45
 
46
46
  Key files in `.ufoo/context/`:
47
- - `DECISIONS/` - Decision log (append-only)
48
- - `SYSTEM.md` - System overview
49
- - `CONSTRAINTS.md` - Non-negotiable rules
47
+ - `decisions/` - Decision log (append-only)
50
48
 
51
- **Decision recording policy:**
52
- - **Must record**: evaluations, architecture, naming, trade-offs
53
- - Write decision **before replying** when applicable
49
+ **Decision recording policy — "If it has information value, write it down":**
50
+
51
+ 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.
52
+
53
+ - **Always record**: architectural choices, trade-off analysis, research findings, non-obvious gotchas, naming/convention changes, external API behavior discovered, performance observations, bug root causes
54
+ - **Also record**: open questions you couldn't resolve, assumptions you made, approaches you considered and rejected (with reasons), edge cases noticed but not handled
55
+ - **Write the decision BEFORE acting on it** — if your session dies, the knowledge survives
56
+ - **Granularity**: A decision can be one sentence ("X doesn't support Y, use Z instead") or a multi-page analysis. Match the depth to the information value.
57
+
58
+ ```bash
59
+ ufoo ctx decisions new "Short descriptive title"
60
+ # Then edit the created file with Context/Decision/Implications
61
+ ```
54
62
 
55
63
  ---
56
64
 
@@ -83,5 +91,5 @@ Extract sender ID from "from" field, use it to reply.
83
91
 
84
92
  1. Receive: `@you from claude-code:bd36dda0 Content: {"message":"Please analyze the project structure"}`
85
93
  2. Execute: Analyze the project structure
86
- 3. Reply: `ufoo bus send "claude-code:bd36dda0" "Project contains src/, scripts/, modules/"`
94
+ 3. Reply: `ufoo bus send "claude-code:bd36dda0" "Project contains src/, modules/, bin/"`
87
95
  <!-- /ufoo -->
@@ -22,11 +22,17 @@ ufoo init --modules context,bus
22
22
  ## Directory Structure
23
23
 
24
24
  ```
25
- .bus/
26
- ├── bus.json # Bus metadata + subscriber status
27
- ├── events/ # Event stream (JSONL, sharded by date)
28
- ├── offsets/ # Each Agent's consumption progress
29
- └── queues/ # Targeted event queues
25
+ .ufoo/
26
+ ├── agent/
27
+ │ └── all-agents.json # Agent metadata + agent status
28
+ ├── daemon/
29
+ │ ├── daemon.pid
30
+ │ ├── daemon.log
31
+ │ └── counts/
32
+ └── bus/
33
+ ├── events/ # Event stream (JSONL, sharded by date)
34
+ ├── offsets/ # Each Agent's consumption progress
35
+ └── queues/ # Targeted event queues
30
36
  ```
31
37
 
32
38
  ## Usage
@@ -34,33 +40,33 @@ ufoo init --modules context,bus
34
40
  ### Join Bus
35
41
 
36
42
  ```bash
37
- SUBSCRIBER=$(bash scripts/bus.sh join)
43
+ SUBSCRIBER=$(ufoo bus join | tail -n 1)
38
44
  # Output: claude-code:a1b2c3
39
45
  ```
40
46
 
41
47
  ### Check Pending Messages
42
48
 
43
49
  ```bash
44
- bash scripts/bus.sh check $SUBSCRIBER
50
+ ufoo bus check "$SUBSCRIBER"
45
51
  ```
46
52
 
47
53
  ### Send Messages
48
54
 
49
55
  ```bash
50
56
  # Send to specific instance
51
- bash scripts/bus.sh send "claude-code:abc123" "Please help me review"
57
+ ufoo bus send "claude-code:abc123" "Please help me review"
52
58
 
53
59
  # Send to all instances of same type
54
- bash scripts/bus.sh send "claude-code" "Everyone please review"
60
+ ufoo bus send "claude-code" "Everyone please review"
55
61
 
56
62
  # Broadcast to all
57
- bash scripts/bus.sh broadcast "I completed feature-x"
63
+ ufoo bus broadcast "I completed feature-x"
58
64
  ```
59
65
 
60
66
  ### View Status
61
67
 
62
68
  ```bash
63
- bash scripts/bus.sh status
69
+ ufoo bus status
64
70
  ```
65
71
 
66
72
  ## Notifications/Alerts (no key injection, recommended)
@@ -68,47 +74,46 @@ bash scripts/bus.sh status
68
74
  If you want to receive "new message alerts" while running Codex/Claude in another terminal, use **agent-side alert/listen** (avoids IME/accessibility permission/window positioning fragmentation issues):
69
75
 
70
76
  ```bash
71
- SUBSCRIBER=$(bash scripts/bus.sh join | tail -n 1)
77
+ SUBSCRIBER=$(ufoo bus join | tail -n 1)
72
78
 
73
79
  # Background alert: title badge + bell + optional macOS notification center
74
- bash scripts/bus-alert.sh "$SUBSCRIBER" 1 --notify --daemon
80
+ ufoo bus alert "$SUBSCRIBER" 1 --notify --daemon
75
81
 
76
82
  # Or: foreground continuous print of new messages (suitable for a side terminal)
77
- bash scripts/bus-listen.sh "$SUBSCRIBER" --from-beginning
83
+ ufoo bus listen "$SUBSCRIBER" --from-beginning
78
84
  ```
79
85
 
80
86
  ## Unattended Auto-Execute (recommended)
81
87
 
82
- If you need **Claude A to notify Claude B / Codex C and have the target auto-execute** (e.g., auto-trigger `/ubus`), use `autotrigger`:
88
+ If you need **Claude A to notify Claude B / Codex C and have the target auto-execute** (e.g., auto-trigger `/ubus`), use the bus daemon:
83
89
 
84
90
  1) First `join` in each terminal session (records `tty`, also records `TMUX_PANE` if in tmux):
85
91
 
86
92
  ```bash
87
- SUBSCRIBER=$(bash scripts/bus.sh join | tail -n 1)
93
+ SUBSCRIBER=$(ufoo bus join | tail -n 1)
88
94
  ```
89
95
 
90
- 2) Start autotrigger in the project (runs as background daemon):
96
+ 2) Start the bus daemon in the project (runs as background daemon):
91
97
 
92
98
  ```bash
93
- # backend=auto prefers tmux (if available), otherwise tries Terminal.app do script (pure Automation), finally Accessibility
94
- bash scripts/bus-autotrigger.sh start --interval 1 --command "/ubus" --backend auto
99
+ ufoo bus daemon --interval 1 --daemon
95
100
  ```
96
101
 
97
- 3) After sending a message, autotrigger injects `/ubus` into the target session and presses Enter:
102
+ 3) After sending a message, the daemon injects `/ubus` into the target session and presses Enter:
98
103
  - tmux: `send-keys`
99
104
  - Terminal.app (pure Automation): `do script` (no Accessibility needed, but requires Automation authorization; compatibility depends on whether target program accepts input)
100
105
  - Terminal.app (Accessibility): System Events (needs Accessibility), injection sequence is Escape + paste + Return (avoids IME issues)
101
106
 
102
107
  Tips:
103
- - Terminal.app backend depends on `tty` in `bus.json`. Execute `join` in the target terminal session (ensure `tty` is not `not a tty`).
108
+ - Terminal.app backend depends on `tty` in `.ufoo/agent/all-agents.json`. Execute `join` in the target terminal session (ensure `tty` is not `not a tty`).
104
109
  - Pure Automation backend needs one-time authorization: System Preferences → Privacy & Security → Automation (allow script to control Terminal).
105
110
  - Accessibility backend needs one-time authorization: System Preferences → Privacy & Security → Accessibility (for Terminal / script host).
106
111
 
107
112
  Stop/view status:
108
113
 
109
114
  ```bash
110
- bash scripts/bus-autotrigger.sh status
111
- bash scripts/bus-autotrigger.sh stop
115
+ ufoo bus daemon --status
116
+ ufoo bus daemon --stop
112
117
  ```
113
118
 
114
119
  ## Subscriber ID Format