u-foo 1.0.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.
Files changed (77) hide show
  1. package/LICENSE +35 -0
  2. package/README.md +163 -0
  3. package/README.zh-CN.md +163 -0
  4. package/bin/uclaude +65 -0
  5. package/bin/ucodex +65 -0
  6. package/bin/ufoo +93 -0
  7. package/bin/ufoo.js +35 -0
  8. package/modules/AGENTS.template.md +87 -0
  9. package/modules/bus/README.md +132 -0
  10. package/modules/bus/SKILLS/ubus/SKILL.md +209 -0
  11. package/modules/bus/scripts/bus-alert.sh +185 -0
  12. package/modules/bus/scripts/bus-listen.sh +117 -0
  13. package/modules/context/ASSUMPTIONS.md +7 -0
  14. package/modules/context/CONSTRAINTS.md +7 -0
  15. package/modules/context/CONTEXT-STRUCTURE.md +49 -0
  16. package/modules/context/DECISION-PROTOCOL.md +62 -0
  17. package/modules/context/HANDOFF.md +33 -0
  18. package/modules/context/README.md +82 -0
  19. package/modules/context/RULES.md +15 -0
  20. package/modules/context/SKILLS/README.md +14 -0
  21. package/modules/context/SKILLS/uctx/SKILL.md +91 -0
  22. package/modules/context/SYSTEM.md +18 -0
  23. package/modules/context/TEMPLATES/assumptions.md +4 -0
  24. package/modules/context/TEMPLATES/constraints.md +4 -0
  25. package/modules/context/TEMPLATES/decision.md +16 -0
  26. package/modules/context/TEMPLATES/project-context-readme.md +6 -0
  27. package/modules/context/TEMPLATES/system.md +3 -0
  28. package/modules/context/TEMPLATES/terminology.md +4 -0
  29. package/modules/context/TERMINOLOGY.md +10 -0
  30. package/modules/resources/ICONS/README.md +12 -0
  31. package/modules/resources/ICONS/libraries/README.md +17 -0
  32. package/modules/resources/ICONS/libraries/heroicons/LICENSE +22 -0
  33. package/modules/resources/ICONS/libraries/heroicons/README.md +15 -0
  34. package/modules/resources/ICONS/libraries/heroicons/arrow-right.svg +4 -0
  35. package/modules/resources/ICONS/libraries/heroicons/check.svg +4 -0
  36. package/modules/resources/ICONS/libraries/heroicons/chevron-down.svg +4 -0
  37. package/modules/resources/ICONS/libraries/heroicons/cog-6-tooth.svg +5 -0
  38. package/modules/resources/ICONS/libraries/heroicons/magnifying-glass.svg +4 -0
  39. package/modules/resources/ICONS/libraries/heroicons/x-mark.svg +4 -0
  40. package/modules/resources/ICONS/libraries/lucide/LICENSE +40 -0
  41. package/modules/resources/ICONS/libraries/lucide/README.md +15 -0
  42. package/modules/resources/ICONS/libraries/lucide/arrow-right.svg +15 -0
  43. package/modules/resources/ICONS/libraries/lucide/check.svg +14 -0
  44. package/modules/resources/ICONS/libraries/lucide/chevron-down.svg +14 -0
  45. package/modules/resources/ICONS/libraries/lucide/search.svg +15 -0
  46. package/modules/resources/ICONS/libraries/lucide/settings.svg +15 -0
  47. package/modules/resources/ICONS/libraries/lucide/x.svg +15 -0
  48. package/modules/resources/ICONS/rules.md +7 -0
  49. package/modules/resources/README.md +9 -0
  50. package/modules/resources/UI/ANTI-PATTERNS.md +6 -0
  51. package/modules/resources/UI/TONE.md +6 -0
  52. package/package.json +40 -0
  53. package/scripts/banner.sh +89 -0
  54. package/scripts/bus-alert.sh +6 -0
  55. package/scripts/bus-autotrigger.sh +6 -0
  56. package/scripts/bus-daemon.sh +231 -0
  57. package/scripts/bus-inject.sh +144 -0
  58. package/scripts/bus-listen.sh +6 -0
  59. package/scripts/bus.sh +984 -0
  60. package/scripts/context-decisions.sh +167 -0
  61. package/scripts/context-doctor.sh +72 -0
  62. package/scripts/context-lint.sh +110 -0
  63. package/scripts/doctor.sh +22 -0
  64. package/scripts/init.sh +247 -0
  65. package/scripts/skills.sh +113 -0
  66. package/scripts/status.sh +125 -0
  67. package/src/agent/cliRunner.js +190 -0
  68. package/src/agent/internalRunner.js +212 -0
  69. package/src/agent/normalizeOutput.js +41 -0
  70. package/src/agent/ufooAgent.js +222 -0
  71. package/src/chat/index.js +1603 -0
  72. package/src/cli.js +349 -0
  73. package/src/config.js +37 -0
  74. package/src/daemon/index.js +501 -0
  75. package/src/daemon/ops.js +120 -0
  76. package/src/daemon/run.js +41 -0
  77. package/src/daemon/status.js +78 -0
