@jungjaehoon/mama-os 0.23.0 → 0.24.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 (197) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +1 -1
  3. package/dist/agent/agent-loop.d.ts +3 -6
  4. package/dist/agent/agent-loop.d.ts.map +1 -1
  5. package/dist/agent/agent-loop.js +466 -230
  6. package/dist/agent/agent-loop.js.map +1 -1
  7. package/dist/agent/code-act/constants.d.ts +2 -2
  8. package/dist/agent/code-act/constants.d.ts.map +1 -1
  9. package/dist/agent/code-act/constants.js +16 -9
  10. package/dist/agent/code-act/constants.js.map +1 -1
  11. package/dist/agent/code-act/host-bridge.d.ts +12 -11
  12. package/dist/agent/code-act/host-bridge.d.ts.map +1 -1
  13. package/dist/agent/code-act/host-bridge.js +92 -15
  14. package/dist/agent/code-act/host-bridge.js.map +1 -1
  15. package/dist/agent/code-act/index.d.ts +2 -0
  16. package/dist/agent/code-act/index.d.ts.map +1 -1
  17. package/dist/agent/code-act/index.js +5 -1
  18. package/dist/agent/code-act/index.js.map +1 -1
  19. package/dist/agent/code-act/tool-policy.d.ts +42 -0
  20. package/dist/agent/code-act/tool-policy.d.ts.map +1 -0
  21. package/dist/agent/code-act/tool-policy.js +122 -0
  22. package/dist/agent/code-act/tool-policy.js.map +1 -0
  23. package/dist/agent/code-act/type-definition-generator.d.ts +4 -3
  24. package/dist/agent/code-act/type-definition-generator.d.ts.map +1 -1
  25. package/dist/agent/code-act/type-definition-generator.js +26 -48
  26. package/dist/agent/code-act/type-definition-generator.js.map +1 -1
  27. package/dist/agent/codex-app-server-process.d.ts +116 -0
  28. package/dist/agent/codex-app-server-process.d.ts.map +1 -0
  29. package/dist/agent/codex-app-server-process.js +1382 -0
  30. package/dist/agent/codex-app-server-process.js.map +1 -0
  31. package/dist/agent/codex-home.d.ts +9 -0
  32. package/dist/agent/codex-home.d.ts.map +1 -1
  33. package/dist/agent/codex-home.js +626 -4
  34. package/dist/agent/codex-home.js.map +1 -1
  35. package/dist/agent/codex-thread-registry.d.ts +63 -0
  36. package/dist/agent/codex-thread-registry.d.ts.map +1 -0
  37. package/dist/agent/codex-thread-registry.js +433 -0
  38. package/dist/agent/codex-thread-registry.js.map +1 -0
  39. package/dist/agent/gateway-tool-executor.d.ts +2 -7
  40. package/dist/agent/gateway-tool-executor.d.ts.map +1 -1
  41. package/dist/agent/gateway-tool-executor.js +69 -84
  42. package/dist/agent/gateway-tool-executor.js.map +1 -1
  43. package/dist/agent/managed-agent-runtime-sync.d.ts.map +1 -1
  44. package/dist/agent/managed-agent-runtime-sync.js +0 -3
  45. package/dist/agent/managed-agent-runtime-sync.js.map +1 -1
  46. package/dist/agent/managed-agent-validation.js +1 -1
  47. package/dist/agent/managed-agent-validation.js.map +1 -1
  48. package/dist/agent/model-runner.d.ts +51 -3
  49. package/dist/agent/model-runner.d.ts.map +1 -1
  50. package/dist/agent/model-runner.js +1 -1
  51. package/dist/agent/model-runner.js.map +1 -1
  52. package/dist/agent/persistent-cli-adapter.d.ts +1 -0
  53. package/dist/agent/persistent-cli-adapter.d.ts.map +1 -1
  54. package/dist/agent/persistent-cli-adapter.js +3 -0
  55. package/dist/agent/persistent-cli-adapter.js.map +1 -1
  56. package/dist/agent/session-pool.d.ts +10 -3
  57. package/dist/agent/session-pool.d.ts.map +1 -1
  58. package/dist/agent/session-pool.js +23 -8
  59. package/dist/agent/session-pool.js.map +1 -1
  60. package/dist/agent/tool-registry.d.ts +14 -0
  61. package/dist/agent/tool-registry.d.ts.map +1 -1
  62. package/dist/agent/tool-registry.js +46 -7
  63. package/dist/agent/tool-registry.js.map +1 -1
  64. package/dist/agent/types.d.ts +44 -6
  65. package/dist/agent/types.d.ts.map +1 -1
  66. package/dist/agent/types.js.map +1 -1
  67. package/dist/api/graph-api.d.ts.map +1 -1
  68. package/dist/api/graph-api.js +19 -7
  69. package/dist/api/graph-api.js.map +1 -1
  70. package/dist/cli/commands/init.d.ts +1 -1
  71. package/dist/cli/commands/init.d.ts.map +1 -1
  72. package/dist/cli/commands/init.js +22 -14
  73. package/dist/cli/commands/init.js.map +1 -1
  74. package/dist/cli/commands/run.d.ts.map +1 -1
  75. package/dist/cli/commands/run.js +7 -4
  76. package/dist/cli/commands/run.js.map +1 -1
  77. package/dist/cli/commands/start.d.ts +12 -1
  78. package/dist/cli/commands/start.d.ts.map +1 -1
  79. package/dist/cli/commands/start.js +161 -27
  80. package/dist/cli/commands/start.js.map +1 -1
  81. package/dist/cli/commands/status.js +2 -2
  82. package/dist/cli/commands/status.js.map +1 -1
  83. package/dist/cli/config/config-manager.d.ts.map +1 -1
  84. package/dist/cli/config/config-manager.js +21 -4
  85. package/dist/cli/config/config-manager.js.map +1 -1
  86. package/dist/cli/config/types.d.ts +4 -4
  87. package/dist/cli/config/types.d.ts.map +1 -1
  88. package/dist/cli/config/types.js +1 -0
  89. package/dist/cli/config/types.js.map +1 -1
  90. package/dist/cli/index.js +2 -2
  91. package/dist/cli/index.js.map +1 -1
  92. package/dist/cli/runtime/agent-loop-init.d.ts +1 -1
  93. package/dist/cli/runtime/agent-loop-init.d.ts.map +1 -1
  94. package/dist/cli/runtime/agent-loop-init.js +12 -11
  95. package/dist/cli/runtime/agent-loop-init.js.map +1 -1
  96. package/dist/cli/runtime/connector-init.d.ts.map +1 -1
  97. package/dist/cli/runtime/connector-init.js +13 -17
  98. package/dist/cli/runtime/connector-init.js.map +1 -1
  99. package/dist/cli/runtime/envelope-bootstrap.d.ts.map +1 -1
  100. package/dist/cli/runtime/envelope-bootstrap.js +13 -1
  101. package/dist/cli/runtime/envelope-bootstrap.js.map +1 -1
  102. package/dist/cli/runtime/gateway-init.d.ts +1 -1
  103. package/dist/cli/runtime/gateway-init.d.ts.map +1 -1
  104. package/dist/cli/runtime/gateway-init.js.map +1 -1
  105. package/dist/cli/runtime/mama-core-init.d.ts +2 -2
  106. package/dist/cli/runtime/mama-core-init.d.ts.map +1 -1
  107. package/dist/cli/runtime/mama-core-init.js +17 -0
  108. package/dist/cli/runtime/mama-core-init.js.map +1 -1
  109. package/dist/cli/runtime/memory-agent-init.d.ts +1 -1
  110. package/dist/cli/runtime/memory-agent-init.d.ts.map +1 -1
  111. package/dist/cli/runtime/memory-agent-init.js +16 -6
  112. package/dist/cli/runtime/memory-agent-init.js.map +1 -1
  113. package/dist/cli/runtime/types.d.ts +4 -26
  114. package/dist/cli/runtime/types.d.ts.map +1 -1
  115. package/dist/cli/runtime/utilities.js +2 -2
  116. package/dist/cli/runtime/utilities.js.map +1 -1
  117. package/dist/connectors/config-loader.d.ts +24 -0
  118. package/dist/connectors/config-loader.d.ts.map +1 -0
  119. package/dist/connectors/config-loader.js +205 -0
  120. package/dist/connectors/config-loader.js.map +1 -0
  121. package/dist/connectors/framework/types.d.ts +2 -0
  122. package/dist/connectors/framework/types.d.ts.map +1 -1
  123. package/dist/connectors/kagemusha/query-tools.js +2 -2
  124. package/dist/connectors/kagemusha/query-tools.js.map +1 -1
  125. package/dist/envelope/reactive-config.d.ts +2 -2
  126. package/dist/envelope/reactive-config.d.ts.map +1 -1
  127. package/dist/envelope/reactive-config.js +13 -6
  128. package/dist/envelope/reactive-config.js.map +1 -1
  129. package/dist/gateways/context-injector.d.ts +2 -1
  130. package/dist/gateways/context-injector.d.ts.map +1 -1
  131. package/dist/gateways/context-injector.js.map +1 -1
  132. package/dist/gateways/message-router.d.ts +9 -0
  133. package/dist/gateways/message-router.d.ts.map +1 -1
  134. package/dist/gateways/message-router.js +87 -18
  135. package/dist/gateways/message-router.js.map +1 -1
  136. package/dist/gateways/types.d.ts +1 -1
  137. package/dist/gateways/types.d.ts.map +1 -1
  138. package/dist/multi-agent/agent-process-manager.d.ts +9 -1
  139. package/dist/multi-agent/agent-process-manager.d.ts.map +1 -1
  140. package/dist/multi-agent/agent-process-manager.js +197 -49
  141. package/dist/multi-agent/agent-process-manager.js.map +1 -1
  142. package/dist/multi-agent/dashboard-agent-persona.js +4 -4
  143. package/dist/multi-agent/multi-agent-base.d.ts.map +1 -1
  144. package/dist/multi-agent/multi-agent-base.js +2 -1
  145. package/dist/multi-agent/multi-agent-base.js.map +1 -1
  146. package/dist/multi-agent/runtime-process.d.ts +18 -15
  147. package/dist/multi-agent/runtime-process.d.ts.map +1 -1
  148. package/dist/multi-agent/runtime-process.js +63 -59
  149. package/dist/multi-agent/runtime-process.js.map +1 -1
  150. package/dist/multi-agent/types.d.ts +13 -7
  151. package/dist/multi-agent/types.d.ts.map +1 -1
  152. package/dist/multi-agent/types.js.map +1 -1
  153. package/dist/multi-agent/workflow-engine.js +3 -3
  154. package/dist/multi-agent/workflow-engine.js.map +1 -1
  155. package/dist/multi-agent/workflow-types.d.ts +2 -2
  156. package/dist/multi-agent/workflow-types.d.ts.map +1 -1
  157. package/dist/operator/operator-trigger-loop.d.ts +3 -0
  158. package/dist/operator/operator-trigger-loop.d.ts.map +1 -1
  159. package/dist/operator/operator-trigger-loop.js +1 -0
  160. package/dist/operator/operator-trigger-loop.js.map +1 -1
  161. package/dist/operator/report-run.d.ts +4 -4
  162. package/dist/operator/situation-report.d.ts +3 -0
  163. package/dist/operator/situation-report.d.ts.map +1 -1
  164. package/dist/operator/situation-report.js +43 -26
  165. package/dist/operator/situation-report.js.map +1 -1
  166. package/dist/operator/trigger-author.d.ts +35 -1
  167. package/dist/operator/trigger-author.d.ts.map +1 -1
  168. package/dist/operator/trigger-author.js +73 -10
  169. package/dist/operator/trigger-author.js.map +1 -1
  170. package/dist/operator/worker-run.d.ts +31 -0
  171. package/dist/operator/worker-run.d.ts.map +1 -1
  172. package/dist/operator/worker-run.js +76 -1
  173. package/dist/operator/worker-run.js.map +1 -1
  174. package/dist/operator/workorder-consumer.d.ts +7 -4
  175. package/dist/operator/workorder-consumer.d.ts.map +1 -1
  176. package/dist/operator/workorder-consumer.js +8 -3
  177. package/dist/operator/workorder-consumer.js.map +1 -1
  178. package/dist/setup/setup-prompt.d.ts +1 -1
  179. package/dist/setup/setup-prompt.d.ts.map +1 -1
  180. package/dist/setup/setup-prompt.js +4 -5
  181. package/dist/setup/setup-prompt.js.map +1 -1
  182. package/dist/utils/untrusted-content.d.ts +1 -0
  183. package/dist/utils/untrusted-content.d.ts.map +1 -1
  184. package/dist/utils/untrusted-content.js +5 -0
  185. package/dist/utils/untrusted-content.js.map +1 -1
  186. package/package.json +1 -1
  187. package/public/viewer/js/modules/agents.js +13 -9
  188. package/public/viewer/js/modules/settings.js +15 -10
  189. package/public/viewer/src/modules/agents.ts +12 -10
  190. package/public/viewer/src/modules/settings.ts +17 -12
  191. package/public/viewer/src/utils/api.ts +2 -2
  192. package/templates/AGENTS.codex.md +2 -23
  193. package/templates/personas/conductor.md +1 -1
  194. package/dist/agent/codex-mcp-process.d.ts +0 -105
  195. package/dist/agent/codex-mcp-process.d.ts.map +0 -1
  196. package/dist/agent/codex-mcp-process.js +0 -748
  197. package/dist/agent/codex-mcp-process.js.map +0 -1
