@excitedjs/dreamux 0.1.1

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 (59) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +223 -0
  3. package/bin/dreamux +31 -0
  4. package/bin/server +35 -0
  5. package/bin/server-ctl +28 -0
  6. package/db/migrations/0001_init.sql +49 -0
  7. package/dist/admin/methods.js +103 -0
  8. package/dist/admin/methods.js.map +1 -0
  9. package/dist/admin/protocol.js +15 -0
  10. package/dist/admin/protocol.js.map +1 -0
  11. package/dist/admin/socket.js +251 -0
  12. package/dist/admin/socket.js.map +1 -0
  13. package/dist/cli/dreamux.js +105 -0
  14. package/dist/cli/dreamux.js.map +1 -0
  15. package/dist/cli/server-ctl.js +172 -0
  16. package/dist/cli/server-ctl.js.map +1 -0
  17. package/dist/cli/server.js +88 -0
  18. package/dist/cli/server.js.map +1 -0
  19. package/dist/codex/events.js +82 -0
  20. package/dist/codex/events.js.map +1 -0
  21. package/dist/codex/handshake.js +85 -0
  22. package/dist/codex/handshake.js.map +1 -0
  23. package/dist/codex/rpc.js +200 -0
  24. package/dist/codex/rpc.js.map +1 -0
  25. package/dist/codex/supervisor.js +184 -0
  26. package/dist/codex/supervisor.js.map +1 -0
  27. package/dist/codex/types.js +10 -0
  28. package/dist/codex/types.js.map +1 -0
  29. package/dist/db/repository.js +207 -0
  30. package/dist/db/repository.js.map +1 -0
  31. package/dist/db/schema.js +29 -0
  32. package/dist/db/schema.js.map +1 -0
  33. package/dist/db/types.js +2 -0
  34. package/dist/db/types.js.map +1 -0
  35. package/dist/dispatcher/approval.js +43 -0
  36. package/dist/dispatcher/approval.js.map +1 -0
  37. package/dist/dispatcher/runtime.js +262 -0
  38. package/dist/dispatcher/runtime.js.map +1 -0
  39. package/dist/dispatcher/turn-manager.js +167 -0
  40. package/dist/dispatcher/turn-manager.js.map +1 -0
  41. package/dist/feishu/bot.js +137 -0
  42. package/dist/feishu/bot.js.map +1 -0
  43. package/dist/feishu/content.js +108 -0
  44. package/dist/feishu/content.js.map +1 -0
  45. package/dist/feishu/render.js +600 -0
  46. package/dist/feishu/render.js.map +1 -0
  47. package/dist/feishu/types.js +9 -0
  48. package/dist/feishu/types.js.map +1 -0
  49. package/dist/runtime/codex-args.js +92 -0
  50. package/dist/runtime/codex-args.js.map +1 -0
  51. package/dist/runtime/config.js +351 -0
  52. package/dist/runtime/config.js.map +1 -0
  53. package/dist/runtime/paths.js +77 -0
  54. package/dist/runtime/paths.js.map +1 -0
  55. package/dist/runtime/secrets.js +18 -0
  56. package/dist/runtime/secrets.js.map +1 -0
  57. package/dist/server.js +234 -0
  58. package/dist/server.js.map +1 -0
  59. package/package.json +43 -0
