@excitedjs/agent-runtime-codex 0.2.0-alpha.g0ddd418597ca

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 (103) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +44 -0
  3. package/dist/approval.d.ts +30 -0
  4. package/dist/approval.d.ts.map +1 -0
  5. package/dist/approval.js +42 -0
  6. package/dist/approval.js.map +1 -0
  7. package/dist/args.d.ts +55 -0
  8. package/dist/args.d.ts.map +1 -0
  9. package/dist/args.js +113 -0
  10. package/dist/args.js.map +1 -0
  11. package/dist/bin.d.ts +14 -0
  12. package/dist/bin.d.ts.map +1 -0
  13. package/dist/bin.js +18 -0
  14. package/dist/bin.js.map +1 -0
  15. package/dist/codex-home.d.ts +42 -0
  16. package/dist/codex-home.d.ts.map +1 -0
  17. package/dist/codex-home.js +112 -0
  18. package/dist/codex-home.js.map +1 -0
  19. package/dist/config.d.ts +76 -0
  20. package/dist/config.d.ts.map +1 -0
  21. package/dist/config.js +106 -0
  22. package/dist/config.js.map +1 -0
  23. package/dist/diagnostic.d.ts +14 -0
  24. package/dist/diagnostic.d.ts.map +1 -0
  25. package/dist/diagnostic.js +58 -0
  26. package/dist/diagnostic.js.map +1 -0
  27. package/dist/events.d.ts +88 -0
  28. package/dist/events.d.ts.map +1 -0
  29. package/dist/events.js +225 -0
  30. package/dist/events.js.map +1 -0
  31. package/dist/handshake.d.ts +44 -0
  32. package/dist/handshake.d.ts.map +1 -0
  33. package/dist/handshake.js +85 -0
  34. package/dist/handshake.js.map +1 -0
  35. package/dist/index.d.ts +22 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +24 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/internal/completion-body.d.ts +38 -0
  40. package/dist/internal/completion-body.d.ts.map +1 -0
  41. package/dist/internal/completion-body.js +62 -0
  42. package/dist/internal/completion-body.js.map +1 -0
  43. package/dist/internal/config-validate.d.ts +23 -0
  44. package/dist/internal/config-validate.d.ts.map +1 -0
  45. package/dist/internal/config-validate.js +122 -0
  46. package/dist/internal/config-validate.js.map +1 -0
  47. package/dist/internal/os.d.ts +30 -0
  48. package/dist/internal/os.d.ts.map +1 -0
  49. package/dist/internal/os.js +81 -0
  50. package/dist/internal/os.js.map +1 -0
  51. package/dist/internal/socket.d.ts +23 -0
  52. package/dist/internal/socket.d.ts.map +1 -0
  53. package/dist/internal/socket.js +74 -0
  54. package/dist/internal/socket.js.map +1 -0
  55. package/dist/internal/turn-render.d.ts +22 -0
  56. package/dist/internal/turn-render.d.ts.map +1 -0
  57. package/dist/internal/turn-render.js +40 -0
  58. package/dist/internal/turn-render.js.map +1 -0
  59. package/dist/mcp-config.d.ts +9 -0
  60. package/dist/mcp-config.d.ts.map +1 -0
  61. package/dist/mcp-config.js +21 -0
  62. package/dist/mcp-config.js.map +1 -0
  63. package/dist/paths.d.ts +7 -0
  64. package/dist/paths.d.ts.map +1 -0
  65. package/dist/paths.js +26 -0
  66. package/dist/paths.js.map +1 -0
  67. package/dist/provider-ref.d.ts +8 -0
  68. package/dist/provider-ref.d.ts.map +1 -0
  69. package/dist/provider-ref.js +8 -0
  70. package/dist/provider-ref.js.map +1 -0
  71. package/dist/provider.d.ts +71 -0
  72. package/dist/provider.d.ts.map +1 -0
  73. package/dist/provider.js +137 -0
  74. package/dist/provider.js.map +1 -0
  75. package/dist/rpc.d.ts +65 -0
  76. package/dist/rpc.d.ts.map +1 -0
  77. package/dist/rpc.js +200 -0
  78. package/dist/rpc.js.map +1 -0
  79. package/dist/runtime-support.d.ts +27 -0
  80. package/dist/runtime-support.d.ts.map +1 -0
  81. package/dist/runtime-support.js +57 -0
  82. package/dist/runtime-support.js.map +1 -0
  83. package/dist/runtime.d.ts +246 -0
  84. package/dist/runtime.d.ts.map +1 -0
  85. package/dist/runtime.js +648 -0
  86. package/dist/runtime.js.map +1 -0
  87. package/dist/supervisor.d.ts +55 -0
  88. package/dist/supervisor.d.ts.map +1 -0
  89. package/dist/supervisor.js +183 -0
  90. package/dist/supervisor.js.map +1 -0
  91. package/dist/turn-manager.d.ts +92 -0
  92. package/dist/turn-manager.d.ts.map +1 -0
  93. package/dist/turn-manager.js +271 -0
  94. package/dist/turn-manager.js.map +1 -0
  95. package/dist/types.d.ts +143 -0
  96. package/dist/types.d.ts.map +1 -0
  97. package/dist/types.js +10 -0
  98. package/dist/types.js.map +1 -0
  99. package/dist/version.d.ts +16 -0
  100. package/dist/version.d.ts.map +1 -0
  101. package/dist/version.js +33 -0
  102. package/dist/version.js.map +1 -0
  103. package/package.json +56 -0
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Codex app-server LSP-style init handshake (required by codex 0.134+).
3
+ *
4
+ * Without this, every business RPC (`thread/start`, `turn/start`, …) is
5
+ * answered with `Not initialized` and the daemon never moves. The sequence
6
+ * is the canonical LSP one:
7
+ *
8
+ * 1. client → `initialize` request with ClientInfo + capabilities
9
+ * 2. server → InitializeResponse (userAgent, codexHome, platform info)
10
+ * 3. client → `initialized` notification (no params)
11
+ *
12
+ * Steps 1 + 3 are both required: codex's `Not initialized` guard is cleared
13
+ * only once the notification arrives. Capabilities can be omitted (the spec
14
+ * accepts `null`) — we pass an explicit default so the negotiation choices
15
+ * are visible in the source.
16
+ */
17
+ /**
18
+ * Our default ClientInfo. Picked once at module load so the version doesn't
19
+ * have to be threaded through every call site. Keep in sync with package.json.
20
+ */
21
+ const DREAMUX_CLIENT_INFO = {
22
+ name: 'dreamux',
23
+ title: 'dreamux Codex-host server',
24
+ version: '0.1.0',
25
+ };
26
+ const DEFAULT_CAPABILITIES = {
27
+ // We don't currently consume any experimental method, but turning this on
28
+ // is harmless — codex only widens the set of method/field shapes it'll
29
+ // emit. Keeping it true avoids a future surprise if we start consuming an
30
+ // experimental notification (e.g. turn/streaming) and the daemon was
31
+ // silently dropping it because of this flag.
32
+ experimentalApi: true,
33
+ // We do not handle attestation requests; do not invite them.
34
+ requestAttestation: false,
35
+ };
36
+ /**
37
+ * Default cap on the initialize round-trip. See HandshakeOptions.timeoutMs.
38
+ * 10s mirrors CodexProcess's spawn ready-probe so a hung handshake doesn't
39
+ * outlive the codex spawn that produced it.
40
+ */
41
+ const DEFAULT_HANDSHAKE_TIMEOUT_MS = 10_000;
42
+ /**
43
+ * Drive the full `initialize` + `initialized` exchange. Returns the
44
+ * server's InitializeResponse (userAgent, codexHome, platform) so callers
45
+ * can log it or surface it via admin.
46
+ *
47
+ * Times out (rejects) if the daemon does not reply within
48
+ * `options.timeoutMs`. The pending request stays in the client's `pending`
49
+ * map after timeout — callers that recover by tearing down the client
50
+ * (e.g. CodexRuntime's cleanupOnFailure) will then drop those
51
+ * pending entries when the WS connection closes.
52
+ */
53
+ export async function performInitializeHandshake(client, options = {}) {
54
+ const params = {
55
+ clientInfo: options.clientInfo ?? DREAMUX_CLIENT_INFO,
56
+ capabilities: options.capabilities === undefined
57
+ ? DEFAULT_CAPABILITIES
58
+ : options.capabilities,
59
+ };
60
+ const timeoutMs = options.timeoutMs ?? DEFAULT_HANDSHAKE_TIMEOUT_MS;
61
+ const response = await withTimeout(client.request('initialize', params), timeoutMs, `codex initialize handshake did not respond within ${timeoutMs}ms — the daemon may be hung, crashed mid-response, or speaking an incompatible protocol`);
62
+ // Per LSP convention the `initialized` notification carries no params.
63
+ // codex's ClientNotification union accepts the bare `{ method: "initialized" }`
64
+ // envelope without a `params` field.
65
+ client.notify('initialized', undefined);
66
+ return response;
67
+ }
68
+ /**
69
+ * Race `p` against a timeout. Rejects with `Error(msg)` if the timeout wins.
70
+ * The timer is `unref`ed so it doesn't keep the event loop alive on its own.
71
+ */
72
+ function withTimeout(p, ms, msg) {
73
+ return new Promise((resolve, reject) => {
74
+ const timer = setTimeout(() => reject(new Error(msg)), ms);
75
+ timer.unref();
76
+ p.then((v) => {
77
+ clearTimeout(timer);
78
+ resolve(v);
79
+ }, (err) => {
80
+ clearTimeout(timer);
81
+ reject(err);
82
+ });
83
+ });
84
+ }
85
+ //# sourceMappingURL=handshake.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handshake.js","sourceRoot":"","sources":["../src/handshake.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAUH;;;GAGG;AACH,MAAM,mBAAmB,GAAe;IACtC,IAAI,EAAE,SAAS;IACf,KAAK,EAAE,2BAA2B;IAClC,OAAO,EAAE,OAAO;CACjB,CAAC;AAEF,MAAM,oBAAoB,GAA2B;IACnD,0EAA0E;IAC1E,uEAAuE;IACvE,0EAA0E;IAC1E,qEAAqE;IACrE,6CAA6C;IAC7C,eAAe,EAAE,IAAI;IACrB,6DAA6D;IAC7D,kBAAkB,EAAE,KAAK;CAC1B,CAAC;AAgBF;;;;GAIG;AACH,MAAM,4BAA4B,GAAG,MAAM,CAAC;AAE5C;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,MAAqB,EACrB,UAA4B,EAAE;IAE9B,MAAM,MAAM,GAAqB;QAC/B,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,mBAAmB;QACrD,YAAY,EACV,OAAO,CAAC,YAAY,KAAK,SAAS;YAChC,CAAC,CAAC,oBAAoB;YACtB,CAAC,CAAC,OAAO,CAAC,YAAY;KAC3B,CAAC;IACF,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,4BAA4B,CAAC;IACpE,MAAM,QAAQ,GAAG,MAAM,WAAW,CAChC,MAAM,CAAC,OAAO,CAAqB,YAAY,EAAE,MAAM,CAAC,EACxD,SAAS,EACT,qDAAqD,SAAS,yFAAyF,CACxJ,CAAC;IACF,uEAAuE;IACvE,gFAAgF;IAChF,qCAAqC;IACrC,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;IACxC,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;GAGG;AACH,SAAS,WAAW,CAClB,CAAa,EACb,EAAU,EACV,GAAW;IAEX,OAAO,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACxC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC3D,KAAK,CAAC,KAAK,EAAE,CAAC;QACd,CAAC,CAAC,IAAI,CACJ,CAAC,CAAC,EAAE,EAAE;YACJ,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,OAAO,CAAC,CAAC,CAAC,CAAC;QACb,CAAC,EACD,CAAC,GAAG,EAAE,EAAE;YACN,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,MAAM,CAAC,GAAG,CAAC,CAAC;QACd,CAAC,CACF,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * `@excitedjs/agent-runtime-codex` — the built-in Codex Agent Runtime provider
3
+ * for Dreamux (alias `builtin:codex`). Implements the
4
+ * `@excitedjs/dreamux-types` `AgentRuntimeProvider` contract; never imports
5
+ * `@excitedjs/dreamux` core.
6
+ */
7
+ export { default, createCodexAgentRuntimeProvider, codexRuntimeArgsForMcpServers, dispatcherCodexConfig, CODEX_AGENT_RUNTIME_CAPABILITIES, type CodexAgentRuntimeProviderOptions, type CodexProviderFactoryContext, } from './provider.js';
8
+ export { resolveCodexBinPath } from './bin.js';
9
+ export { CodexRuntime, type CodexRuntimeDeps, } from './runtime.js';
10
+ export { CodexProcess, type CodexProcessOptions, type CodexProcessExit, type CodexProcessExitHandler, } from './supervisor.js';
11
+ export { CodexWsClient, type CodexWsClientOptions, type NotificationHandler, } from './rpc.js';
12
+ export type { ServerNotification, ServerRequest, ThreadStartResponse, TurnStartResponse, } from './types.js';
13
+ export { performInitializeHandshake } from './handshake.js';
14
+ export { codexMcpServerArgs } from './mcp-config.js';
15
+ export { parseCodexArgs, codexArgsFromConfig, codexArgsToCli, type ParsedCodexArgs, } from './args.js';
16
+ export { type DispatcherCodexConfig, readDispatcherCodexConfig, defaultDispatcherCodexConfig, DEFAULT_CODEX_BIN, DEFAULT_INITIALIZE_TIMEOUT_MS, DEFAULT_CODEX_TURN_TIMEOUT_MS, DEFAULT_APPROVAL_POLICY, DEFAULT_SANDBOX_MODE, ALLOWED_APPROVAL_POLICIES, ALLOWED_SANDBOX_MODES, } from './config.js';
17
+ export { MIN_CODEX_VERSION, parseCodexVersion, codexVersionSatisfies, } from './version.js';
18
+ export { BUILTIN_CODEX_PROVIDER_REF } from './provider-ref.js';
19
+ export { codexAgentRuntimeDiagnostic } from './diagnostic.js';
20
+ export { DISPATCHER_APP_SERVER_SOCKET_PATH_MAX_BYTES, dispatcherCodexHomeDoctorContext, validateDispatcherCodexHome, assertDispatcherCodexHomeReady, formatDispatcherCodexHomeErrors, type DispatcherCodexHomeDoctor, type DispatcherCodexHomeDoctorContext, type DispatcherCodexHomeDoctorResult, } from './codex-home.js';
21
+ export { operatorCodexHome, dispatcherCodexHome, dispatcherCodexConfigPath, } from './paths.js';
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,OAAO,EACP,+BAA+B,EAC/B,6BAA6B,EAC7B,qBAAqB,EACrB,gCAAgC,EAChC,KAAK,gCAAgC,EACrC,KAAK,2BAA2B,GACjC,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAE/C,OAAO,EACL,YAAY,EACZ,KAAK,gBAAgB,GACtB,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,YAAY,EACZ,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,GAC7B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,aAAa,EACb,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,GACzB,MAAM,UAAU,CAAC;AAElB,YAAY,EACV,kBAAkB,EAClB,aAAa,EACb,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAE5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAErD,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,cAAc,EACd,KAAK,eAAe,GACrB,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,KAAK,qBAAqB,EAC1B,yBAAyB,EACzB,4BAA4B,EAC5B,iBAAiB,EACjB,6BAA6B,EAC7B,6BAA6B,EAC7B,uBAAuB,EACvB,oBAAoB,EACpB,yBAAyB,EACzB,qBAAqB,GACtB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AAK/D,OAAO,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AAE9D,OAAO,EACL,2CAA2C,EAC3C,gCAAgC,EAChC,2BAA2B,EAC3B,8BAA8B,EAC9B,+BAA+B,EAC/B,KAAK,yBAAyB,EAC9B,KAAK,gCAAgC,EACrC,KAAK,+BAA+B,GACrC,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,yBAAyB,GAC1B,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,24 @@
1
+ /**
2
+ * `@excitedjs/agent-runtime-codex` — the built-in Codex Agent Runtime provider
3
+ * for Dreamux (alias `builtin:codex`). Implements the
4
+ * `@excitedjs/dreamux-types` `AgentRuntimeProvider` contract; never imports
5
+ * `@excitedjs/dreamux` core.
6
+ */
7
+ export { default, createCodexAgentRuntimeProvider, codexRuntimeArgsForMcpServers, dispatcherCodexConfig, CODEX_AGENT_RUNTIME_CAPABILITIES, } from './provider.js';
8
+ export { resolveCodexBinPath } from './bin.js';
9
+ export { CodexRuntime, } from './runtime.js';
10
+ export { CodexProcess, } from './supervisor.js';
11
+ export { CodexWsClient, } from './rpc.js';
12
+ export { performInitializeHandshake } from './handshake.js';
13
+ export { codexMcpServerArgs } from './mcp-config.js';
14
+ export { parseCodexArgs, codexArgsFromConfig, codexArgsToCli, } from './args.js';
15
+ export { readDispatcherCodexConfig, defaultDispatcherCodexConfig, DEFAULT_CODEX_BIN, DEFAULT_INITIALIZE_TIMEOUT_MS, DEFAULT_CODEX_TURN_TIMEOUT_MS, DEFAULT_APPROVAL_POLICY, DEFAULT_SANDBOX_MODE, ALLOWED_APPROVAL_POLICIES, ALLOWED_SANDBOX_MODES, } from './config.js';
16
+ export { MIN_CODEX_VERSION, parseCodexVersion, codexVersionSatisfies, } from './version.js';
17
+ export { BUILTIN_CODEX_PROVIDER_REF } from './provider-ref.js';
18
+ // The codex doctor surface now lives in this package (issue #209 cleanup): the
19
+ // neutral diagnostic, the Codex home/auth validation, and the Codex home/config
20
+ // path resolvers. Core's doctor + onboard consume these directly.
21
+ export { codexAgentRuntimeDiagnostic } from './diagnostic.js';
22
+ export { DISPATCHER_APP_SERVER_SOCKET_PATH_MAX_BYTES, dispatcherCodexHomeDoctorContext, validateDispatcherCodexHome, assertDispatcherCodexHomeReady, formatDispatcherCodexHomeErrors, } from './codex-home.js';
23
+ export { operatorCodexHome, dispatcherCodexHome, dispatcherCodexConfigPath, } from './paths.js';
24
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,OAAO,EACP,+BAA+B,EAC/B,6BAA6B,EAC7B,qBAAqB,EACrB,gCAAgC,GAGjC,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAE/C,OAAO,EACL,YAAY,GAEb,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,YAAY,GAIb,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,aAAa,GAGd,MAAM,UAAU,CAAC;AASlB,OAAO,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAC;AAE5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAErD,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,cAAc,GAEf,MAAM,WAAW,CAAC;AAEnB,OAAO,EAEL,yBAAyB,EACzB,4BAA4B,EAC5B,iBAAiB,EACjB,6BAA6B,EAC7B,6BAA6B,EAC7B,uBAAuB,EACvB,oBAAoB,EACpB,yBAAyB,EACzB,qBAAqB,GACtB,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AAE/D,+EAA+E;AAC/E,gFAAgF;AAChF,kEAAkE;AAClE,OAAO,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AAE9D,OAAO,EACL,2CAA2C,EAC3C,gCAAgC,EAChC,2BAA2B,EAC3B,8BAA8B,EAC9B,+BAA+B,GAIhC,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,iBAAiB,EACjB,mBAAmB,EACnB,yBAAyB,GAC1B,MAAM,YAAY,CAAC"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Neutral completion-body resolution for the Codex runtime.
3
+ *
4
+ * A teammate completion is delivered back to the dispatcher as turn text. When
5
+ * the result is short it is inlined verbatim; when it overflows the inline
6
+ * budget the full result is spilled to an owner-only 0600 file under the
7
+ * host-supplied spill directory and only the path is inlined, so a large result
8
+ * never floods the dispatcher's context window.
9
+ *
10
+ * Vendored from the host's neutral `agent-runtime/completion-body.ts` so this
11
+ * package never imports `@excitedjs/dreamux` core. The spill directory is
12
+ * supplied by the host through the create context's path context, so this
13
+ * module owns no Dreamux layout contract — only the safe filename shape inside
14
+ * that directory.
15
+ */
16
+ import type { CompletionEnvelope } from '@excitedjs/dreamux-types';
17
+ export declare const COMPLETION_INLINE_BUDGET_DEFAULT = 32000;
18
+ export declare const COMPLETION_INLINE_BUDGET_MAX = 160000;
19
+ export type ResolvedCompletionBody = {
20
+ kind: 'inline';
21
+ text: string;
22
+ } | {
23
+ kind: 'spilled';
24
+ path: string;
25
+ };
26
+ /**
27
+ * Resolve the effective inline budget from the environment: unset/blank or
28
+ * non-positive falls back to the default; values above the upper bound are
29
+ * clamped; a non-integer value falls back to the default.
30
+ */
31
+ export declare function completionInlineBudget(env?: NodeJS.ProcessEnv): number;
32
+ /**
33
+ * Decide whether a completion result is inlined or spilled. Spilling writes the
34
+ * FULL result to a 0600 file (async fs only) under the host-supplied
35
+ * `spillDir`, then returns the path; the caller inlines only that path.
36
+ */
37
+ export declare function resolveCompletionBody(completion: CompletionEnvelope, spillDir: string): Promise<ResolvedCompletionBody>;
38
+ //# sourceMappingURL=completion-body.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"completion-body.d.ts","sourceRoot":"","sources":["../../src/internal/completion-body.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAKH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAInE,eAAO,MAAM,gCAAgC,QAAS,CAAC;AACvD,eAAO,MAAM,4BAA4B,SAAU,CAAC;AAGpD,MAAM,MAAM,sBAAsB,GAC9B;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAgBtC;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,GAAE,MAAM,CAAC,UAAmC,GAC9C,MAAM,CAUR;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,kBAAkB,EAC9B,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,sBAAsB,CAAC,CAUjC"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Neutral completion-body resolution for the Codex runtime.
3
+ *
4
+ * A teammate completion is delivered back to the dispatcher as turn text. When
5
+ * the result is short it is inlined verbatim; when it overflows the inline
6
+ * budget the full result is spilled to an owner-only 0600 file under the
7
+ * host-supplied spill directory and only the path is inlined, so a large result
8
+ * never floods the dispatcher's context window.
9
+ *
10
+ * Vendored from the host's neutral `agent-runtime/completion-body.ts` so this
11
+ * package never imports `@excitedjs/dreamux` core. The spill directory is
12
+ * supplied by the host through the create context's path context, so this
13
+ * module owns no Dreamux layout contract — only the safe filename shape inside
14
+ * that directory.
15
+ */
16
+ import { chmod, writeFile } from 'node:fs/promises';
17
+ import { join } from 'node:path';
18
+ import { ensureOwnerOnlyDir } from './os.js';
19
+ export const COMPLETION_INLINE_BUDGET_DEFAULT = 32_000;
20
+ export const COMPLETION_INLINE_BUDGET_MAX = 160_000;
21
+ const COMPLETION_INLINE_BUDGET_ENV = 'TASK_MAX_OUTPUT_LENGTH';
22
+ /** Sanitize a name into a safe single path segment. */
23
+ function safeSegment(name) {
24
+ return name.replace(/[^A-Za-z0-9._-]/g, '_');
25
+ }
26
+ /** Spill file for an overflowing completion result, inside `spillDir`. */
27
+ function completionOutputPath(spillDir, source, id) {
28
+ return join(spillDir, `teammate-${safeSegment(source)}-${safeSegment(id)}.output`);
29
+ }
30
+ /**
31
+ * Resolve the effective inline budget from the environment: unset/blank or
32
+ * non-positive falls back to the default; values above the upper bound are
33
+ * clamped; a non-integer value falls back to the default.
34
+ */
35
+ export function completionInlineBudget(env = globalThis.process.env) {
36
+ const raw = env[COMPLETION_INLINE_BUDGET_ENV]?.trim();
37
+ if (raw === undefined || raw === '' || !/^\d+$/.test(raw)) {
38
+ return COMPLETION_INLINE_BUDGET_DEFAULT;
39
+ }
40
+ const parsed = Number(raw);
41
+ if (parsed <= 0) {
42
+ return COMPLETION_INLINE_BUDGET_DEFAULT;
43
+ }
44
+ return Math.min(parsed, COMPLETION_INLINE_BUDGET_MAX);
45
+ }
46
+ /**
47
+ * Decide whether a completion result is inlined or spilled. Spilling writes the
48
+ * FULL result to a 0600 file (async fs only) under the host-supplied
49
+ * `spillDir`, then returns the path; the caller inlines only that path.
50
+ */
51
+ export async function resolveCompletionBody(completion, spillDir) {
52
+ const budget = completionInlineBudget();
53
+ if (completion.result.length <= budget) {
54
+ return { kind: 'inline', text: completion.result };
55
+ }
56
+ const path = completionOutputPath(spillDir, completion.source, completion.id);
57
+ await ensureOwnerOnlyDir(spillDir);
58
+ await writeFile(path, completion.result, { mode: 0o600 });
59
+ await chmod(path, 0o600);
60
+ return { kind: 'spilled', path };
61
+ }
62
+ //# sourceMappingURL=completion-body.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"completion-body.js","sourceRoot":"","sources":["../../src/internal/completion-body.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAIjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAE7C,MAAM,CAAC,MAAM,gCAAgC,GAAG,MAAM,CAAC;AACvD,MAAM,CAAC,MAAM,4BAA4B,GAAG,OAAO,CAAC;AACpD,MAAM,4BAA4B,GAAG,wBAAwB,CAAC;AAM9D,uDAAuD;AACvD,SAAS,WAAW,CAAC,IAAY;IAC/B,OAAO,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC;AAC/C,CAAC;AAED,0EAA0E;AAC1E,SAAS,oBAAoB,CAC3B,QAAgB,EAChB,MAAc,EACd,EAAU;IAEV,OAAO,IAAI,CAAC,QAAQ,EAAE,YAAY,WAAW,CAAC,MAAM,CAAC,IAAI,WAAW,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;AACrF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CACpC,MAAyB,UAAU,CAAC,OAAO,CAAC,GAAG;IAE/C,MAAM,GAAG,GAAG,GAAG,CAAC,4BAA4B,CAAC,EAAE,IAAI,EAAE,CAAC;IACtD,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1D,OAAO,gCAAgC,CAAC;IAC1C,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC3B,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;QAChB,OAAO,gCAAgC,CAAC;IAC1C,CAAC;IACD,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,4BAA4B,CAAC,CAAC;AACxD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,UAA8B,EAC9B,QAAgB;IAEhB,MAAM,MAAM,GAAG,sBAAsB,EAAE,CAAC;IACxC,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,EAAE,CAAC;QACvC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC;IACrD,CAAC;IACD,MAAM,IAAI,GAAG,oBAAoB,CAAC,QAAQ,EAAE,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC;IAC9E,MAAM,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IACnC,MAAM,SAAS,CAAC,IAAI,EAAE,UAAU,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC1D,MAAM,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACzB,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AACnC,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Neutral config validation primitives.
3
+ *
4
+ * Extracted from `config/config.ts` so that per-runtime config readers (each
5
+ * builtin's `agent-runtime/builtin/<name>/config.ts`) can validate their own
6
+ * config blocks without importing `config/config.ts` — importing the host
7
+ * config module from a builtin would re-form the builtin -> config import
8
+ * cycle. These helpers are runtime-agnostic: they only know about JSON shapes
9
+ * and produce `dreamux config error in <file>: ...` messages.
10
+ */
11
+ export declare function isPlainObject(v: unknown): v is Record<string, unknown>;
12
+ export declare function describeType(v: unknown): string;
13
+ export declare function rejectUnknownKeys(obj: Record<string, unknown>, allowed: Set<string>, file: string, prefix: string): void;
14
+ export declare function requireNonEmptyString(obj: Record<string, unknown>, key: string, file: string, prefix?: string): string;
15
+ export declare function readOptionalString(obj: Record<string, unknown>, key: string, file: string, prefix?: string): string | null;
16
+ export declare function readOptionalBoolean(obj: Record<string, unknown>, key: string, fallback: boolean, file: string, prefix?: string): boolean;
17
+ export declare function requireStringArray(obj: Record<string, unknown>, key: string, fallback: string[], file: string, prefix?: string): string[];
18
+ export declare function requireStringRecord(obj: Record<string, unknown>, key: string, fallback: Record<string, string>, file: string, prefix?: string): Record<string, string>;
19
+ export declare function requirePositiveInt(obj: Record<string, unknown>, key: string, fallback: number, file: string, prefix?: string): number;
20
+ export declare function readProviderConfigObject(rawConfig: unknown, file: string, name: string, options?: {
21
+ allowMissing?: boolean;
22
+ }): Record<string, unknown>;
23
+ //# sourceMappingURL=config-validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-validate.d.ts","sourceRoot":"","sources":["../../src/internal/config-validate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEtE;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAI/C;AAED,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,EACpB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GACb,IAAI,CAgBN;AAuBD,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,MAAM,SAAK,GACV,MAAM,CAMR;AAED,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,MAAM,SAAK,GACV,MAAM,GAAG,IAAI,CAIf;AAED,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,OAAO,EACjB,IAAI,EAAE,MAAM,EACZ,MAAM,SAAK,GACV,OAAO,CAOT;AAED,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAAE,EAClB,IAAI,EAAE,MAAM,EACZ,MAAM,SAAK,GACV,MAAM,EAAE,CAgBV;AAED,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAChC,IAAI,EAAE,MAAM,EACZ,MAAM,SAAK,GACV,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAkBxB;AAgBD,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,MAAM,SAAK,GACV,MAAM,CASR;AAED,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,OAAO,EAClB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAA;CAAO,GACvC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAQzB"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Neutral config validation primitives.
3
+ *
4
+ * Extracted from `config/config.ts` so that per-runtime config readers (each
5
+ * builtin's `agent-runtime/builtin/<name>/config.ts`) can validate their own
6
+ * config blocks without importing `config/config.ts` — importing the host
7
+ * config module from a builtin would re-form the builtin -> config import
8
+ * cycle. These helpers are runtime-agnostic: they only know about JSON shapes
9
+ * and produce `dreamux config error in <file>: ...` messages.
10
+ */
11
+ export function isPlainObject(v) {
12
+ return v !== null && typeof v === 'object' && !Array.isArray(v);
13
+ }
14
+ export function describeType(v) {
15
+ if (v === null)
16
+ return 'null';
17
+ if (Array.isArray(v))
18
+ return 'array';
19
+ return typeof v;
20
+ }
21
+ export function rejectUnknownKeys(obj, allowed, file, prefix) {
22
+ for (const key of Object.keys(obj)) {
23
+ if (allowed.has(key))
24
+ continue;
25
+ const name = `${prefix}${key}`;
26
+ if (/^dispatchers\[\d+\]\.$/.test(prefix) && (key === 'feishu' || key === 'codex')) {
27
+ throw new Error(`dreamux config error in ${file}: ${name} is not supported by the providerized config v2 schema.\n` +
28
+ 'Dreamux 0.x does not silently migrate operator-owned config. Rebuild this dispatcher with ' +
29
+ 'dispatchers[].channels[] for the channel and a named agents[] entry referenced via ' +
30
+ 'dispatchers[].agentRuntime for the runtime, then restart.');
31
+ }
32
+ throw new Error(`dreamux config error in ${file}: ${name} is not supported by the providerized config v2 schema`);
33
+ }
34
+ }
35
+ function ensureString(v, key, file) {
36
+ if (typeof v !== 'string') {
37
+ throw new Error(`dreamux config error in ${file}: ${key} must be a string (got ${describeType(v)})`);
38
+ }
39
+ return v;
40
+ }
41
+ function requireString(obj, key, fallback, file, prefix = '') {
42
+ const v = obj[key];
43
+ if (v === undefined)
44
+ return fallback;
45
+ return ensureString(v, `${prefix}${key}`, file);
46
+ }
47
+ export function requireNonEmptyString(obj, key, file, prefix = '') {
48
+ const value = requireString(obj, key, '', file, prefix);
49
+ if (value.trim() !== '')
50
+ return value;
51
+ throw new Error(`dreamux config error in ${file}: ${prefix}${key} must be a non-empty string`);
52
+ }
53
+ export function readOptionalString(obj, key, file, prefix = '') {
54
+ const v = obj[key];
55
+ if (v === undefined || v === null)
56
+ return null;
57
+ return ensureString(v, `${prefix}${key}`, file);
58
+ }
59
+ export function readOptionalBoolean(obj, key, fallback, file, prefix = '') {
60
+ const v = obj[key];
61
+ if (v === undefined)
62
+ return fallback;
63
+ if (typeof v === 'boolean')
64
+ return v;
65
+ throw new Error(`dreamux config error in ${file}: ${prefix}${key} must be a boolean (got ${describeType(v)})`);
66
+ }
67
+ export function requireStringArray(obj, key, fallback, file, prefix = '') {
68
+ const v = obj[key];
69
+ if (v === undefined)
70
+ return fallback;
71
+ if (!Array.isArray(v)) {
72
+ throw new Error(`dreamux config error in ${file}: ${prefix}${key} must be an array of strings (got ${describeType(v)})`);
73
+ }
74
+ return v.map((item, i) => {
75
+ if (typeof item !== 'string') {
76
+ throw new Error(`dreamux config error in ${file}: ${prefix}${key}[${i}] must be a string (got ${describeType(item)})`);
77
+ }
78
+ return item;
79
+ });
80
+ }
81
+ export function requireStringRecord(obj, key, fallback, file, prefix = '') {
82
+ const v = obj[key];
83
+ if (v === undefined)
84
+ return { ...fallback };
85
+ if (!isPlainObject(v)) {
86
+ throw new Error(`dreamux config error in ${file}: ${prefix}${key} must be an object of strings (got ${describeType(v)})`);
87
+ }
88
+ const out = {};
89
+ for (const [entryKey, entryValue] of Object.entries(v)) {
90
+ if (typeof entryValue !== 'string') {
91
+ throw new Error(`dreamux config error in ${file}: ${prefix}${key}.${entryKey} must be a string (got ${describeType(entryValue)})`);
92
+ }
93
+ out[entryKey] = entryValue;
94
+ }
95
+ return out;
96
+ }
97
+ function readInt(obj, key, file, prefix) {
98
+ const v = obj[key];
99
+ if (v === undefined)
100
+ return null;
101
+ if (typeof v === 'number' && Number.isInteger(v))
102
+ return v;
103
+ throw new Error(`dreamux config error in ${file}: ${prefix}${key} must be an integer (got ${describeType(v)})`);
104
+ }
105
+ export function requirePositiveInt(obj, key, fallback, file, prefix = '') {
106
+ const n = readInt(obj, key, file, prefix);
107
+ if (n === null)
108
+ return fallback;
109
+ if (n <= 0) {
110
+ throw new Error(`dreamux config error in ${file}: ${prefix}${key} must be > 0 (got ${n})`);
111
+ }
112
+ return n;
113
+ }
114
+ export function readProviderConfigObject(rawConfig, file, name, options = {}) {
115
+ if (rawConfig === undefined && options.allowMissing === true)
116
+ return {};
117
+ if (!isPlainObject(rawConfig)) {
118
+ throw new Error(`dreamux config error in ${file}: ${name} must be an object (got ${describeType(rawConfig)})`);
119
+ }
120
+ return rawConfig;
121
+ }
122
+ //# sourceMappingURL=config-validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-validate.js","sourceRoot":"","sources":["../../src/internal/config-validate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Generic OS/filesystem utilities the Codex runtime needs, vendored into this
3
+ * package so it depends on `@excitedjs/dreamux-types` only and never imports
4
+ * `@excitedjs/dreamux` core. These are platform primitives (process-group
5
+ * signalling, owner-only dir enforcement, empty-log cleanup, existence probe),
6
+ * NOT Dreamux host layout/path/socket/log contracts — those are supplied by the
7
+ * host through the create context and provider options.
8
+ */
9
+ /** True when `pid` names a live process (EPERM counts as alive). */
10
+ export declare function isProcessAlive(pid: number): boolean;
11
+ /** Signal an entire process group; ESRCH/EPERM are swallowed. */
12
+ export declare function killProcessGroup(pgid: number, signal: NodeJS.Signals | number): void;
13
+ export interface EnsureOwnerOnlyDirOptions {
14
+ /** Current-user uid probe override (tests). */
15
+ getuid?: () => number;
16
+ }
17
+ /**
18
+ * Create/adopt a directory and guarantee the owner-only (0700) privacy
19
+ * invariant regardless of who created it: reject a symlink leaf, fail loud on a
20
+ * foreign-uid dir, and tighten any group/other permission bits.
21
+ */
22
+ export declare function ensureOwnerOnlyDir(path: string, options?: EnsureOwnerOnlyDirOptions): Promise<void>;
23
+ /**
24
+ * Remove `path` only if it exists and is zero bytes. Best-effort: a missing,
25
+ * non-empty, or busy file is left untouched and never throws.
26
+ */
27
+ export declare function removeEmptyLogFile(path: string): Promise<void>;
28
+ /** Best-effort existence probe — the async replacement for `existsSync`. */
29
+ export declare function pathExists(path: string): Promise<boolean>;
30
+ //# sourceMappingURL=os.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"os.d.ts","sourceRoot":"","sources":["../../src/internal/os.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,oEAAoE;AACpE,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CASnD;AAED,iEAAiE;AACjE,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,MAAM,GAC9B,IAAI,CASN;AAED,MAAM,WAAW,yBAAyB;IACxC,+CAA+C;IAC/C,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,yBAA8B,GACtC,OAAO,CAAC,IAAI,CAAC,CAkBf;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAOpE;AAED,4EAA4E;AAC5E,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAO/D"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Generic OS/filesystem utilities the Codex runtime needs, vendored into this
3
+ * package so it depends on `@excitedjs/dreamux-types` only and never imports
4
+ * `@excitedjs/dreamux` core. These are platform primitives (process-group
5
+ * signalling, owner-only dir enforcement, empty-log cleanup, existence probe),
6
+ * NOT Dreamux host layout/path/socket/log contracts — those are supplied by the
7
+ * host through the create context and provider options.
8
+ */
9
+ import { access, chmod, lstat, mkdir, stat, unlink } from 'node:fs/promises';
10
+ /** True when `pid` names a live process (EPERM counts as alive). */
11
+ export function isProcessAlive(pid) {
12
+ if (!Number.isFinite(pid) || pid <= 0)
13
+ return false;
14
+ try {
15
+ process.kill(pid, 0);
16
+ return true;
17
+ }
18
+ catch (e) {
19
+ const errno = e.code;
20
+ return errno === 'EPERM';
21
+ }
22
+ }
23
+ /** Signal an entire process group; ESRCH/EPERM are swallowed. */
24
+ export function killProcessGroup(pgid, signal) {
25
+ if (!Number.isFinite(pgid) || pgid <= 0)
26
+ return;
27
+ try {
28
+ process.kill(-pgid, signal);
29
+ }
30
+ catch (e) {
31
+ const errno = e.code;
32
+ if (errno === 'ESRCH' || errno === 'EPERM')
33
+ return;
34
+ throw e;
35
+ }
36
+ }
37
+ /**
38
+ * Create/adopt a directory and guarantee the owner-only (0700) privacy
39
+ * invariant regardless of who created it: reject a symlink leaf, fail loud on a
40
+ * foreign-uid dir, and tighten any group/other permission bits.
41
+ */
42
+ export async function ensureOwnerOnlyDir(path, options = {}) {
43
+ await mkdir(path, { recursive: true, mode: 0o700 });
44
+ const info = await lstat(path);
45
+ if (info.isSymbolicLink()) {
46
+ throw new Error(`refusing to use Dreamux runtime directory ${path}: it is a symlink, not a real directory`);
47
+ }
48
+ const getuid = options.getuid ?? process.getuid?.bind(process);
49
+ if (getuid !== undefined && info.uid !== getuid()) {
50
+ throw new Error(`refusing to use Dreamux runtime directory ${path}: it is owned by uid ${info.uid}, ` +
51
+ `not the current user (uid ${getuid()})`);
52
+ }
53
+ if ((info.mode & 0o077) !== 0) {
54
+ await chmod(path, 0o700);
55
+ }
56
+ }
57
+ /**
58
+ * Remove `path` only if it exists and is zero bytes. Best-effort: a missing,
59
+ * non-empty, or busy file is left untouched and never throws.
60
+ */
61
+ export async function removeEmptyLogFile(path) {
62
+ try {
63
+ const info = await stat(path);
64
+ if (info.size === 0)
65
+ await unlink(path);
66
+ }
67
+ catch {
68
+ /* best effort — missing/busy/non-empty files are left as-is */
69
+ }
70
+ }
71
+ /** Best-effort existence probe — the async replacement for `existsSync`. */
72
+ export async function pathExists(path) {
73
+ try {
74
+ await access(path);
75
+ return true;
76
+ }
77
+ catch {
78
+ return false;
79
+ }
80
+ }
81
+ //# sourceMappingURL=os.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"os.js","sourceRoot":"","sources":["../../src/internal/os.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE7E,oEAAoE;AACpE,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACpD,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,KAAK,GAAI,CAA2B,CAAC,IAAI,CAAC;QAChD,OAAO,KAAK,KAAK,OAAO,CAAC;IAC3B,CAAC;AACH,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,gBAAgB,CAC9B,IAAY,EACZ,MAA+B;IAE/B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC;QAAE,OAAO;IAChD,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC9B,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,KAAK,GAAI,CAA2B,CAAC,IAAI,CAAC;QAChD,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,OAAO;YAAE,OAAO;QACnD,MAAM,CAAC,CAAC;IACV,CAAC;AACH,CAAC;AAOD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,IAAY,EACZ,UAAqC,EAAE;IAEvC,MAAM,KAAK,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CACb,6CAA6C,IAAI,yCAAyC,CAC3F,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/D,IAAI,MAAM,KAAK,SAAS,IAAI,IAAI,CAAC,GAAG,KAAK,MAAM,EAAE,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CACb,6CAA6C,IAAI,wBAAwB,IAAI,CAAC,GAAG,IAAI;YACnF,6BAA6B,MAAM,EAAE,GAAG,CAC3C,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;QAC9B,MAAM,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC3B,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAAY;IACnD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC;YAAE,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,+DAA+D;IACjE,CAAC;AACH,CAAC;AAED,4EAA4E;AAC5E,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAY;IAC3C,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Standalone default for the volatile socket path, used when no host candidate
3
+ * directories are supplied (the bare generic-loader path or external standalone
4
+ * use). This is the PACKAGE's own fallback root — `$XDG_RUNTIME_DIR` when set,
5
+ * else the OS temp dir — deliberately NOT the Dreamux host socket contract. The
6
+ * path is random per call and never persisted.
7
+ */
8
+ export declare function defaultVolatileSocketPath(id: string): string;
9
+ /**
10
+ * Allocate a fresh Codex app-server socket path inside the first host candidate
11
+ * directory whose full path fits the socket budget. Fails loud (naming `id`)
12
+ * when even the last candidate is over budget. With no candidate directories it
13
+ * uses {@link defaultVolatileSocketPath}.
14
+ */
15
+ export declare function allocateCodexSocketPath(socketDirs: readonly string[], id: string): string;
16
+ /**
17
+ * A representative, NON-throwing socket sample for the doctor: the first
18
+ * candidate whose path fits, else the last candidate (which is then over budget,
19
+ * so the home doctor can REPORT it as an error rather than throwing here). With
20
+ * no candidate directories it uses {@link defaultVolatileSocketPath}.
21
+ */
22
+ export declare function representativeCodexSocketPath(socketDirs: readonly string[], id: string): string;
23
+ //# sourceMappingURL=socket.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"socket.d.ts","sourceRoot":"","sources":["../../src/internal/socket.ts"],"names":[],"mappings":"AA+BA;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAG5D;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,EAAE,EAAE,MAAM,GACT,MAAM,CAYR;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAC3C,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,EAAE,EAAE,MAAM,GACT,MAAM,CAQR"}