@@ -1,17 +1,339 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.buildMAMACodexConfig = buildMAMACodexConfig;
4
+ exports.buildMAMACodexAppServerConfig = buildMAMACodexAppServerConfig;
5
+ exports.buildCodexAppServerLaunchConfig = buildCodexAppServerLaunchConfig;
4
6
  exports.getLocalMCPServerEntry = getLocalMCPServerEntry;
5
7
  const path_1 = require("path");
6
8
  const fs_1 = require("fs");
9
+ const node_crypto_1 = require("node:crypto");
10
+ const ENV_NAME_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
11
+ const SERVER_NAME_PATTERN = /^[A-Za-z0-9_.-]+$/;
12
+ const AUTH_MODES = new Set(['oauth', 'chatgpt']);
13
+ const APPROVAL_MODES = new Set(['auto', 'prompt', 'writes', 'approve']);
14
+ const HTTP_HEADER_NAME_PATTERN = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
15
+ const ROOT_FIELDS = new Set(['mcpServers', '_installedBy']);
16
+ const SERVER_FIELDS = new Set([
17
+ 'command',
18
+ 'args',
19
+ 'env',
20
+ 'env_vars',
21
+ 'cwd',
22
+ 'experimental_environment',
23
+ 'url',
24
+ 'auth',
25
+ 'bearer_token_env_var',
26
+ 'http_headers',
27
+ 'env_http_headers',
28
+ 'required',
29
+ 'supports_parallel_tool_calls',
30
+ 'environment_id',
31
+ 'startup_timeout_sec',
32
+ 'startup_timeout_ms',
33
+ 'tool_timeout_sec',
34
+ 'tool_timeout_ms',
35
+ 'enabled',
36
+ 'enabled_tools',
37
+ 'disabled_tools',
38
+ 'allowed_tools',
39
+ 'denied_tools',
40
+ 'default_tools_approval_mode',
41
+ 'tools',
42
+ 'scopes',
43
+ 'oauth_resource',
44
+ '_installedBy',
45
+ ]);
46
+ function isRecord(value) {
47
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
48
+ }
49
+ function rejectUnknownFields(value, allowed, location) {
50
+ for (const key of Object.keys(value)) {
51
+ validateTomlString(key, `${location} field name`);
52
+ if (!allowed.has(key)) {
53
+ throw new Error(`Unsupported field ${location}.${key}`);
54
+ }
55
+ }
56
+ }
57
+ function requireString(value, location) {
58
+ if (typeof value !== 'string' || value.length === 0) {
59
+ throw new Error(`${location} must be a non-empty string`);
60
+ }
61
+ validateTomlString(value, location);
62
+ return value;
63
+ }
64
+ function validateUnicodeScalarString(value, location) {
65
+ for (let index = 0; index < value.length; index += 1) {
66
+ const codeUnit = value.charCodeAt(index);
67
+ if (codeUnit >= 0xd800 && codeUnit <= 0xdbff) {
68
+ const next = value.charCodeAt(index + 1);
69
+ if (index + 1 >= value.length || next < 0xdc00 || next > 0xdfff) {
70
+ throw new Error(`${location} must contain only Unicode scalar values`);
71
+ }
72
+ index += 1;
73
+ }
74
+ else if (codeUnit >= 0xdc00 && codeUnit <= 0xdfff) {
75
+ throw new Error(`${location} must contain only Unicode scalar values`);
76
+ }
77
+ }
78
+ }
79
+ function validateTomlString(value, location) {
80
+ validateUnicodeScalarString(value, location);
81
+ for (let index = 0; index < value.length; index += 1) {
82
+ const codeUnit = value.charCodeAt(index);
83
+ if (codeUnit <= 0x1f || codeUnit === 0x7f) {
84
+ throw new Error(`${location} must not contain TOML control characters`);
85
+ }
86
+ }
87
+ }
88
+ function validateChildEnvValue(value, location) {
89
+ validateUnicodeScalarString(value, location);
90
+ if (value.includes('\0')) {
91
+ throw new Error(`${location} must not contain NUL`);
92
+ }
93
+ }
94
+ function validateHttpHeaderValue(value, location) {
95
+ validateUnicodeScalarString(value, location);
96
+ for (let index = 0; index < value.length; index += 1) {
97
+ const codeUnit = value.charCodeAt(index);
98
+ if ((codeUnit <= 0x1f && codeUnit !== 0x09) || codeUnit === 0x7f) {
99
+ throw new Error(`${location} contains an invalid HTTP header value`);
100
+ }
101
+ }
102
+ }
103
+ function optionalString(value, location) {
104
+ return value === undefined ? undefined : requireString(value, location);
105
+ }
106
+ function optionalBoolean(value, location) {
107
+ if (value === undefined) {
108
+ return undefined;
109
+ }
110
+ if (typeof value !== 'boolean') {
111
+ throw new Error(`${location} must be a boolean`);
112
+ }
113
+ return value;
114
+ }
115
+ function optionalPositiveNumber(value, location) {
116
+ if (value === undefined) {
117
+ return undefined;
118
+ }
119
+ if (typeof value !== 'number' || !Number.isFinite(value) || value <= 0) {
120
+ throw new Error(`${location} must be a positive finite number`);
121
+ }
122
+ return value;
123
+ }
124
+ function optionalStringArray(value, location) {
125
+ if (value === undefined) {
126
+ return undefined;
127
+ }
128
+ if (!Array.isArray(value) || value.some((entry) => typeof entry !== 'string')) {
129
+ throw new Error(`${location} must be an array of strings`);
130
+ }
131
+ return value.map((entry, index) => {
132
+ validateTomlString(entry, `${location}[${index}]`);
133
+ return entry;
134
+ });
135
+ }
136
+ function codeUnitCompare(left, right) {
137
+ return left < right ? -1 : left > right ? 1 : 0;
138
+ }
139
+ function optionalStringSet(value, location) {
140
+ const entries = optionalStringArray(value, location);
141
+ return entries === undefined ? undefined : [...new Set(entries)].sort(codeUnitCompare);
142
+ }
143
+ function requireEnum(value, allowed, location) {
144
+ const result = requireString(value, location);
145
+ if (!allowed.has(result)) {
146
+ throw new Error(`${location} has an unsupported value`);
147
+ }
148
+ return result;
149
+ }
150
+ function stringRecord(value, location, validateValue = validateTomlString) {
151
+ if (value === undefined) {
152
+ return undefined;
153
+ }
154
+ if (!isRecord(value)) {
155
+ throw new Error(`${location} must be an object`);
156
+ }
157
+ const result = Object.create(null);
158
+ for (const key of Object.keys(value).sort()) {
159
+ validateTomlString(key, `${location} key`);
160
+ const entry = value[key];
161
+ if (typeof entry !== 'string') {
162
+ throw new Error(`${location}.${key} must be a string`);
163
+ }
164
+ validateValue(entry, `${location}.${key}`);
165
+ result[key] = entry;
166
+ }
167
+ return result;
168
+ }
169
+ function validateEnvName(name, location) {
170
+ validateUnicodeScalarString(name, location);
171
+ if (!ENV_NAME_PATTERN.test(name)) {
172
+ throw new Error(`${location} contains invalid environment name ${name}`);
173
+ }
174
+ }
175
+ function validateHeaderName(name, location) {
176
+ validateUnicodeScalarString(name, location);
177
+ if (!HTTP_HEADER_NAME_PATTERN.test(name)) {
178
+ throw new Error(`${location} contains an invalid HTTP header name`);
179
+ }
180
+ }
181
+ function validateHttpUrl(value, location) {
182
+ let parsed;
183
+ try {
184
+ parsed = new URL(value);
185
+ }
186
+ catch {
187
+ throw new Error(`${location} must be a valid HTTP URL`);
188
+ }
189
+ if (parsed.protocol !== 'http:' && parsed.protocol !== 'https:') {
190
+ throw new Error(`${location} must use http or https`);
191
+ }
192
+ if (parsed.username !== '' || parsed.password !== '') {
193
+ throw new Error(`${location} must not contain user information`);
194
+ }
195
+ if (value.includes('?')) {
196
+ throw new Error(`${location} must not contain a query; use environment-backed authentication`);
197
+ }
198
+ if (value.includes('#')) {
199
+ throw new Error(`${location} must not contain a fragment`);
200
+ }
201
+ return value;
202
+ }
203
+ function tomlBooleanOrNumber(value) {
204
+ return String(value);
205
+ }
206
+ function tomlInlineApprovalTable(value, location) {
207
+ if (value === undefined) {
208
+ return undefined;
209
+ }
210
+ if (!isRecord(value)) {
211
+ throw new Error(`${location} must be an object`);
212
+ }
213
+ const entries = [];
214
+ for (const toolName of Object.keys(value).sort()) {
215
+ validateTomlString(toolName, `${location} tool name`);
216
+ if (!SERVER_NAME_PATTERN.test(toolName)) {
217
+ throw new Error(`${location} contains invalid tool name ${toolName}`);
218
+ }
219
+ const tool = value[toolName];
220
+ if (!isRecord(tool)) {
221
+ throw new Error(`${location}.${toolName} must be an object`);
222
+ }
223
+ rejectUnknownFields(tool, new Set(['approval_mode']), `${location}.${toolName}`);
224
+ const approvalMode = requireEnum(tool.approval_mode, APPROVAL_MODES, `${location}.${toolName}.approval_mode`);
225
+ entries.push(`${tomlString(toolName)} = { approval_mode = ${tomlString(approvalMode)} }`);
226
+ }
227
+ return `{ ${entries.join(', ')} }`;
228
+ }
229
+ function normalizedApprovalTools(value, location) {
230
+ if (value === undefined) {
231
+ return undefined;
232
+ }
233
+ if (!isRecord(value)) {
234
+ throw new Error(`${location} must be an object`);
235
+ }
236
+ const result = Object.create(null);
237
+ for (const toolName of Object.keys(value).sort()) {
238
+ const tool = value[toolName];
239
+ if (!isRecord(tool)) {
240
+ throw new Error(`${location}.${toolName} must be an object`);
241
+ }
242
+ const normalizedTool = Object.create(null);
243
+ normalizedTool.approval_mode = requireEnum(tool.approval_mode, APPROVAL_MODES, `${location}.${toolName}.approval_mode`);
244
+ result[toolName] = normalizedTool;
245
+ }
246
+ return result;
247
+ }
248
+ function addOverride(args, path, value) {
249
+ args.push('-c', `${path}=${value}`);
250
+ }
251
+ function consolidateMcpOverrides(overrides) {
252
+ if (overrides.length === 0) {
253
+ return [];
254
+ }
255
+ const servers = new Map();
256
+ for (let index = 1; index < overrides.length; index += 2) {
257
+ const assignment = overrides[index];
258
+ const separator = assignment.indexOf('=');
259
+ const path = assignment.slice(0, separator);
260
+ const value = assignment.slice(separator + 1);
261
+ const prefix = 'mcp_servers.';
262
+ const fieldSeparator = path.lastIndexOf('.');
263
+ const name = JSON.parse(path.slice(prefix.length, fieldSeparator));
264
+ if (typeof name !== 'string') {
265
+ throw new Error('Internal MCP override name must be a string');
266
+ }
267
+ const fields = servers.get(name) ?? [];
268
+ fields.push([path.slice(fieldSeparator + 1), value]);
269
+ servers.set(name, fields);
270
+ }
271
+ const entries = [...servers.entries()].map(([name, fields]) => {
272
+ const serialized = fields.map(([field, value]) => `${field} = ${value}`).join(', ');
273
+ return `${tomlString(name)} = { ${serialized} }`;
274
+ });
275
+ return ['-c', `mcp_servers={ ${entries.join(', ')} }`];
276
+ }
277
+ function registerUserBinding(userBindings, generatedBindings, name) {
278
+ if (generatedBindings.has(name)) {
279
+ throw new Error(`Environment binding ${name} collides with a generated secret source`);
280
+ }
281
+ userBindings.add(name);
282
+ }
283
+ function reserveGeneratedBinding(env, userBindings, generatedBindings, name, origin) {
284
+ const existing = generatedBindings.get(name);
285
+ if (existing !== undefined && existing !== origin) {
286
+ throw new Error(`Generated secret source ${name} has conflicting origins`);
287
+ }
288
+ if (existing === origin) {
289
+ return;
290
+ }
291
+ if (Object.prototype.hasOwnProperty.call(env, name) || userBindings.has(name)) {
292
+ throw new Error(`Generated secret source ${name} collides with a user environment binding`);
293
+ }
294
+ generatedBindings.set(name, origin);
295
+ }
296
+ function setChildSecret(env, name, value, configuredNames) {
297
+ const configured = configuredNames.get(name);
298
+ if (configured !== undefined && configured !== value) {
299
+ throw new Error(`Conflicting values configured for environment name ${name}`);
300
+ }
301
+ const inherited = env[name];
302
+ if (inherited !== undefined && inherited !== value) {
303
+ throw new Error(`Configured value conflicts with inherited environment name ${name}`);
304
+ }
305
+ configuredNames.set(name, value);
306
+ env[name] = value;
307
+ }
308
+ function generatedHeaderEnvName(serverName, headerName) {
309
+ const server = serverName.toUpperCase().replace(/[^A-Z0-9_]/g, '_');
310
+ const header = headerName.toUpperCase().replace(/[^A-Z0-9_]/g, '_');
311
+ const suffix = (0, node_crypto_1.createHash)('sha256')
312
+ .update(`${serverName}\0${headerName}`)
313
+ .digest('hex')
314
+ .slice(0, 12)
315
+ .toUpperCase();
316
+ return `MAMA_MCP_${server}_HTTP_HEADER_${header}_${suffix}`;
317
+ }
318
+ function fingerprintPolicy(value) {
319
+ return (0, node_crypto_1.createHash)('sha256').update(JSON.stringify(value)).digest('hex');
320
+ }
7
321
  function tomlString(value) {
322
+ validateTomlString(value, 'TOML string');
8
323
  return JSON.stringify(value);
9
324
  }