package/dist/server.js ADDED
@@ -0,0 +1,234 @@
1
+ /**
2
+ * The dreamux Server — the long-running Node process that hosts N dispatchers.
3
+ *
4
+ * Lifecycle:
5
+ * 1. open SQLite (migrate if needed)
6
+ * 2. open admin Unix socket (so server-ctl can talk to us even if a
7
+ * dispatcher fails to come up)
8
+ * 3. for each enabled dispatcher: spawn codex, open feishu, start turn worker
9
+ * 4. install SIGTERM/SIGINT handlers for graceful drain
10
+ *
11
+ * Issue #2 §"D1": crash recovery does NOT replay running turns. Per dispatcher,
12
+ * the runtime's startup sweep flips stale `running` → `unknown` before
13
+ * Feishu inbound is opened, so the user gets a visible prompt instead of a
14
+ * silent duplicate turn.
15
+ */
16
+ import { openDatabase } from './db/schema.js';
17
+ import { DispatcherRepo, InboundRepo } from './db/repository.js';
18
+ import { DispatcherRuntime } from './dispatcher/runtime.js';
19
+ import { createFeishuBot } from './feishu/bot.js';
20
+ import { parseCodexArgs, codexArgsToCli } from './runtime/codex-args.js';
21
+ import { resolveBotSecret } from './runtime/secrets.js';
22
+ import { BUILT_IN_DEFAULTS } from './runtime/config.js';
23
+ import { adminSocketPath, databasePath, dispatcherCodexCwd, setRuntimeConfig, } from './runtime/paths.js';
24
+ import { createAdminSocketServer } from './admin/socket.js';
25
+ export class Server {
26
+ repos;
27
+ db;
28
+ slots = new Map();
29
+ /**
30
+ * PR #3 review #4: in-flight startDispatcher promises, keyed by id.
31
+ * Two concurrent callers must await the same start, not race to spawn
32
+ * duplicate Codex children / Feishu listeners.
33
+ */
34
+ starting = new Map();
35
+ admin = null;
36
+ shuttingDown = false;
37
+ opts;
38
+ constructor(opts = {}) {
39
+ this.opts = opts;
40
+ // Install the config snapshot before any paths.* / runtime.* lookup
41
+ // happens. paths.runtimeRoot / adminSocketPath / etc. consult this
42
+ // snapshot for non-env defaults (env vars still win).
43
+ setRuntimeConfig(opts.config ?? BUILT_IN_DEFAULTS);
44
+ this.db = openDatabase({ path: opts.databasePath ?? databasePath() });
45
+ this.repos = {
46
+ dispatchers: new DispatcherRepo(this.db),
47
+ inbound: new InboundRepo(this.db),
48
+ };
49
+ }
50
+ /** Effective config (caller-supplied or built-in defaults). */
51
+ effectiveConfig() {
52
+ return this.opts.config ?? BUILT_IN_DEFAULTS;
53
+ }
54
+ /**
55
+ * Final codex binary path. Precedence:
56
+ * 1. ServerOptions.codexBinPath (test seam)
57
+ * 2. CODEX_HOST_CODEX_BIN env (CI / debug escape hatch)
58
+ * 3. config.codex.bin (~/.dreamux/config.toml)
59
+ * 4. 'codex' (PATH lookup)
60
+ */
61
+ resolveCodexBinPath() {
62
+ if (this.opts.codexBinPath !== undefined)
63
+ return this.opts.codexBinPath;
64
+ const fromEnv = process.env['CODEX_HOST_CODEX_BIN'];
65
+ if (fromEnv !== undefined && fromEnv !== '')
66
+ return fromEnv;
67
+ const fromConfig = this.effectiveConfig().codex.bin;
68
+ return fromConfig === '' ? undefined : fromConfig;
69
+ }
70
+ /** Bring up admin socket + all enabled dispatchers. */
71
+ async start() {
72
+ this.admin = createAdminSocketServer(this, this.opts.adminSocketPath ?? adminSocketPath());
73
+ await this.admin.start();
74
+ console.error(`[server] admin socket listening at ${this.admin.socketPath}`);
75
+ const rows = this.repos.dispatchers.listEnabled();
76
+ for (const row of rows) {
77
+ try {
78
+ await this.startDispatcher(row.dispatcher_id);
79
+ }
80
+ catch (err) {
81
+ console.error(`[server] dispatcher '${row.dispatcher_id}' failed to start:`, err);
82
+ // server keeps running; admin can inspect & retry via dispatcher.start
83
+ }
84
+ }
85
+ }
86
+ /** Bring one dispatcher up. Safe to call when already running (no-op). */
87
+ async startDispatcher(id) {
88
+ if (this.slots.has(id))
89
+ return;
90
+ // PR #3 review #4: another caller may already be mid-startup. The
91
+ // `slots.has(id)` check above only catches *finished* startups; without
92
+ // this in-flight map two concurrent calls (e.g. start() at boot + an
93
+ // admin dispatcher.start) would both pass and spawn duplicate Codex
94
+ // children / Feishu listeners. Coalesce on the first promise.
95
+ const inflight = this.starting.get(id);
96
+ if (inflight !== undefined)
97
+ return inflight;
98
+ const promise = this.doStartDispatcher(id).finally(() => {
99
+ this.starting.delete(id);
100
+ });
101
+ this.starting.set(id, promise);
102
+ return promise;
103
+ }
104
+ async doStartDispatcher(id) {
105
+ const row = this.repos.dispatchers.get(id);
106
+ if (row === null)
107
+ throw new Error(`no dispatcher '${id}'`);
108
+ // Re-check inside the critical section; a concurrent caller that won
109
+ // the race may have finished by the time we got scheduled.
110
+ if (this.slots.has(id))
111
+ return;
112
+ const cfg = this.effectiveConfig();
113
+ const codexArgs = parseCodexArgs(row.codex_args_json, {
114
+ approvalPolicy: cfg.codex.approval_policy,
115
+ sandboxMode: cfg.codex.sandbox_mode,
116
+ extraArgs: cfg.codex.extra_args,
117
+ });
118
+ const botSecret = this.opts.skipBotSecret
119
+ ? ''
120
+ : resolveBotSecret(row.bot_secret_ref);
121
+ const bot = this.opts.botFactory
122
+ ? this.opts.botFactory(row, botSecret)
123
+ : createFeishuBot({ appId: row.bot_app_id, appSecret: botSecret });
124
+ const runtime = new DispatcherRuntime(row, {
125
+ dispatchers: this.repos.dispatchers,
126
+ inbound: this.repos.inbound,
127
+ outbound: {
128
+ sendText: async (chatId, text) => (await bot.sendText(chatId, text)).messageIds,
129
+ },
130
+ codexBinPath: this.resolveCodexBinPath(),
131
+ codexProcessFactory: this.opts.codexProcessFactory,
132
+ codexClientFactory: this.opts.codexClientFactory,
133
+ resolveExtraArgs: () => codexArgsToCli(codexArgs),
134
+ handshakeTimeoutMs: cfg.codex.initialize_timeout_ms,
135
+ outboundRetries: cfg.outbound.retries,
136
+ outboundRetryDelayMs: cfg.outbound.retry_delay_ms,
137
+ });
138
+ try {
139
+ await runtime.start();
140
+ await bot.start(async (event) => {
141
+ runtime.enqueueInbound({
142
+ source_chat_id: event.chatId,
143
+ source_message_id: event.messageId,
144
+ sender_id: event.senderId,
145
+ feishu_event_json: safeStringify(event.raw),
146
+ parsed_text: event.parsedText,
147
+ });
148
+ });
149
+ }
150
+ catch (err) {
151
+ // Failed midway: undo any partial bring-up so a retry isn't
152
+ // racing leftovers. Best-effort — we still surface the original err.
153
+ try {
154
+ await bot.close();
155
+ }
156
+ catch {
157
+ /* */
158
+ }
159
+ try {
160
+ await runtime.stop();
161
+ }
162
+ catch {
163
+ /* */
164
+ }
165
+ throw err;
166
+ }
167
+ this.slots.set(id, { row, runtime, bot });
168
+ console.error(`[server] dispatcher '${id}' is ready (bot=${row.bot_app_id} cwd=${row.codex_cwd ?? dispatcherCodexCwd(id)})`);
169
+ }
170
+ /** Gracefully stop one dispatcher. Idempotent. */
171
+ async stopDispatcher(id) {
172
+ const slot = this.slots.get(id);
173
+ if (slot === undefined)
174
+ return;
175
+ try {
176
+ await slot.bot.close();
177
+ }
178
+ catch (err) {
179
+ console.error(`[server] error closing bot for '${id}':`, err);
180
+ }
181
+ try {
182
+ await slot.runtime.stop();
183
+ }
184
+ catch (err) {
185
+ console.error(`[server] error stopping dispatcher '${id}':`, err);
186
+ }
187
+ this.slots.delete(id);
188
+ }
189
+ getRuntime(id) {
190
+ return this.slots.get(id)?.runtime ?? null;
191
+ }
192
+ /** Summary of every declared dispatcher (DB-backed, includes stopped). */
193
+ summarize() {
194
+ return this.repos.dispatchers.list().map((row) => {
195
+ const runtime = this.slots.get(row.dispatcher_id)?.runtime;
196
+ return {
197
+ dispatcher_id: row.dispatcher_id,
198
+ bot_app_id: row.bot_app_id,
199
+ status: runtime?.getStatus() ?? row.status,
200
+ thread_id: runtime?.getThreadId() ?? row.thread_id,
201
+ enabled: row.enabled === 1,
202
+ };
203
+ });
204
+ }
205
+ /** Graceful shutdown — drain dispatchers, close socket, close DB. */
206
+ async shutdown() {
207
+ if (this.shuttingDown)
208
+ return;
209
+ this.shuttingDown = true;
210
+ console.error('[server] shutting down...');
211
+ for (const id of Array.from(this.slots.keys())) {
212
+ await this.stopDispatcher(id);
213
+ }
214
+ if (this.admin !== null) {
215
+ await this.admin.close();
216
+ this.admin = null;
217
+ }
218
+ try {
219
+ this.db.close();
220
+ }
221
+ catch (err) {
222
+ console.error('[server] db close error:', err);
223
+ }
224
+ }
225
+ }
226
+ function safeStringify(value) {
227
+ try {
228
+ return JSON.stringify(value);
229
+ }
230
+ catch {
231
+ return '{}';
232
+ }
233
+ }
234
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@excitedjs/dreamux",
3
+ "version": "0.1.1",
4
+ "description": "Codex-host server — single-session MVP. One node process hosts N dispatchers, each binding 1 Feishu bot + 1 Codex thread.",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "./dist/server.js",
8
+ "engines": {
9
+ "node": ">=22.7"
10
+ },
11
+ "bin": {
12
+ "dreamux": "./bin/dreamux",
13
+ "dreamux-server": "./bin/server",
14
+ "server-ctl": "./bin/server-ctl"
15
+ },
16
+ "files": [
17
+ "bin",
18
+ "dist",
19
+ "db",
20
+ "README.md",
21
+ "LICENSE"
22
+ ],
23
+ "dependencies": {
24
+ "better-sqlite3": "^11.5.0",
25
+ "smol-toml": "^1.6.1",
26
+ "ws": "^8.18.0",
27
+ "@excitedjs/feishu-transport": "0.0.1"
28
+ },
29
+ "devDependencies": {
30
+ "@types/better-sqlite3": "^7.6.12",
31
+ "@types/node": "^22.10.0",
32
+ "@types/ws": "^8.5.13",
33
+ "typescript": "^5.7.0",
34
+ "vitest": "^2.1.0"
35
+ },
36
+ "scripts": {
37
+ "build": "tsc -p tsconfig.json",
38
+ "typecheck": "tsc -p tsconfig.json --noEmit",
39
+ "test": "vitest run",
40
+ "test:watch": "vitest",
41
+ "clean": "rm -rf dist"
42
+ }
43
+ }