package/LICENSE ADDED
@@ -0,0 +1,35 @@
1
+ UFOO Software License Agreement
2
+ Version 1.0, February 2026
3
+
4
+ Copyright (c) 2026 UFOO Team. All rights reserved.
5
+
6
+ TERMS AND CONDITIONS
7
+
8
+ 1. GRANT OF LICENSE
9
+ You are granted a non-exclusive, non-transferable license to use this
10
+ software for personal and internal business purposes only.
11
+
12
+ 2. RESTRICTIONS
13
+ You may NOT:
14
+ - Redistribute, sell, lease, or sublicense this software
15
+ - Modify, reverse engineer, or create derivative works
16
+ - Remove or alter any proprietary notices or labels
17
+ - Use this software to build competing products or services
18
+
19
+ 3. COMMERCIAL USE
20
+ Commercial use requires a separate commercial license.
21
+ Contact: license@ufoo.dev
22
+
23
+ 4. NO WARRANTY
24
+ THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
25
+ USE AT YOUR OWN RISK.
26
+
27
+ 5. LIMITATION OF LIABILITY
28
+ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DAMAGES ARISING
29
+ FROM THE USE OF THIS SOFTWARE.
30
+
31
+ 6. TERMINATION
32
+ This license terminates automatically if you violate any terms.
33
+ Upon termination, you must destroy all copies of the software.
34
+
35
+ For licensing inquiries: https://ufoo.dev
package/README.md ADDED
@@ -0,0 +1,163 @@
1
+ # ufoo
2
+
3
+ Multi-agent AI collaboration toolkit for Claude Code and OpenAI Codex.
4
+
5
+ ## Features
6
+
7
+ - **Event Bus** - Real-time inter-agent messaging (`ufoo bus`)
8
+ - **Context Sharing** - Shared decisions and project context (`ufoo ctx`)
9
+ - **Agent Wrappers** - Auto-initialization for Claude Code (`uclaude`) and Codex (`ucodex`)
10
+ - **Skills System** - Extensible agent capabilities (`ufoo skills`)
11
+
12
+ ## Quick Start
13
+
14
+ ```bash
15
+ # Clone and link globally
16
+ git clone <repo> ~/.ufoo
17
+ cd ~/.ufoo && npm link
18
+
19
+ # Initialize a project
20
+ cd your-project
21
+ ufoo init
22
+
23
+ # Or use agent wrappers (auto-init + bus join)
24
+ uclaude # instead of 'claude'
25
+ ucodex # instead of 'codex'
26
+ ```
27
+
28
+ ## Architecture
29
+
30
+ ```
31
+ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
32
+ │ uclaude │ │ ucodex │ │ other... │
33
+ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘
34
+ │ │ │
35
+ └───────────────────┼───────────────────┘
36
+
37
+ ┌──────▼──────┐
38
+ │ ufoo bus │ Event Bus
39
+ └──────┬──────┘
40
+
41
+ ┌────────────┼────────────┐
42
+ │ │ │
43
+ ┌──────▼──────┐ ┌───▼───┐ ┌──────▼──────┐
44
+ │ .ufoo/bus │ │context│ │ decisions │
45
+ └─────────────┘ └───────┘ └─────────────┘
46
+ ```
47
+
48
+ ## Commands
49
+
50
+ | Command | Description |
51
+ |---------|-------------|
52
+ | `ufoo init` | Initialize .ufoo in current project |
53
+ | `ufoo status` | Show banner, unread bus messages, open decisions |
54
+ | `ufoo daemon --start|--stop|--status` | Manage ufoo daemon |
55
+ | `ufoo chat` | Launch ufoo chat UI (also default when no args) |
56
+ | `ufoo bus join` | Join event bus (auto by uclaude/ucodex) |
57
+ | `ufoo bus send <id> <msg>` | Send message to agent |
58
+ | `ufoo bus check <id>` | Check pending messages |
59
+ | `ufoo bus status` | Show bus status |
60
+ | `ufoo ctx decisions -l` | List all decisions |
61
+ | `ufoo ctx decisions -n 1` | Show latest decision |
62
+ | `ufoo skills list` | List available skills |
63
+ | `ufoo doctor` | Check installation health |
64
+
65
+ Notes:
66
+ - Claude CLI headless agent uses `--dangerously-skip-permissions`.
67
+
68
+ ## Project Structure
69
+
70
+ ```
71
+ ufoo/
72
+ ├── bin/
73
+ │ ├── ufoo # Main CLI entry (bash)
74
+ │ ├── ufoo.js # Node wrapper
75
+ │ ├── uclaude # Claude Code wrapper
76
+ │ └── ucodex # Codex wrapper
77
+ ├── 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
84
+ ├── modules/
85
+ │ ├── context/ # Decision/context protocol
86
+ │ ├── bus/ # Bus module resources
87
+ │ └── resources/ # UI/icons (optional)
88
+ ├── AGENTS.md # Project instructions (canonical)
89
+ └── CLAUDE.md # Points to AGENTS.md
90
+ ```
91
+
92
+ ## Per-Project Layout
93
+
94
+ After `ufoo init`, your project gets:
95
+
96
+ ```
97
+ your-project/
98
+ ├── .ufoo/
99
+ │ ├── bus/
100
+ │ │ ├── events/ # Event log (append-only)
101
+ │ │ ├── queues/ # Per-agent message queues
102
+ │ │ └── offsets/ # Read position tracking
103
+ │ └── context/
104
+ │ └── DECISIONS/ # Decision records
105
+ ├── scripts/ # Symlinked ufoo scripts
106
+ ├── AGENTS.md # Injected protocol blocks
107
+ └── CLAUDE.md # → AGENTS.md
108
+ ```
109
+
110
+ ## Agent Communication
111
+
112
+ Agents communicate via the event bus:
113
+
114
+ ```bash
115
+ # Agent A sends task to Agent B
116
+ ufoo bus send "codex:abc123" "Please analyze the project structure"
117
+
118
+ # Agent B checks and executes
119
+ ufoo bus check "codex:abc123"
120
+ # → Executes task automatically
121
+ # → Replies with result
122
+ ufoo bus send "claude-code:xyz789" "分析完成:..."
123
+ ```
124
+
125
+ ## Skills (for Agents)
126
+
127
+ Built-in skills triggered by slash commands:
128
+
129
+ - `/ubus` - Check and auto-execute pending messages
130
+ - `/uctx` - Quick context status check
131
+ - `/ustatus` - Unified status view (banner, unread bus, open decisions)
132
+ - `/uinit` - Manual .ufoo initialization
133
+
134
+ ## Requirements
135
+
136
+ - macOS (for Terminal.app/iTerm2 injection features)
137
+ - Node.js >= 18 (optional, for npm global install)
138
+ - Bash 4+
139
+
140
+ ## Codex CLI Notes
141
+
142
+ If Codex CLI fails with permission errors under `~/.codex` (e.g. sessions dir), set `CODEX_HOME` to a writable path before starting the daemon/chat:
143
+
144
+ ```bash
145
+ export CODEX_HOME="$PWD/.ufoo/codex"
146
+ ufoo daemon start
147
+ ufoo chat
148
+ ```
149
+
150
+ ## Development
151
+
152
+ ```bash
153
+ # Local development
154
+ ./bin/ufoo --help
155
+
156
+ # Or via Node
157
+ npm link
158
+ ufoo --help
159
+ ```
160
+
161
+ ## License
162
+
163
+ UNLICENSED (Private)
@@ -0,0 +1,163 @@
1
+ # ufoo
2
+
3
+ 多Agent AI 协作工具包,支持 Claude Code 和 OpenAI Codex。
4
+
5
+ ## 功能特性
6
+
7
+ - **事件总线** - Agent间实时消息通信 (`ufoo bus`)
8
+ - **上下文共享** - 共享决策和项目上下文 (`ufoo ctx`)
9
+ - **Agent包装器** - Claude Code (`uclaude`) 和 Codex (`ucodex`) 自动初始化
10
+ - **技能系统** - 可扩展的Agent能力 (`ufoo skills`)
11
+
12
+ ## 快速开始
13
+
14
+ ```bash
15
+ # 克隆并全局链接
16
+ git clone <repo> ~/.ufoo
17
+ cd ~/.ufoo && npm link
18
+
19
+ # 初始化项目
20
+ cd your-project
21
+ ufoo init
22
+
23
+ # 或使用Agent包装器(自动初始化 + 加入总线)
24
+ uclaude # 代替 'claude'
25
+ ucodex # 代替 'codex'
26
+ ```
27
+
28
+ ## 架构
29
+
30
+ ```
31
+ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
32
+ │ uclaude │ │ ucodex │ │ 其他... │
33
+ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘
34
+ │ │ │
35
+ └───────────────────┼───────────────────┘
36
+
37
+ ┌──────▼──────┐
38
+ │ ufoo bus │ 事件总线
39
+ └──────┬──────┘
40
+
41
+ ┌────────────┼────────────┐
42
+ │ │ │
43
+ ┌──────▼──────┐ ┌───▼───┐ ┌──────▼──────┐
44
+ │ .ufoo/bus │ │context│ │ decisions │
45
+ └─────────────┘ └───────┘ └─────────────┘
46
+ ```
47
+
48
+ ## 命令列表
49
+
50
+ | 命令 | 说明 |
51
+ |------|------|
52
+ | `ufoo init` | 在当前项目初始化 .ufoo |
53
+ | `ufoo status` | 显示 banner、未读消息和未处理决策 |
54
+ | `ufoo daemon --start|--stop|--status` | 管理 ufoo 守护进程 |
55
+ | `ufoo chat` | 启动 ufoo 交互界面(无参数默认进入) |
56
+ | `ufoo bus join` | 加入事件总线(uclaude/ucodex 自动完成)|
57
+ | `ufoo bus send <id> <msg>` | 发送消息给Agent |
58
+ | `ufoo bus check <id>` | 检查待处理消息 |
59
+ | `ufoo bus status` | 查看总线状态 |
60
+ | `ufoo ctx decisions -l` | 列出所有决策 |
61
+ | `ufoo ctx decisions -n 1` | 显示最新决策 |
62
+ | `ufoo skills list` | 列出可用技能 |
63
+ | `ufoo doctor` | 检查安装状态 |
64
+
65
+ 备注:
66
+ - Claude CLI 的 headless agent 使用 `--dangerously-skip-permissions`。
67
+
68
+ ## 项目结构
69
+
70
+ ```
71
+ ufoo/
72
+ ├── bin/
73
+ │ ├── ufoo # 主 CLI 入口 (bash)
74
+ │ ├── ufoo.js # Node 包装器
75
+ │ ├── uclaude # Claude Code 包装器
76
+ │ └── ucodex # Codex 包装器
77
+ ├── SKILLS/ # 全局技能(uinit, ustatus)
78
+ ├── scripts/
79
+ │ ├── bus.sh # 事件总线实现
80
+ │ ├── bus-*.sh # 总线工具(注入、守护进程、提醒)
81
+ │ ├── context-*.sh # 上下文管理
82
+ │ ├── init.sh # 项目初始化
83
+ │ └── skills.sh # 技能管理
84
+ ├── modules/
85
+ │ ├── context/ # 决策/上下文协议
86
+ │ ├── bus/ # 总线模块资源
87
+ │ └── resources/ # UI/图标(可选)
88
+ ├── AGENTS.md # 项目指令(规范文件)
89
+ └── CLAUDE.md # 指向 AGENTS.md
90
+ ```
91
+
92
+ ## 项目初始化后的目录结构
93
+
94
+ 执行 `ufoo init` 后,你的项目会包含:
95
+
96
+ ```
97
+ your-project/
98
+ ├── .ufoo/
99
+ │ ├── bus/
100
+ │ │ ├── events/ # 事件日志(只追加)
101
+ │ │ ├── queues/ # 每个Agent的消息队列
102
+ │ │ └── offsets/ # 读取位置跟踪
103
+ │ └── context/
104
+ │ └── DECISIONS/ # 决策记录
105
+ ├── scripts/ # 软链接的 ufoo 脚本
106
+ ├── AGENTS.md # 注入的协议块
107
+ └── CLAUDE.md # → AGENTS.md
108
+ ```
109
+
110
+ ## Agent通信
111
+
112
+ Agent通过事件总线通信:
113
+
114
+ ```bash
115
+ # Agent A 向Agent B 发送任务
116
+ ufoo bus send "codex:abc123" "请分析项目结构"
117
+
118
+ # Agent B 检查并执行
119
+ ufoo bus check "codex:abc123"
120
+ # → 自动执行任务
121
+ # → 回复结果
122
+ ufoo bus send "claude-code:xyz789" "分析完成:..."
123
+ ```
124
+
125
+ ## 技能(供Agent使用)
126
+
127
+ 内置技能通过斜杠命令触发:
128
+
129
+ - `/ubus` - 检查并自动执行待处理消息
130
+ - `/uctx` - 快速检查上下文状态
131
+ - `/ustatus` - 统一状态视图(横幅、未读消息、未决决策)
132
+ - `/uinit` - 手动初始化 .ufoo
133
+
134
+ ## 系统要求
135
+
136
+ - macOS(用于 Terminal.app/iTerm2 注入功能)
137
+ - Node.js >= 18(可选,用于 npm 全局安装)
138
+ - Bash 4+
139
+
140
+ ## Codex CLI 说明
141
+
142
+ 如果 Codex CLI 在 `~/.codex` 下报权限错误(例如 sessions 目录),请在启动 daemon/chat 前设置可写的 `CODEX_HOME`:
143
+
144
+ ```bash
145
+ export CODEX_HOME="$PWD/.ufoo/codex"
146
+ ufoo daemon start
147
+ ufoo chat
148
+ ```
149
+
150
+ ## 开发
151
+
152
+ ```bash
153
+ # 本地开发
154
+ ./bin/ufoo --help
155
+
156
+ # 或通过 Node
157
+ npm link
158
+ ufoo --help
159
+ ```
160
+
161
+ ## 许可证
162
+
163
+ UNLICENSED(私有)
package/bin/uclaude ADDED
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env bash
2
+ # uclaude: Launch Claude Code and auto-join event bus
3
+ #
4
+ # Usage: uclaude [claude args...]
5
+
6
+ set -euo pipefail
7
+
8
+ # Resolve symlinks to get real script location
9
+ SCRIPT_PATH="${BASH_SOURCE[0]}"
10
+ while [[ -L "$SCRIPT_PATH" ]]; do
11
+ SCRIPT_DIR="$(cd "$(dirname "$SCRIPT_PATH")" && pwd)"
12
+ SCRIPT_PATH="$(readlink "$SCRIPT_PATH")"
13
+ [[ "$SCRIPT_PATH" != /* ]] && SCRIPT_PATH="$SCRIPT_DIR/$SCRIPT_PATH"
14
+ done
15
+ SCRIPT_DIR="$(cd "$(dirname "$SCRIPT_PATH")" && pwd)"
16
+ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
17
+
18
+ # Source banner
19
+ source "$PROJECT_ROOT/scripts/banner.sh" 2>/dev/null || true
20
+
21
+ # Check and initialize .ufoo (silent)
22
+ if [[ ! -d ".ufoo/bus" ]]; then
23
+ ufoo init --modules context,bus &>/dev/null || true
24
+ fi
25
+
26
+ # Check if AGENTS.md has ufoo template (inject if not)
27
+ if [[ -f "AGENTS.md" ]] && ! grep -q "<!-- ufoo -->" "AGENTS.md" 2>/dev/null; then
28
+ ufoo init --modules context,bus &>/dev/null || true
29
+ fi
30
+
31
+ # Generate or reuse session ID
32
+ if [[ -z "${CLAUDE_SESSION_ID:-}" ]]; then
33
+ export CLAUDE_SESSION_ID="$(date +%s%N | shasum | head -c 8)"
34
+ fi
35
+
36
+ # Join event bus (using fixed session ID)
37
+ # Export our PID so bus.sh registers the correct process
38
+ export UFOO_PARENT_PID=$$
39
+ NICKNAME="${UFOO_NICKNAME:-}"
40
+ SUBSCRIBER=$(ufoo bus join "$CLAUDE_SESSION_ID" claude-code "$NICKNAME" 2>/dev/null | tail -1)
41
+
42
+ # Auto-start project-level daemon (if not running)
43
+ DAEMON_STATUS=""
44
+ PID_FILE=".ufoo/bus/.daemon.pid"
45
+ if [[ -f "$PID_FILE" ]]; then
46
+ existing="$(cat "$PID_FILE" 2>/dev/null || true)"
47
+ if [[ -n "$existing" ]] && kill -0 "$existing" 2>/dev/null; then
48
+ DAEMON_STATUS="running"
49
+ else
50
+ ufoo bus daemon --daemon &>/dev/null && DAEMON_STATUS="started"
51
+ fi
52
+ else
53
+ ufoo bus daemon --daemon &>/dev/null && DAEMON_STATUS="started"
54
+ fi
55
+
56
+ # Show banner
57
+ if type show_banner &>/dev/null; then
58
+ show_banner "claude" "$CLAUDE_SESSION_ID" "$SUBSCRIBER" "$DAEMON_STATUS"
59
+ else
60
+ echo "[uclaude] Connected -> $SUBSCRIBER"
61
+ echo "[uclaude] Daemon: $DAEMON_STATUS"
62
+ echo ""
63
+ fi
64
+
65
+ exec claude "$@"
package/bin/ucodex ADDED
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env bash
2
+ # ucodex: Launch Codex and auto-join event bus
3
+ #
4
+ # Usage: ucodex [codex args...]
5
+
6
+ set -euo pipefail
7
+
8
+ # Resolve symlinks to get real script location
9
+ SCRIPT_PATH="${BASH_SOURCE[0]}"
10
+ while [[ -L "$SCRIPT_PATH" ]]; do
11
+ SCRIPT_DIR="$(cd "$(dirname "$SCRIPT_PATH")" && pwd)"
12
+ SCRIPT_PATH="$(readlink "$SCRIPT_PATH")"
13
+ [[ "$SCRIPT_PATH" != /* ]] && SCRIPT_PATH="$SCRIPT_DIR/$SCRIPT_PATH"
14
+ done
15
+ SCRIPT_DIR="$(cd "$(dirname "$SCRIPT_PATH")" && pwd)"
16
+ PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
17
+
18
+ # Source banner
19
+ source "$PROJECT_ROOT/scripts/banner.sh" 2>/dev/null || true
20
+
21
+ # Check and initialize .ufoo (silent)
22
+ if [[ ! -d ".ufoo/bus" ]]; then
23
+ ufoo init --modules context,bus &>/dev/null || true
24
+ fi
25
+
26
+ # Check if AGENTS.md has ufoo template (inject if not)
27
+ if [[ -f "AGENTS.md" ]] && ! grep -q "<!-- ufoo -->" "AGENTS.md" 2>/dev/null; then
28
+ ufoo init --modules context,bus &>/dev/null || true
29
+ fi
30
+
31
+ # Generate or reuse session ID
32
+ if [[ -z "${CODEX_SESSION_ID:-}" ]]; then
33
+ export CODEX_SESSION_ID="$(date +%s%N | shasum | head -c 8)"
34
+ fi
35
+
36
+ # Join event bus (using fixed session ID)
37
+ # Export our PID so bus.sh registers the correct process
38
+ export UFOO_PARENT_PID=$$
39
+ NICKNAME="${UFOO_NICKNAME:-}"
40
+ SUBSCRIBER=$(ufoo bus join "$CODEX_SESSION_ID" codex "$NICKNAME" 2>/dev/null | tail -1)
41
+
42
+ # Auto-start project-level daemon (if not running)
43
+ DAEMON_STATUS=""
44
+ PID_FILE=".ufoo/bus/.daemon.pid"
45
+ if [[ -f "$PID_FILE" ]]; then
46
+ existing="$(cat "$PID_FILE" 2>/dev/null || true)"
47
+ if [[ -n "$existing" ]] && kill -0 "$existing" 2>/dev/null; then
48
+ DAEMON_STATUS="running"
49
+ else
50
+ ufoo bus daemon --daemon &>/dev/null && DAEMON_STATUS="started"
51
+ fi
52
+ else
53
+ ufoo bus daemon --daemon &>/dev/null && DAEMON_STATUS="started"
54
+ fi
55
+
56
+ # Show banner
57
+ if type show_banner &>/dev/null; then
58
+ show_banner "codex" "$CODEX_SESSION_ID" "$SUBSCRIBER" "$DAEMON_STATUS"
59
+ else
60
+ echo "[ucodex] Connected -> $SUBSCRIBER"
61
+ echo "[ucodex] Daemon: $DAEMON_STATUS"
62
+ echo ""
63
+ fi
64
+
65
+ exec codex "$@"
package/bin/ufoo ADDED
@@ -0,0 +1,93 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5
+
6
+ usage() {
7
+ cat <<'USAGE'
8
+ ufoo
9
+
10
+ Monorepo layout:
11
+ ~/.ufoo/ (clone of ufoo)
12
+ modules/ai-context/ (protocol module)
13
+ modules/ai-resources/ (optional resources)
14
+
15
+ Usage:
16
+ ufoo doctor
17
+ ufoo status
18
+ ufoo daemon --start|--stop|--status
19
+ ufoo chat
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
23
+ ufoo skills list
24
+ ufoo skills install <name|all> [--codex|--agents|--target <dir>]
25
+
26
+ Notes:
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).
29
+ USAGE
30
+ }
31
+
32
+ cmd="${1:-}"
33
+ shift || true
34
+
35
+ case "$cmd" in
36
+ ""|--help|-h)
37
+ exec node "$repo_root/bin/ufoo.js" chat
38
+ ;;
39
+ doctor)
40
+ exec bash "$repo_root/scripts/doctor.sh"
41
+ ;;
42
+ status)
43
+ exec bash "$repo_root/scripts/status.sh"
44
+ ;;
45
+ daemon)
46
+ exec node "$repo_root/bin/ufoo.js" daemon "$@"
47
+ ;;
48
+ chat)
49
+ exec node "$repo_root/bin/ufoo.js" chat
50
+ ;;
51
+ init)
52
+ exec bash "$repo_root/scripts/init.sh" "$@"
53
+ ;;
54
+ bus)
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" "$@"
61
+ ;;
62
+ 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
82
+ ;;
83
+ skills)
84
+ sub="${1:-}"
85
+ shift || true
86
+ exec bash "$repo_root/scripts/skills.sh" "$sub" "$@"
87
+ ;;
88
+ *)
89
+ echo "Unknown command: $cmd" >&2
90
+ usage >&2
91
+ exit 1
92
+ ;;
93
+ esac
package/bin/ufoo.js ADDED
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env node
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/agent/internalRunner");
7
+
8
+ const cmd = process.argv[2];
9
+
10
+ async function main() {
11
+ if (!cmd) {
12
+ await runChat(process.cwd());
13
+ return;
14
+ }
15
+ if (cmd === "daemon") {
16
+ runDaemonCli(process.argv.slice(2));
17
+ return;
18
+ }
19
+ if (cmd === "agent-runner") {
20
+ const agentType = process.argv[3] || "codex";
21
+ await runInternalRunner({ projectRoot: process.cwd(), agentType });
22
+ return;
23
+ }
24
+ if (cmd === "chat") {
25
+ await runChat(process.cwd());
26
+ return;
27
+ }
28
+ await runCli(process.argv);
29
+ }
30
+
31
+ main().catch((err) => {
32
+ const message = err && err.stack ? err.stack : String(err);
33
+ console.error(message);
34
+ process.exitCode = 1;
35
+ });