10
325
  function tomlStringArray(values) {
11
326
  return `[${values.map(tomlString).join(', ')}]`;
12
327
  }
13
328
  function tomlInlineStringTable(values) {
14
- const entries = Object.entries(values).map(([key, value]) => `${key} = ${tomlString(value)}`);
329
+ const entries = Object.entries(values).map(([key, value]) => {
330
+ validateTomlString(key, 'TOML table key');
331
+ return `${key} = ${tomlString(value)}`;
332
+ });
333
+ return `{ ${entries.join(', ')} }`;
334
+ }
335
+ function tomlInlineQuotedStringTable(values) {
336
+ const entries = Object.entries(values).map(([key, value]) => `${tomlString(key)} = ${tomlString(value)}`);
15
337
  return `{ ${entries.join(', ')} }`;
16
338
  }
17
339
  function mcpServersToml(mcpConfigPath) {
@@ -31,9 +353,14 @@ function mcpServersToml(mcpConfigPath) {
31
353
  const args = Array.isArray(server.args)
32
354
  ? server.args.filter((arg) => typeof arg === 'string')
33
355
  : [];
34
- const env = server.env && typeof server.env === 'object' && !Array.isArray(server.env)
35
- ? Object.fromEntries(Object.entries(server.env).filter((entry) => typeof entry[1] === 'string'))
36
- : {};
356
+ const env = Object.create(null);
357
+ if (server.env && typeof server.env === 'object' && !Array.isArray(server.env)) {
358
+ for (const [name, value] of Object.entries(server.env)) {
359
+ if (typeof value === 'string') {
360
+ env[name] = value;
361
+ }
362
+ }
363
+ }
37
364
  lines.push('', `[mcp_servers.${tomlString(name)}]`, `command = ${tomlString(server.command)}`);
38
365
  if (args.length > 0) {
39
366
  lines.push(`args = ${tomlStringArray(args)}`);
@@ -56,6 +383,301 @@ function buildMAMACodexConfig(mcpConfigPath) {
56
383
  ...mcpServersToml(mcpConfigPath),
57
384
  ].join('\n');
58
385
  }
386
+ function buildMAMACodexAppServerConfig() {
387
+ return [
388
+ 'approval_policy = "on-request"',
389
+ 'sandbox_mode = "workspace-write"',
390
+ 'model_reasoning_effort = "high"',
391
+ 'instructions = ""',
392
+ 'developer_instructions = ""',
393
+ 'include_apps_instructions = false',
394
+ 'include_environment_context = false',
395
+ '',
396
+ '[analytics]',
397
+ 'enabled = false',
398
+ '',
399
+ '[features]',
400
+ 'plugins = false',
401
+ 'apps = false',
402
+ 'tool_search = false',
403
+ 'shell_tool = false',
404
+ 'unified_exec = false',
405
+ 'web_search = false',
406
+ 'browser_use = false',
407
+ 'computer_use = false',
408
+ 'image_generation = false',
409
+ '',
410
+ '# MAMA standalone owns identity, skills, memory tools, and evidence gates.',
411
+ '# App-server is isolated under the managed MAMA home.',
412
+ '# Runner-specific MCP servers are supplied per process and never written here.',
413
+ ].join('\n');
414
+ }
415
+ function buildCodexAppServerLaunchConfig(mcpConfigPath, processEnv) {
416
+ const childEnv = Object.create(null);
417
+ for (const [name, value] of Object.entries(processEnv)) {
418
+ childEnv[name] = value;
419
+ }
420
+ if (mcpConfigPath === undefined) {
421
+ return {
422
+ args: [],
423
+ env: childEnv,
424
+ fingerprint: fingerprintPolicy({}),
425
+ secretFingerprint: fingerprintPolicy({}),
426
+ };
427
+ }
428
+ let parsed;
429
+ try {
430
+ parsed = JSON.parse((0, fs_1.readFileSync)(mcpConfigPath, 'utf-8'));
431
+ }
432
+ catch (error) {
433
+ const reason = error instanceof SyntaxError ? 'invalid JSON' : 'unreadable file';
434
+ throw new Error(`MCP config is ${reason}`);
435
+ }
436
+ if (!isRecord(parsed)) {
437
+ throw new Error('MCP config root must be an object');
438
+ }
439
+ rejectUnknownFields(parsed, ROOT_FIELDS, 'root');
440
+ if (!isRecord(parsed.mcpServers)) {
441
+ throw new Error('root.mcpServers must be an object');
442
+ }
443
+ const mcpServers = parsed.mcpServers;
444
+ const args = [];
445
+ const configuredNames = new Map();
446
+ const userBindings = new Set();
447
+ const generatedBindings = new Map();
448
+ const normalizedServers = Object.create(null);
449
+ for (const name of Object.keys(mcpServers).sort()) {
450
+ validateTomlString(name, 'MCP server name');
451
+ if (!SERVER_NAME_PATTERN.test(name)) {
452
+ throw new Error(`Invalid MCP server name ${name}`);
453
+ }
454
+ const raw = mcpServers[name];
455
+ if (!isRecord(raw)) {
456
+ throw new Error(`mcpServers.${name} must be an object`);
457
+ }
458
+ rejectUnknownFields(raw, SERVER_FIELDS, `mcpServers.${name}`);
459
+ // MAMA and legacy code-act are owned by the canonical native host bridge.
460
+ // Passing either server to app-server would create an unprojected bypass
461
+ // around role, runtime, tier, and envelope enforcement.
462
+ if (name === 'mama' || name === 'code-act') {
463
+ continue;
464
+ }
465
+ const location = `mcpServers.${name}`;
466
+ const command = optionalString(raw.command, `${location}.command`);
467
+ const rawUrl = optionalString(raw.url, `${location}.url`);
468
+ const url = rawUrl === undefined ? undefined : validateHttpUrl(rawUrl, `${location}.url`);
469
+ if ((command === undefined) === (url === undefined)) {
470
+ throw new Error(`${location} must configure exactly one of command or url`);
471
+ }
472
+ const base = `mcp_servers.${tomlString(name)}`;
473
+ const normalized = Object.create(null);
474
+ normalized.transport = command === undefined ? 'http' : 'stdio';
475
+ if (command !== undefined) {
476
+ addOverride(args, `${base}.command`, tomlString(command));
477
+ normalized.command = command;
478
+ }
479
+ else if (url !== undefined) {
480
+ addOverride(args, `${base}.url`, tomlString(url));
481
+ normalized.url = url;
482
+ }
483
+ const serverArgs = optionalStringArray(raw.args, `${location}.args`);
484
+ if (serverArgs !== undefined) {
485
+ if (command === undefined) {
486
+ throw new Error(`${location}.args is only valid for stdio servers`);
487
+ }
488
+ addOverride(args, `${base}.args`, tomlStringArray(serverArgs));
489
+ normalized.args = serverArgs;
490
+ }
491
+ const literalEnv = stringRecord(raw.env, `${location}.env`, validateChildEnvValue);
492
+ const inheritedEnvNames = optionalStringArray(raw.env_vars, `${location}.env_vars`);
493
+ if ((literalEnv !== undefined || inheritedEnvNames !== undefined) && command === undefined) {
494
+ throw new Error(`${location}.env and env_vars are only valid for stdio servers`);
495
+ }
496
+ const allEnvNames = new Set();
497
+ for (const envName of inheritedEnvNames ?? []) {
498
+ validateEnvName(envName, `${location}.env_vars`);
499
+ registerUserBinding(userBindings, generatedBindings, envName);
500
+ allEnvNames.add(envName);
501
+ }
502
+ for (const [envName, value] of Object.entries(literalEnv ?? {})) {
503
+ validateEnvName(envName, `${location}.env`);
504
+ registerUserBinding(userBindings, generatedBindings, envName);
505
+ setChildSecret(childEnv, envName, value, configuredNames);
506
+ allEnvNames.add(envName);
507
+ }
508
+ if (allEnvNames.size > 0) {
509
+ const envNames = [...allEnvNames].sort();
510
+ addOverride(args, `${base}.env_vars`, tomlStringArray(envNames));
511
+ normalized.env_vars = envNames;
512
+ }
513
+ const cwd = optionalString(raw.cwd, `${location}.cwd`);
514
+ if (cwd !== undefined) {
515
+ if (command === undefined) {
516
+ throw new Error(`${location}.cwd is only valid for stdio servers`);
517
+ }
518
+ addOverride(args, `${base}.cwd`, tomlString(cwd));
519
+ normalized.cwd = cwd;
520
+ }
521
+ const experimentalEnvironment = optionalString(raw.experimental_environment, `${location}.experimental_environment`);
522
+ if (experimentalEnvironment !== undefined && command === undefined) {
523
+ throw new Error(`${location}.experimental_environment is only valid for stdio servers`);
524
+ }
525
+ const environmentId = optionalString(raw.environment_id, `${location}.environment_id`);
526
+ if (experimentalEnvironment !== undefined && environmentId !== undefined) {
527
+ throw new Error(`${location} cannot set both experimental_environment and environment_id`);
528
+ }
529
+ const effectiveEnvironmentId = environmentId ?? experimentalEnvironment;
530
+ if (effectiveEnvironmentId !== undefined) {
531
+ addOverride(args, `${base}.environment_id`, tomlString(effectiveEnvironmentId));
532
+ normalized.environment_id = effectiveEnvironmentId;
533
+ }
534
+ const auth = raw.auth === undefined ? undefined : requireEnum(raw.auth, AUTH_MODES, `${location}.auth`);
535
+ if (auth !== undefined) {
536
+ if (url === undefined) {
537
+ throw new Error(`${location}.auth is only valid for HTTP servers`);
538
+ }
539
+ addOverride(args, `${base}.auth`, tomlString(auth));
540
+ normalized.auth = auth;
541
+ }
542
+ const bearerTokenEnvVar = optionalString(raw.bearer_token_env_var, `${location}.bearer_token_env_var`);
543
+ if (bearerTokenEnvVar !== undefined) {
544
+ if (url === undefined) {
545
+ throw new Error(`${location}.bearer_token_env_var is only valid for HTTP servers`);
546
+ }
547
+ validateEnvName(bearerTokenEnvVar, `${location}.bearer_token_env_var`);
548
+ registerUserBinding(userBindings, generatedBindings, bearerTokenEnvVar);
549
+ addOverride(args, `${base}.bearer_token_env_var`, tomlString(bearerTokenEnvVar));
550
+ normalized.bearer_token_env_var = bearerTokenEnvVar;
551
+ }
552
+ const literalHeaders = stringRecord(raw.http_headers, `${location}.http_headers`, validateHttpHeaderValue);
553
+ const envHeaders = stringRecord(raw.env_http_headers, `${location}.env_http_headers`) ?? {};
554
+ if ((literalHeaders !== undefined || Object.keys(envHeaders).length > 0) && url === undefined) {
555
+ throw new Error(`${location} HTTP headers are only valid for HTTP servers`);
556
+ }
557
+ const effectiveHeaderBindings = Object.create(null);
558
+ for (const [headerName, envName] of Object.entries(envHeaders)) {
559
+ validateHeaderName(headerName, `${location}.env_http_headers`);
560
+ validateEnvName(envName, `${location}.env_http_headers.${headerName}`);
561
+ const canonicalHeader = headerName.toLowerCase();
562
+ if (effectiveHeaderBindings[canonicalHeader] !== undefined) {
563
+ throw new Error(`${location} configures header ${canonicalHeader} more than once`);
564
+ }
565
+ registerUserBinding(userBindings, generatedBindings, envName);
566
+ effectiveHeaderBindings[canonicalHeader] = envName;
567
+ }
568
+ for (const [headerName, value] of Object.entries(literalHeaders ?? {})) {
569
+ validateHeaderName(headerName, `${location}.http_headers`);
570
+ const canonicalHeader = headerName.toLowerCase();
571
+ if (effectiveHeaderBindings[canonicalHeader] !== undefined) {
572
+ throw new Error(`${location} configures header ${canonicalHeader} more than once`);
573
+ }
574
+ const generatedName = generatedHeaderEnvName(name, canonicalHeader);
575
+ reserveGeneratedBinding(childEnv, userBindings, generatedBindings, generatedName, `${name}:generated-header:${canonicalHeader}`);
576
+ setChildSecret(childEnv, generatedName, value, configuredNames);
577
+ effectiveHeaderBindings[canonicalHeader] = generatedName;
578
+ }
579
+ if (Object.keys(effectiveHeaderBindings).length > 0) {
580
+ const sortedBindings = Object.create(null);
581
+ for (const [headerName, envName] of Object.entries(effectiveHeaderBindings).sort(([left], [right]) => codeUnitCompare(left, right))) {
582
+ sortedBindings[headerName] = envName;
583
+ }
584
+ addOverride(args, `${base}.env_http_headers`, tomlInlineQuotedStringTable(sortedBindings));
585
+ normalized.env_http_headers = sortedBindings;
586
+ }
587
+ const required = optionalBoolean(raw.required, `${location}.required`);
588
+ const parallel = optionalBoolean(raw.supports_parallel_tool_calls, `${location}.supports_parallel_tool_calls`);
589
+ const enabled = optionalBoolean(raw.enabled, `${location}.enabled`);
590
+ for (const [field, value] of [
591
+ ['required', required],
592
+ ['supports_parallel_tool_calls', parallel],
593
+ ['enabled', enabled],
594
+ ]) {
595
+ if (value !== undefined) {
596
+ addOverride(args, `${base}.${field}`, tomlBooleanOrNumber(value));
597
+ normalized[field] = value;
598
+ }
599
+ }
600
+ const startupSeconds = optionalPositiveNumber(raw.startup_timeout_sec, `${location}.startup_timeout_sec`);
601
+ const startupMilliseconds = optionalPositiveNumber(raw.startup_timeout_ms, `${location}.startup_timeout_ms`);
602
+ const toolSeconds = optionalPositiveNumber(raw.tool_timeout_sec, `${location}.tool_timeout_sec`);
603
+ const toolMilliseconds = optionalPositiveNumber(raw.tool_timeout_ms, `${location}.tool_timeout_ms`);
604
+ if (startupSeconds !== undefined && startupMilliseconds !== undefined) {
605
+ throw new Error(`${location} cannot set both startup timeout units`);
606
+ }
607
+ if (toolSeconds !== undefined && toolMilliseconds !== undefined) {
608
+ throw new Error(`${location} cannot set both tool timeout units`);
609
+ }
610
+ const effectiveStartupSeconds = startupSeconds ??
611
+ (startupMilliseconds === undefined ? undefined : startupMilliseconds / 1000);
612
+ const effectiveToolSeconds = toolSeconds ?? (toolMilliseconds === undefined ? undefined : toolMilliseconds / 1000);
613
+ if (effectiveStartupSeconds !== undefined) {
614
+ addOverride(args, `${base}.startup_timeout_sec`, String(effectiveStartupSeconds));
615
+ normalized.startup_timeout_sec = effectiveStartupSeconds;
616
+ }
617
+ if (effectiveToolSeconds !== undefined) {
618
+ addOverride(args, `${base}.tool_timeout_sec`, String(effectiveToolSeconds));
619
+ normalized.tool_timeout_sec = effectiveToolSeconds;
620
+ }
621
+ const enabledTools = optionalStringSet(raw.enabled_tools, `${location}.enabled_tools`);
622
+ const allowedTools = optionalStringSet(raw.allowed_tools, `${location}.allowed_tools`);
623
+ const disabledTools = optionalStringSet(raw.disabled_tools, `${location}.disabled_tools`);
624
+ const deniedTools = optionalStringSet(raw.denied_tools, `${location}.denied_tools`);
625
+ if (enabledTools !== undefined && allowedTools !== undefined) {
626
+ throw new Error(`${location} cannot set both enabled_tools and allowed_tools`);
627
+ }
628
+ if (disabledTools !== undefined && deniedTools !== undefined) {
629
+ throw new Error(`${location} cannot set both disabled_tools and denied_tools`);
630
+ }
631
+ const effectiveEnabledTools = enabledTools ?? allowedTools;
632
+ const effectiveDisabledTools = disabledTools ?? deniedTools;
633
+ if (effectiveEnabledTools !== undefined) {
634
+ addOverride(args, `${base}.enabled_tools`, tomlStringArray(effectiveEnabledTools));
635
+ normalized.enabled_tools = effectiveEnabledTools;
636
+ }
637
+ if (effectiveDisabledTools !== undefined) {
638
+ addOverride(args, `${base}.disabled_tools`, tomlStringArray(effectiveDisabledTools));
639
+ normalized.disabled_tools = effectiveDisabledTools;
640
+ }
641
+ const defaultApproval = raw.default_tools_approval_mode === undefined
642
+ ? undefined
643
+ : requireEnum(raw.default_tools_approval_mode, APPROVAL_MODES, `${location}.default_tools_approval_mode`);
644
+ if (defaultApproval !== undefined) {
645
+ addOverride(args, `${base}.default_tools_approval_mode`, tomlString(defaultApproval));
646
+ normalized.default_tools_approval_mode = defaultApproval;
647
+ }
648
+ const toolsToml = tomlInlineApprovalTable(raw.tools, `${location}.tools`);
649
+ if (toolsToml !== undefined) {
650
+ addOverride(args, `${base}.tools`, toolsToml);
651
+ normalized.tools = normalizedApprovalTools(raw.tools, `${location}.tools`);
652
+ }
653
+ const scopes = optionalStringSet(raw.scopes, `${location}.scopes`);
654
+ if (scopes !== undefined) {
655
+ addOverride(args, `${base}.scopes`, tomlStringArray(scopes));
656
+ normalized.scopes = scopes;
657
+ }
658
+ const rawOauthResource = optionalString(raw.oauth_resource, `${location}.oauth_resource`);
659
+ const oauthResource = rawOauthResource === undefined
660
+ ? undefined
661
+ : validateHttpUrl(rawOauthResource, `${location}.oauth_resource`);
662
+ if (oauthResource !== undefined) {
663
+ if (url === undefined) {
664
+ throw new Error(`${location}.oauth_resource is only valid for HTTP servers`);
665
+ }
666
+ addOverride(args, `${base}.oauth_resource`, tomlString(oauthResource));
667
+ normalized.oauth_resource = oauthResource;
668
+ }
669
+ normalizedServers[name] = normalized;
670
+ }
671
+ const secretBindings = [...new Set([...userBindings, ...generatedBindings.keys()])]
672
+ .sort(codeUnitCompare)
673
+ .map((name) => [name, childEnv[name] ?? null]);
674
+ return {
675
+ args: consolidateMcpOverrides(args),
676
+ env: childEnv,
677
+ fingerprint: fingerprintPolicy(normalizedServers),
678
+ secretFingerprint: fingerprintPolicy(secretBindings),
679
+ };
680
+ }
59
681
  function getLocalMCPServerEntry() {
60
682
  try {
61
683
  return require.resolve('@jungjaehoon/mama-server');