@excitedjs/dreamux 0.1.4 → 0.3.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 +170 -154
- package/bin/tm +30 -0
- package/dist/admin/client.js +98 -0
- package/dist/admin/client.js.map +1 -0
- package/dist/admin/methods.js +83 -38
- package/dist/admin/methods.js.map +1 -1
- package/dist/admin/socket.js +2 -2
- package/dist/admin/socket.js.map +1 -1
- package/dist/channel/feishu-gate.js +187 -18
- package/dist/channel/feishu-gate.js.map +1 -1
- package/dist/channel/feishu-message.js +92 -0
- package/dist/channel/feishu-message.js.map +1 -0
- package/dist/cli/doctor.js +53 -58
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/dreamux.js +72 -61
- package/dist/cli/dreamux.js.map +1 -1
- package/dist/cli/server-ctl.js +6 -8
- package/dist/cli/server-ctl.js.map +1 -1
- package/dist/cli/server.js +25 -38
- package/dist/cli/server.js.map +1 -1
- package/dist/codex/events.js +3 -2
- package/dist/codex/events.js.map +1 -1
- package/dist/codex/mcp-config.js +24 -0
- package/dist/codex/mcp-config.js.map +1 -0
- package/dist/codex/supervisor.js +16 -0
- package/dist/codex/supervisor.js.map +1 -1
- package/dist/dispatcher/approval.js +2 -3
- package/dist/dispatcher/approval.js.map +1 -1
- package/dist/dispatcher/runtime.js +195 -143
- package/dist/dispatcher/runtime.js.map +1 -1
- package/dist/dispatcher/turn-manager.js +78 -97
- package/dist/dispatcher/turn-manager.js.map +1 -1
- package/dist/feishu/bot.js +71 -9
- package/dist/feishu/bot.js.map +1 -1
- package/dist/mcp/feishu-mcp.js +269 -0
- package/dist/mcp/feishu-mcp.js.map +1 -0
- package/dist/onboard/config-files.js +60 -87
- package/dist/onboard/config-files.js.map +1 -1
- package/dist/onboard/dispatcher-skill.js +18 -0
- package/dist/onboard/dispatcher-skill.js.map +1 -0
- package/dist/onboard/run.js +40 -79
- package/dist/onboard/run.js.map +1 -1
- package/dist/onboard/service.js +6 -5
- package/dist/onboard/service.js.map +1 -1
- package/dist/onboard/uninstall.js +161 -0
- package/dist/onboard/uninstall.js.map +1 -0
- package/dist/onboard/wizard.js +12 -69
- package/dist/onboard/wizard.js.map +1 -1
- package/dist/runtime/codex-args.js +1 -1
- package/dist/runtime/config.js +213 -213
- package/dist/runtime/config.js.map +1 -1
- package/dist/runtime/dispatcher-codex-home.js +21 -185
- package/dist/runtime/dispatcher-codex-home.js.map +1 -1
- package/dist/runtime/dispatcher-id.js +9 -0
- package/dist/runtime/dispatcher-id.js.map +1 -0
- package/dist/runtime/dispatcher-store.js +202 -0
- package/dist/runtime/dispatcher-store.js.map +1 -0
- package/dist/runtime/package-bin.js +41 -0
- package/dist/runtime/package-bin.js.map +1 -0
- package/dist/runtime/paths.js +87 -48
- package/dist/runtime/paths.js.map +1 -1
- package/dist/runtime/secrets.js +17 -14
- package/dist/runtime/secrets.js.map +1 -1
- package/dist/server.js +112 -38
- package/dist/server.js.map +1 -1
- package/package.json +6 -6
- package/skills/dispatcher/SKILL.md +107 -0
- package/db/migrations/0001_init.sql +0 -49
- package/dist/channel/outbound.js +0 -12
- package/dist/channel/outbound.js.map +0 -1
- package/dist/db/repository.js +0 -223
- package/dist/db/repository.js.map +0 -1
- package/dist/db/schema.js +0 -29
- package/dist/db/schema.js.map +0 -1
- package/dist/db/types.js +0 -2
- package/dist/db/types.js.map +0 -1
- package/dist/onboard/plugins.js +0 -202
- package/dist/onboard/plugins.js.map +0 -1
package/README.md
CHANGED
|
@@ -3,54 +3,61 @@
|
|
|
3
3
|
The Codex-host server package. One long-running Node process hosts N
|
|
4
4
|
**Dispatchers**; each Dispatcher binds **1 Feishu bot + 1 Codex thread**.
|
|
5
5
|
|
|
6
|
-
This file is the **package-level** quick start. For the monorepo layout
|
|
7
|
-
|
|
8
|
-
[`README.md`](../../README.md) and
|
|
6
|
+
This file is the **package-level** quick start. For the monorepo layout and
|
|
7
|
+
knowledge base, see the top-level [`README.md`](../../README.md) and
|
|
9
8
|
[`.agents/root.md`](../../.agents/root.md).
|
|
10
9
|
|
|
11
10
|
Design background:
|
|
12
11
|
[#1 Proposal](https://github.com/excitedjs/dreamux/issues/1) ·
|
|
13
12
|
[#2 Engineering plan](https://github.com/excitedjs/dreamux/issues/2) ·
|
|
14
13
|
[#4 Monorepo + harness](https://github.com/excitedjs/dreamux/issues/4) ·
|
|
15
|
-
[#18 Global bin onboarding](https://github.com/excitedjs/dreamux/issues/18)
|
|
14
|
+
[#18 Global bin onboarding](https://github.com/excitedjs/dreamux/issues/18) ·
|
|
15
|
+
[#36 MVP tracking](https://github.com/excitedjs/dreamux/issues/36).
|
|
16
16
|
|
|
17
17
|
## What this package ships
|
|
18
18
|
|
|
19
|
-
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
- A
|
|
23
|
-
|
|
19
|
+
- Public CLI bins: `dreamux` and `tm`. `dreamux` owns onboarding, serving,
|
|
20
|
+
status, doctor, dispatcher commands, and config commands. `tm` is a wrapper
|
|
21
|
+
around the package-local `@excitedjs/tm` dependency for dispatcher skills.
|
|
22
|
+
- A bundled dispatcher Codex skill, copied by `dreamux onboard` into
|
|
23
|
+
`<dispatcher cwd>/.codex/skills/dispatcher/SKILL.md`.
|
|
24
|
+
- Config-backed dispatcher declarations, server-owned state/log paths, a
|
|
25
|
+
Feishu long-connection inbound channel, Codex app-server lifecycle
|
|
26
|
+
management, and a dispatcher-scoped Feishu MCP shim for model replies.
|
|
24
27
|
|
|
25
|
-
##
|
|
28
|
+
## MVP contract
|
|
26
29
|
|
|
27
30
|
- **One Node process, many Dispatchers.** Each Dispatcher = 1 Feishu Bot
|
|
28
|
-
(
|
|
29
|
-
|
|
30
|
-
- **
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
- **
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
- **
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
31
|
+
(`app_id`/`app_secret`) + 1 long-lived Codex `app-server` child + 1 Codex
|
|
32
|
+
thread.
|
|
33
|
+
- **One dispatcher is one trust domain.** A bot may receive multiple chats, but
|
|
34
|
+
all accepted messages share one Codex thread. Do not bind unrelated private
|
|
35
|
+
chats to the same dispatcher.
|
|
36
|
+
- **Dispatcher cwd is explicit, Codex state stays global.** Dispatcher
|
|
37
|
+
app-server processes use Codex's global default home (`~/.codex`) for auth,
|
|
38
|
+
memory, and config. The dispatcher skill is workspace-local under the
|
|
39
|
+
dispatcher cwd.
|
|
40
|
+
- **Inbound state is in memory.** The server keeps only process-local turn
|
|
41
|
+
queues, message dedupe, coalescing state, and received-reaction ownership.
|
|
42
|
+
Restarting the server drops unprocessed inbound messages and may leave
|
|
43
|
+
received reactions behind.
|
|
44
|
+
- **Outbound is MCP reply-only.** Assistant text emitted by Codex is never
|
|
45
|
+
forwarded to Feishu automatically. The model must call the dispatcher-scoped
|
|
46
|
+
Feishu MCP tools such as `reply` or `react`.
|
|
47
|
+
- **No webhook surface in MVP.** Feishu inbound uses the SDK long-connection
|
|
48
|
+
WebSocket path. Webhook-only verification/encryption fields are not part of
|
|
49
|
+
the config schema.
|
|
50
|
+
|
|
51
|
+
Explicitly **not** in MVP: per-chat threads, durable inbound buffers,
|
|
52
|
+
automatic assistant-text outbound, HTTP MCP listeners by default, reaction
|
|
53
|
+
ledgers, streaming outbound, tm registry isolation, cross-machine
|
|
54
|
+
coordination, and a web UI.
|
|
46
55
|
|
|
47
56
|
## Install / build / test
|
|
48
57
|
|
|
49
|
-
Use the monorepo (rush) path from the repo root
|
|
50
|
-
install path
|
|
51
|
-
pnpm `workspace:*` protocol
|
|
52
|
-
`cd packages/dreamux && npm install` no longer works (see
|
|
53
|
-
[the install-model decision](../../.agents/decisions/install-model.md)):
|
|
58
|
+
Use the monorepo (rush) path from the repo root. It is the only supported
|
|
59
|
+
install path because this package depends on workspace packages through the
|
|
60
|
+
pnpm `workspace:*` protocol:
|
|
54
61
|
|
|
55
62
|
```bash
|
|
56
63
|
node common/scripts/install-run-rush.js update
|
|
@@ -58,10 +65,8 @@ node common/scripts/install-run-rush.js build
|
|
|
58
65
|
node common/scripts/install-run-rush.js test
|
|
59
66
|
```
|
|
60
67
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
The bin launchers shell out to plain `node` against the compiled `dist/`
|
|
64
|
-
output; **no `tsx` is needed at runtime** (PR #6).
|
|
68
|
+
The bin launchers shell out to plain `node` against compiled `dist/` output;
|
|
69
|
+
no `tsx` is needed at runtime.
|
|
65
70
|
|
|
66
71
|
## Run the server
|
|
67
72
|
|
|
@@ -69,144 +74,155 @@ output; **no `tsx` is needed at runtime** (PR #6).
|
|
|
69
74
|
./bin/dreamux serve
|
|
70
75
|
```
|
|
71
76
|
|
|
72
|
-
The launcher works from any cwd and via symlinks
|
|
77
|
+
The launcher works from any cwd and via symlinks.
|
|
73
78
|
|
|
74
|
-
The server
|
|
75
|
-
|
|
79
|
+
The server keeps operator-edited config separate from server-owned state and
|
|
80
|
+
logs:
|
|
76
81
|
|
|
77
82
|
| Path | Purpose | Source of truth |
|
|
78
83
|
|---|---|---|
|
|
79
|
-
| `~/.dreamux/config.
|
|
80
|
-
| `~/.
|
|
81
|
-
| `~/.
|
|
82
|
-
| `~/.
|
|
83
|
-
| `~/.
|
|
84
|
-
| `~/.
|
|
85
|
-
| `~/.codex-
|
|
84
|
+
| `~/.dreamux/config.json` | User-editable config and Feishu bot secrets, created by `dreamux onboard`; edit and restart to apply | the operator |
|
|
85
|
+
| `~/.dreamux/state/server.json` | Server status snapshot | the server |
|
|
86
|
+
| `~/.dreamux/state/admin.sock` | Admin Unix socket | the server |
|
|
87
|
+
| `~/.dreamux/state/<id>/status.json` | Dispatcher runtime status and Codex thread id | the server |
|
|
88
|
+
| `~/.dreamux/state/<id>/access.json` | Dispatcher-local access-gate state | the server |
|
|
89
|
+
| `~/.dreamux/state/<id>/codex.sock` | Codex app-server Unix socket | the server |
|
|
90
|
+
| `~/.dreamux/logs/codex-app-server/<id>.log` | Codex app-server stdout/stderr | the server |
|
|
91
|
+
| `~/.dreamux/logs/feishu-channel/<id>.log` | Feishu channel logs | the server |
|
|
92
|
+
| `~/.codex/` | Codex global default home: auth, memory, and config | the operator / Codex |
|
|
93
|
+
| `<dispatcher cwd>/.codex/skills/dispatcher/SKILL.md` | Dispatcher skill copied by `dreamux onboard`; reported but not deleted by `dreamux uninstall` | dreamux installer |
|
|
86
94
|
|
|
87
|
-
`rm -rf ~/.
|
|
88
|
-
|
|
89
|
-
the `~/.codex-host` half anywhere you like.
|
|
95
|
+
`rm -rf ~/.dreamux/state ~/.dreamux/logs` is a state/log recovery path; dreamux
|
|
96
|
+
config and global Codex auth survive.
|
|
90
97
|
|
|
91
|
-
## Configure
|
|
98
|
+
## Configure dispatchers
|
|
92
99
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
./bin/dreamux dispatcher add \
|
|
98
|
-
--id flow \
|
|
99
|
-
--bot-app-id <APP_ID> \
|
|
100
|
-
--bot-secret-ref env:BOT_SECRET_FLOW
|
|
101
|
-
|
|
102
|
-
# Inspect / restart
|
|
103
|
-
./bin/dreamux dispatcher list
|
|
104
|
-
./bin/dreamux dispatcher status --id flow
|
|
105
|
-
./bin/dreamux dispatcher start --id flow # if not auto-started
|
|
106
|
-
```
|
|
100
|
+
For normal installs, run `dreamux onboard`. It writes `~/.dreamux/config.json`
|
|
101
|
+
with mode `0600`, creates state/log directories, installs the workspace skill,
|
|
102
|
+
and registers a user-level service when supported.
|
|
107
103
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
1. `dreamux dispatcher add --id flow --bot-app-id <APP_ID> --bot-secret-ref env:BOT_SECRET_FLOW`
|
|
111
|
-
2. `dreamux serve` — dispatcher `flow` goes to `ready`
|
|
112
|
-
3. Invite the bot to a Feishu group A, send `hi`
|
|
113
|
-
4. Server delivers it into the Codex thread; reply goes back to group A
|
|
114
|
-
5. Invite the same bot to a DM, ask "do you remember the 'hi' from earlier?"
|
|
115
|
-
6. Same thread, so the reply confirms — and goes back to the DM
|
|
116
|
-
7. Ask the bot to "run the test suite via tm and summarize"
|
|
117
|
-
8. Codex shells out to `tm`, reads stdout/stderr, replies into the source chat
|
|
118
|
-
9. Repeat with a **different** worktree to prove dispatcher↔worktree decoupling
|
|
119
|
-
10. `pkill node` to crash the server, then restart it
|
|
120
|
-
11. Continue chatting — Codex `thread/resume` restores context
|
|
121
|
-
|
|
122
|
-
## Configuration reference
|
|
123
|
-
|
|
124
|
-
Precedence for every config-able value (highest wins): env var →
|
|
125
|
-
per-dispatcher field → `~/.dreamux/config.toml` → built-in default.
|
|
126
|
-
See [the global-config decision](../../.agents/decisions/global-config-dir.md).
|
|
127
|
-
|
|
128
|
-
### Global: `~/.dreamux/config.toml`
|
|
129
|
-
|
|
130
|
-
Auto-created on first boot with this default (excerpt — open the file
|
|
131
|
-
itself for the inline comments explaining each key):
|
|
132
|
-
|
|
133
|
-
```toml
|
|
134
|
-
runtime_dir = "~/.codex-host"
|
|
135
|
-
# admin_socket = "~/.codex-host/admin.sock" # default: <runtime_dir>/admin.sock
|
|
136
|
-
|
|
137
|
-
[codex]
|
|
138
|
-
bin = "codex"
|
|
139
|
-
approval_policy = "never" # never | auto | auto-approve | on-failure
|
|
140
|
-
sandbox_mode = "workspace-write" # read-only | workspace-write | danger-full-access
|
|
141
|
-
extra_args = []
|
|
142
|
-
initialize_timeout_ms = 10000
|
|
143
|
-
|
|
144
|
-
[outbound]
|
|
145
|
-
retries = 3
|
|
146
|
-
retry_delay_ms = 1000
|
|
147
|
-
```
|
|
104
|
+
Dispatcher declarations live in `config.json`:
|
|
148
105
|
|
|
149
|
-
|
|
150
|
-
|
|
106
|
+
```json
|
|
107
|
+
{
|
|
108
|
+
"codex": {
|
|
109
|
+
"bin": "codex",
|
|
110
|
+
"approval_policy": "never",
|
|
111
|
+
"sandbox_mode": "workspace-write",
|
|
112
|
+
"extra_args": [],
|
|
113
|
+
"initialize_timeout_ms": 10000
|
|
114
|
+
},
|
|
115
|
+
"dispatchers": [
|
|
116
|
+
{
|
|
117
|
+
"id": "flow",
|
|
118
|
+
"cwd": "<WORKSPACE>",
|
|
119
|
+
"enabled": true,
|
|
120
|
+
"feishu": {
|
|
121
|
+
"app_id": "<APP_ID>",
|
|
122
|
+
"app_secret": "<APP_SECRET>"
|
|
123
|
+
},
|
|
124
|
+
"codex": {
|
|
125
|
+
"approval_policy": null,
|
|
126
|
+
"sandbox_mode": null,
|
|
127
|
+
"extra_args": [],
|
|
128
|
+
"extra_env": {
|
|
129
|
+
"EXAMPLE_FLAG": "1"
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
]
|
|
134
|
+
}
|
|
135
|
+
```
|
|
151
136
|
|
|
152
|
-
|
|
137
|
+
Edit and restart `dreamux serve` to apply dispatcher declaration changes.
|
|
138
|
+
`app_id` values must be unique across all declared dispatchers, including
|
|
139
|
+
disabled ones. Dispatcher ids use a path-safe character set so they map
|
|
140
|
+
one-to-one to state directories.
|
|
153
141
|
|
|
154
|
-
|
|
142
|
+
Access-gate allowlists are not part of `config.json`. Configure them in
|
|
143
|
+
`~/.dreamux/state/<id>/access.json`:
|
|
155
144
|
|
|
156
145
|
```json
|
|
157
|
-
{
|
|
146
|
+
{
|
|
147
|
+
"version": 1,
|
|
148
|
+
"dm": {
|
|
149
|
+
"allow_users": ["<USER_ID>"]
|
|
150
|
+
},
|
|
151
|
+
"group": {
|
|
152
|
+
"allow_chats": ["<CHAT_ID>"],
|
|
153
|
+
"follow_users": ["<USER_ID>"],
|
|
154
|
+
"require_mention": true
|
|
155
|
+
},
|
|
156
|
+
"observed_chats": [],
|
|
157
|
+
"warnings": [],
|
|
158
|
+
"last_gate": null
|
|
159
|
+
}
|
|
158
160
|
```
|
|
159
161
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
-
|
|
187
|
-
|
|
188
|
-
-
|
|
189
|
-
|
|
162
|
+
The server reads `access.json` directly at runtime and preserves runtime
|
|
163
|
+
observations and warnings in the same file.
|
|
164
|
+
|
|
165
|
+
`dreamux config show`, `dreamux status`, `dreamux doctor`, and logs redact
|
|
166
|
+
`app_secret`. There is no CLI raw mode for printing the unredacted local file.
|
|
167
|
+
|
|
168
|
+
## Codex configuration precedence
|
|
169
|
+
|
|
170
|
+
Precedence for Codex-related values, highest first:
|
|
171
|
+
|
|
172
|
+
1. Environment variables, such as `CODEX_HOST_CODEX_BIN`.
|
|
173
|
+
2. Per-dispatcher `dispatchers[].codex` fields.
|
|
174
|
+
3. Global `codex` fields in `~/.dreamux/config.json`.
|
|
175
|
+
4. Built-in defaults compiled into `src/runtime/config.ts`.
|
|
176
|
+
|
|
177
|
+
Per-dispatcher `extra_args` are appended after global `codex.extra_args`, which
|
|
178
|
+
matches Codex's last-write-wins behavior for repeated `-c key=value` options.
|
|
179
|
+
Per-dispatcher `extra_env` is merged over the server process environment before
|
|
180
|
+
spawning that dispatcher app-server; dreamux still removes `CODEX_HOME` so
|
|
181
|
+
Codex keeps using its global default home.
|
|
182
|
+
|
|
183
|
+
## MCP reply flow
|
|
184
|
+
|
|
185
|
+
Each dispatcher injects a Feishu MCP stdio server into its Codex app-server.
|
|
186
|
+
The stdio shim does not read Feishu secrets. It forwards outbound tool calls to
|
|
187
|
+
the serve process over the admin socket, and the serve process owns the Feishu
|
|
188
|
+
client plus process-local received-reaction cleanup state.
|
|
189
|
+
|
|
190
|
+
The model-facing tools include:
|
|
191
|
+
|
|
192
|
+
- `reply`: send a Feishu reply to a target message or chat.
|
|
193
|
+
- `react`: add a model-owned reaction to a Feishu message.
|
|
194
|
+
|
|
195
|
+
If the model only emits assistant text, nothing is sent to Feishu.
|
|
196
|
+
|
|
197
|
+
## MVP verification path
|
|
198
|
+
|
|
199
|
+
1. `dreamux onboard --dispatcher-id flow --dispatcher-cwd <WORKSPACE> --bot-app-id <APP_ID> --bot-app-secret <APP_SECRET>`
|
|
200
|
+
2. `dreamux serve` starts dispatcher `flow`.
|
|
201
|
+
3. Invite the bot to a Feishu group, send a mention that passes the access gate.
|
|
202
|
+
4. Server injects a `<feishu_message>` block into the Codex thread.
|
|
203
|
+
5. Codex calls the Feishu MCP `reply` tool; the reply is delivered to Feishu.
|
|
204
|
+
6. Send another accepted message from a different chat in the same trust
|
|
205
|
+
domain; it enters the same Codex thread.
|
|
206
|
+
7. Ask the bot to run teammate work through the bundled `tm` wrapper.
|
|
207
|
+
8. Restart the server and continue chatting; Codex `thread/resume` restores the
|
|
208
|
+
thread when possible, but in-flight inbound messages are not durable.
|
|
190
209
|
|
|
191
210
|
## Testing
|
|
192
211
|
|
|
193
212
|
```bash
|
|
194
|
-
|
|
195
|
-
node common/scripts/install-run-rush.js test # smoke + bin-launcher + codex-0135-live
|
|
213
|
+
node common/scripts/install-run-rush.js test
|
|
196
214
|
```
|
|
197
215
|
|
|
198
|
-
- `tests/smoke.test.ts` — fake-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
- `tests/bin-launcher.test.ts` —
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
(skipped loudly when `codex` is missing or wrong version; opt-in via
|
|
209
|
-
`DREAMUX_SKIP_LIVE_CODEX=1`).
|
|
216
|
+
- `tests/smoke.test.ts` — fake-Codex dispatcher behavior: access gate,
|
|
217
|
+
in-memory turn serialization/coalescing/dedupe, MCP reply-only outbound,
|
|
218
|
+
thread resume, app-server restart behavior, and approval fail-fast.
|
|
219
|
+
- `tests/bin-launcher.test.ts` — real launcher and repo-root shim behavior from
|
|
220
|
+
arbitrary cwd and through symlinks.
|
|
221
|
+
- `tests/doctor.test.ts` — standalone doctor checks for config, Codex home,
|
|
222
|
+
services, and dispatcher workspace skill state.
|
|
223
|
+
- `tests/codex-0135-live.test.ts` and `tests/codex-0136-mcp-live.test.ts` —
|
|
224
|
+
real Codex app-server compatibility checks. Set `DREAMUX_SKIP_LIVE_CODEX=1`
|
|
225
|
+
only when no Codex binary is available locally.
|
|
210
226
|
|
|
211
227
|
## License
|
|
212
228
|
|
package/bin/tm
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Launcher for the tm CLI bundled as a direct @excitedjs/dreamux dependency.
|
|
3
|
+
# Resolves its own location through symlinks so it works from npm global bins,
|
|
4
|
+
# npm-link, and source-checkout shortcuts.
|
|
5
|
+
set -eu
|
|
6
|
+
|
|
7
|
+
SOURCE="${BASH_SOURCE[0]}"
|
|
8
|
+
hop=0
|
|
9
|
+
while [ -L "$SOURCE" ]; do
|
|
10
|
+
hop=$((hop + 1))
|
|
11
|
+
if [ "$hop" -gt 40 ]; then
|
|
12
|
+
echo "tm: too many symlink hops resolving $SOURCE" >&2
|
|
13
|
+
exit 1
|
|
14
|
+
fi
|
|
15
|
+
TARGET="$(readlink "$SOURCE")"
|
|
16
|
+
if [ "${TARGET:0:1}" = "/" ]; then
|
|
17
|
+
SOURCE="$TARGET"
|
|
18
|
+
else
|
|
19
|
+
SOURCE="$(dirname -- "$SOURCE")/$TARGET"
|
|
20
|
+
fi
|
|
21
|
+
done
|
|
22
|
+
|
|
23
|
+
DIR="$(cd -- "$(dirname -- "$SOURCE")/.." &> /dev/null && pwd)"
|
|
24
|
+
TARGET="$DIR/node_modules/.bin/tm"
|
|
25
|
+
if [ ! -x "$TARGET" ]; then
|
|
26
|
+
echo "tm: $TARGET is missing." >&2
|
|
27
|
+
echo "Install dependencies first from the repo root: node common/scripts/install-run-rush.js update." >&2
|
|
28
|
+
exit 1
|
|
29
|
+
fi
|
|
30
|
+
exec "$TARGET" "$@"
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { connect } from 'node:net';
|
|
2
|
+
import { adminSocketPath as defaultAdminSocketPath } from '../runtime/paths.js';
|
|
3
|
+
export class AdminClientError extends Error {
|
|
4
|
+
code;
|
|
5
|
+
constructor(code, message) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.code = code;
|
|
8
|
+
this.name = 'AdminClientError';
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
const DEFAULT_TIMEOUT_MS = 10_000;
|
|
12
|
+
let nextRequestId = 1;
|
|
13
|
+
export function sendAdminRequest(method, params, options = {}) {
|
|
14
|
+
const socketPath = options.socketPath ?? defaultAdminSocketPath();
|
|
15
|
+
const request = {
|
|
16
|
+
id: options.requestId ?? adminRequestId(),
|
|
17
|
+
method,
|
|
18
|
+
params,
|
|
19
|
+
};
|
|
20
|
+
return sendOne(socketPath, request, options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
|
|
21
|
+
}
|
|
22
|
+
export function sendOneAdminRequest(socketPath, request, timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
23
|
+
return sendOne(socketPath, request, timeoutMs);
|
|
24
|
+
}
|
|
25
|
+
function sendOne(socketPath, request, timeoutMs) {
|
|
26
|
+
return new Promise((resolve, reject) => {
|
|
27
|
+
let buf = '';
|
|
28
|
+
let settled = false;
|
|
29
|
+
let sock = null;
|
|
30
|
+
const timer = setTimeout(() => {
|
|
31
|
+
settle(new Error(`admin socket request timed out after ${timeoutMs}ms`));
|
|
32
|
+
try {
|
|
33
|
+
sock?.destroy();
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
/* already gone */
|
|
37
|
+
}
|
|
38
|
+
}, timeoutMs);
|
|
39
|
+
timer.unref();
|
|
40
|
+
function settle(value, isError = true) {
|
|
41
|
+
if (settled)
|
|
42
|
+
return;
|
|
43
|
+
settled = true;
|
|
44
|
+
clearTimeout(timer);
|
|
45
|
+
if (isError)
|
|
46
|
+
reject(value);
|
|
47
|
+
else
|
|
48
|
+
resolve(value);
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
sock = connect(socketPath);
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
settle(err);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
sock.setEncoding('utf8');
|
|
58
|
+
sock.on('connect', () => {
|
|
59
|
+
sock.write(`${JSON.stringify(request)}\n`);
|
|
60
|
+
});
|
|
61
|
+
sock.on('data', (chunk) => {
|
|
62
|
+
buf += chunk;
|
|
63
|
+
const nl = buf.indexOf('\n');
|
|
64
|
+
if (nl === -1 || settled)
|
|
65
|
+
return;
|
|
66
|
+
const line = buf.slice(0, nl).trim();
|
|
67
|
+
try {
|
|
68
|
+
const response = JSON.parse(line);
|
|
69
|
+
if (response.ok)
|
|
70
|
+
settle(response.result, false);
|
|
71
|
+
else
|
|
72
|
+
settle(new AdminClientError(response.error.code, response.error.message));
|
|
73
|
+
}
|
|
74
|
+
catch (err) {
|
|
75
|
+
settle(err);
|
|
76
|
+
}
|
|
77
|
+
sock.end();
|
|
78
|
+
});
|
|
79
|
+
sock.on('error', (err) => {
|
|
80
|
+
if (settled)
|
|
81
|
+
return;
|
|
82
|
+
const code = err.code;
|
|
83
|
+
if (code === 'ENOENT' || code === 'ECONNREFUSED') {
|
|
84
|
+
settle(new Error(`cannot reach admin socket at ${socketPath} - is the server running?`));
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
settle(err);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
sock.on('close', () => {
|
|
91
|
+
settle(new Error('admin socket closed without a response'));
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
function adminRequestId() {
|
|
96
|
+
return `mcp-${process.pid}-${Date.now()}-${nextRequestId++}`;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/admin/client.ts"],"names":[],"mappings":"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"}
|