@jungjaehoon/mama-os 0.22.1 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (257) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +3 -1
  3. package/dist/agent/agent-loop.d.ts +3 -9
  4. package/dist/agent/agent-loop.d.ts.map +1 -1
  5. package/dist/agent/agent-loop.js +419 -216
  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 +20 -7
  40. package/dist/agent/gateway-tool-executor.d.ts.map +1 -1
  41. package/dist/agent/gateway-tool-executor.js +254 -90
  42. package/dist/agent/gateway-tool-executor.js.map +1 -1
  43. package/dist/agent/gateway-tools.md +10 -5
  44. package/dist/agent/managed-agent-runtime-sync.d.ts.map +1 -1
  45. package/dist/agent/managed-agent-runtime-sync.js +0 -3
  46. package/dist/agent/managed-agent-runtime-sync.js.map +1 -1
  47. package/dist/agent/managed-agent-validation.js +1 -1
  48. package/dist/agent/managed-agent-validation.js.map +1 -1
  49. package/dist/agent/model-runner.d.ts +51 -3
  50. package/dist/agent/model-runner.d.ts.map +1 -1
  51. package/dist/agent/model-runner.js +1 -1
  52. package/dist/agent/model-runner.js.map +1 -1
  53. package/dist/agent/persistent-cli-adapter.d.ts +1 -0
  54. package/dist/agent/persistent-cli-adapter.d.ts.map +1 -1
  55. package/dist/agent/persistent-cli-adapter.js +3 -0
  56. package/dist/agent/persistent-cli-adapter.js.map +1 -1
  57. package/dist/agent/role-manager.d.ts +22 -1
  58. package/dist/agent/role-manager.d.ts.map +1 -1
  59. package/dist/agent/role-manager.js +39 -2
  60. package/dist/agent/role-manager.js.map +1 -1
  61. package/dist/agent/session-pool.d.ts +2 -2
  62. package/dist/agent/session-pool.d.ts.map +1 -1
  63. package/dist/agent/session-pool.js +6 -6
  64. package/dist/agent/session-pool.js.map +1 -1
  65. package/dist/agent/tool-registry.d.ts +14 -0
  66. package/dist/agent/tool-registry.d.ts.map +1 -1
  67. package/dist/agent/tool-registry.js +81 -12
  68. package/dist/agent/tool-registry.js.map +1 -1
  69. package/dist/agent/types.d.ts +49 -7
  70. package/dist/agent/types.d.ts.map +1 -1
  71. package/dist/agent/types.js.map +1 -1
  72. package/dist/api/graph-api.d.ts.map +1 -1
  73. package/dist/api/graph-api.js +62 -40
  74. package/dist/api/graph-api.js.map +1 -1
  75. package/dist/api/operator-tasks-handler.d.ts.map +1 -1
  76. package/dist/api/operator-tasks-handler.js +6 -2
  77. package/dist/api/operator-tasks-handler.js.map +1 -1
  78. package/dist/cli/commands/init.d.ts +1 -1
  79. package/dist/cli/commands/init.d.ts.map +1 -1
  80. package/dist/cli/commands/init.js +22 -14
  81. package/dist/cli/commands/init.js.map +1 -1
  82. package/dist/cli/commands/run.d.ts.map +1 -1
  83. package/dist/cli/commands/run.js +7 -4
  84. package/dist/cli/commands/run.js.map +1 -1
  85. package/dist/cli/commands/start.d.ts +2 -0
  86. package/dist/cli/commands/start.d.ts.map +1 -1
  87. package/dist/cli/commands/start.js +259 -23
  88. package/dist/cli/commands/start.js.map +1 -1
  89. package/dist/cli/commands/status.js +2 -2
  90. package/dist/cli/commands/status.js.map +1 -1
  91. package/dist/cli/config/config-manager.d.ts +0 -5
  92. package/dist/cli/config/config-manager.d.ts.map +1 -1
  93. package/dist/cli/config/config-manager.js +78 -6
  94. package/dist/cli/config/config-manager.js.map +1 -1
  95. package/dist/cli/config/types.d.ts +4 -4
  96. package/dist/cli/config/types.d.ts.map +1 -1
  97. package/dist/cli/config/types.js +36 -0
  98. package/dist/cli/config/types.js.map +1 -1
  99. package/dist/cli/index.js +2 -2
  100. package/dist/cli/index.js.map +1 -1
  101. package/dist/cli/runtime/agent-loop-init.d.ts +1 -1
  102. package/dist/cli/runtime/agent-loop-init.d.ts.map +1 -1
  103. package/dist/cli/runtime/agent-loop-init.js +106 -60
  104. package/dist/cli/runtime/agent-loop-init.js.map +1 -1
  105. package/dist/cli/runtime/api-routes-init.d.ts +3 -0
  106. package/dist/cli/runtime/api-routes-init.d.ts.map +1 -1
  107. package/dist/cli/runtime/api-routes-init.js +226 -51
  108. package/dist/cli/runtime/api-routes-init.js.map +1 -1
  109. package/dist/cli/runtime/connector-init.d.ts.map +1 -1
  110. package/dist/cli/runtime/connector-init.js +13 -17
  111. package/dist/cli/runtime/connector-init.js.map +1 -1
  112. package/dist/cli/runtime/envelope-bootstrap.d.ts.map +1 -1
  113. package/dist/cli/runtime/envelope-bootstrap.js +13 -1
  114. package/dist/cli/runtime/envelope-bootstrap.js.map +1 -1
  115. package/dist/cli/runtime/gateway-init.d.ts +1 -1
  116. package/dist/cli/runtime/gateway-init.d.ts.map +1 -1
  117. package/dist/cli/runtime/gateway-init.js +5 -0
  118. package/dist/cli/runtime/gateway-init.js.map +1 -1
  119. package/dist/cli/runtime/mama-core-init.d.ts +2 -2
  120. package/dist/cli/runtime/mama-core-init.d.ts.map +1 -1
  121. package/dist/cli/runtime/mama-core-init.js +17 -0
  122. package/dist/cli/runtime/mama-core-init.js.map +1 -1
  123. package/dist/cli/runtime/memory-agent-init.d.ts +1 -1
  124. package/dist/cli/runtime/memory-agent-init.d.ts.map +1 -1
  125. package/dist/cli/runtime/memory-agent-init.js +16 -6
  126. package/dist/cli/runtime/memory-agent-init.js.map +1 -1
  127. package/dist/cli/runtime/types.d.ts +4 -26
  128. package/dist/cli/runtime/types.d.ts.map +1 -1
  129. package/dist/cli/runtime/utilities.js +2 -2
  130. package/dist/cli/runtime/utilities.js.map +1 -1
  131. package/dist/connectors/config-loader.d.ts +24 -0
  132. package/dist/connectors/config-loader.d.ts.map +1 -0
  133. package/dist/connectors/config-loader.js +205 -0
  134. package/dist/connectors/config-loader.js.map +1 -0
  135. package/dist/connectors/framework/types.d.ts +2 -0
  136. package/dist/connectors/framework/types.d.ts.map +1 -1
  137. package/dist/connectors/kagemusha/query-tools.js +2 -2
  138. package/dist/connectors/kagemusha/query-tools.js.map +1 -1
  139. package/dist/envelope/reactive-config.d.ts +2 -2
  140. package/dist/envelope/reactive-config.d.ts.map +1 -1
  141. package/dist/envelope/reactive-config.js +36 -4
  142. package/dist/envelope/reactive-config.js.map +1 -1
  143. package/dist/gateways/context-injector.d.ts +2 -1
  144. package/dist/gateways/context-injector.d.ts.map +1 -1
  145. package/dist/gateways/context-injector.js.map +1 -1
  146. package/dist/gateways/message-router.d.ts +19 -1
  147. package/dist/gateways/message-router.d.ts.map +1 -1
  148. package/dist/gateways/message-router.js +179 -24
  149. package/dist/gateways/message-router.js.map +1 -1
  150. package/dist/gateways/telegram.d.ts.map +1 -1
  151. package/dist/gateways/telegram.js +13 -0
  152. package/dist/gateways/telegram.js.map +1 -1
  153. package/dist/gateways/types.d.ts +4 -1
  154. package/dist/gateways/types.d.ts.map +1 -1
  155. package/dist/memory/history-extractor.d.ts +0 -24
  156. package/dist/memory/history-extractor.d.ts.map +1 -1
  157. package/dist/memory/history-extractor.js +0 -132
  158. package/dist/memory/history-extractor.js.map +1 -1
  159. package/dist/memory/save-candidate-extractor.d.ts +3 -0
  160. package/dist/memory/save-candidate-extractor.d.ts.map +1 -1
  161. package/dist/memory/save-candidate-extractor.js +12 -1
  162. package/dist/memory/save-candidate-extractor.js.map +1 -1
  163. package/dist/memory/secret-filter.d.ts +22 -0
  164. package/dist/memory/secret-filter.d.ts.map +1 -0
  165. package/dist/memory/secret-filter.js +77 -0
  166. package/dist/memory/secret-filter.js.map +1 -0
  167. package/dist/multi-agent/agent-process-manager.d.ts +9 -1
  168. package/dist/multi-agent/agent-process-manager.d.ts.map +1 -1
  169. package/dist/multi-agent/agent-process-manager.js +197 -49
  170. package/dist/multi-agent/agent-process-manager.js.map +1 -1
  171. package/dist/multi-agent/multi-agent-base.d.ts.map +1 -1
  172. package/dist/multi-agent/multi-agent-base.js +2 -1
  173. package/dist/multi-agent/multi-agent-base.js.map +1 -1
  174. package/dist/multi-agent/runtime-process.d.ts +18 -15
  175. package/dist/multi-agent/runtime-process.d.ts.map +1 -1
  176. package/dist/multi-agent/runtime-process.js +63 -59
  177. package/dist/multi-agent/runtime-process.js.map +1 -1
  178. package/dist/multi-agent/types.d.ts +13 -7
  179. package/dist/multi-agent/types.d.ts.map +1 -1
  180. package/dist/multi-agent/types.js.map +1 -1
  181. package/dist/multi-agent/workflow-engine.js +3 -3
  182. package/dist/multi-agent/workflow-engine.js.map +1 -1
  183. package/dist/multi-agent/workflow-types.d.ts +2 -2
  184. package/dist/multi-agent/workflow-types.d.ts.map +1 -1
  185. package/dist/observability/code-audit.d.ts +4 -0
  186. package/dist/observability/code-audit.d.ts.map +1 -1
  187. package/dist/observability/code-audit.js +69 -0
  188. package/dist/observability/code-audit.js.map +1 -1
  189. package/dist/operator/briefs.d.ts +26 -0
  190. package/dist/operator/briefs.d.ts.map +1 -0
  191. package/dist/operator/briefs.js +128 -0
  192. package/dist/operator/briefs.js.map +1 -0
  193. package/dist/operator/operator-trigger-loop.d.ts +27 -0
  194. package/dist/operator/operator-trigger-loop.d.ts.map +1 -1
  195. package/dist/operator/operator-trigger-loop.js +72 -12
  196. package/dist/operator/operator-trigger-loop.js.map +1 -1
  197. package/dist/operator/report-carry.d.ts +29 -0
  198. package/dist/operator/report-carry.d.ts.map +1 -0
  199. package/dist/operator/report-carry.js +81 -0
  200. package/dist/operator/report-carry.js.map +1 -0
  201. package/dist/operator/report-run.d.ts +4 -4
  202. package/dist/operator/shadow-capture.d.ts +20 -0
  203. package/dist/operator/shadow-capture.d.ts.map +1 -0
  204. package/dist/operator/shadow-capture.js +34 -0
  205. package/dist/operator/shadow-capture.js.map +1 -0
  206. package/dist/operator/situation-report.d.ts +9 -0
  207. package/dist/operator/situation-report.d.ts.map +1 -1
  208. package/dist/operator/situation-report.js +56 -26
  209. package/dist/operator/situation-report.js.map +1 -1
  210. package/dist/operator/task-ledger.d.ts +90 -2
  211. package/dist/operator/task-ledger.d.ts.map +1 -1
  212. package/dist/operator/task-ledger.js +359 -23
  213. package/dist/operator/task-ledger.js.map +1 -1
  214. package/dist/operator/trigger-author.d.ts +35 -1
  215. package/dist/operator/trigger-author.d.ts.map +1 -1
  216. package/dist/operator/trigger-author.js +73 -10
  217. package/dist/operator/trigger-author.js.map +1 -1
  218. package/dist/operator/worker-run.d.ts +89 -0
  219. package/dist/operator/worker-run.d.ts.map +1 -0
  220. package/dist/operator/worker-run.js +127 -0
  221. package/dist/operator/worker-run.js.map +1 -0
  222. package/dist/operator/workorder-consumer.d.ts +121 -0
  223. package/dist/operator/workorder-consumer.d.ts.map +1 -0
  224. package/dist/operator/workorder-consumer.js +253 -0
  225. package/dist/operator/workorder-consumer.js.map +1 -0
  226. package/dist/operator/workorder-hooks.d.ts +30 -0
  227. package/dist/operator/workorder-hooks.d.ts.map +1 -0
  228. package/dist/operator/workorder-hooks.js +70 -0
  229. package/dist/operator/workorder-hooks.js.map +1 -0
  230. package/dist/operator/workorder-publishers.d.ts +68 -0
  231. package/dist/operator/workorder-publishers.d.ts.map +1 -0
  232. package/dist/operator/workorder-publishers.js +150 -0
  233. package/dist/operator/workorder-publishers.js.map +1 -0
  234. package/dist/security/security-monitor.d.ts +7 -0
  235. package/dist/security/security-monitor.d.ts.map +1 -1
  236. package/dist/security/security-monitor.js +17 -0
  237. package/dist/security/security-monitor.js.map +1 -1
  238. package/dist/setup/setup-prompt.d.ts +1 -1
  239. package/dist/setup/setup-prompt.d.ts.map +1 -1
  240. package/dist/setup/setup-prompt.js +4 -5
  241. package/dist/setup/setup-prompt.js.map +1 -1
  242. package/dist/utils/untrusted-content.d.ts +13 -0
  243. package/dist/utils/untrusted-content.d.ts.map +1 -1
  244. package/dist/utils/untrusted-content.js +43 -0
  245. package/dist/utils/untrusted-content.js.map +1 -1
  246. package/package.json +2 -2
  247. package/public/viewer/js/modules/agents.js +13 -9
  248. package/public/viewer/js/modules/settings.js +15 -10
  249. package/public/viewer/src/modules/agents.ts +12 -10
  250. package/public/viewer/src/modules/settings.ts +17 -12
  251. package/public/viewer/src/utils/api.ts +2 -2
  252. package/templates/AGENTS.codex.md +2 -23
  253. package/templates/personas/conductor.md +1 -1
  254. package/dist/agent/codex-mcp-process.d.ts +0 -105
  255. package/dist/agent/codex-mcp-process.d.ts.map +0 -1
  256. package/dist/agent/codex-mcp-process.js +0 -748
  257. package/dist/agent/codex-mcp-process.js.map +0 -1
@@ -29,6 +29,7 @@ const os_1 = __importDefault(require("os"));
29
29
  const js_yaml_1 = __importDefault(require("js-yaml"));
30
30
  const auth_middleware_js_1 = require("./auth-middleware.js");
31
31
  const trusted_proxy_js_1 = require("../security/trusted-proxy.js");
32
+ const types_js_1 = require("../cli/config/types.js");
32
33
  const agent_handler_js_1 = require("./agent-handler.js");
33
34
  const ui_command_handler_js_1 = require("./ui-command-handler.js");
34
35
  const entity_review_handler_js_1 = require("./entity-review-handler.js");
@@ -125,8 +126,8 @@ const codeActRateBuckets = new Map();
125
126
  // Model pattern helpers (used in multiple validation functions)
126
127
  const isClaudeModel = (model) => /^claude-/i.test(model);
127
128
  const isCodexModel = (model) => /^(gpt-|o\d|codex)/i.test(model);
128
- const supportedManagedBackends = ['claude', 'codex', 'codex-mcp'];
129
- const isCodexFamilyBackend = (backend) => backend === 'codex' || backend === 'codex-mcp';
129
+ const supportedManagedBackends = ['claude', 'codex'];
130
+ const isCodexFamilyBackend = (backend) => backend === 'codex';
130
131
  const VALIDATION_TRIGGER_TYPES = new Set([
131
132
  'agent_test',
132
133
  'delegate_run',
@@ -136,6 +137,10 @@ const VALIDATION_TRIGGER_TYPES = new Set([
136
137
  const isOpus46Model = (model) => /^claude-opus-4-6(?:$|-)/i.test(model) || model.toLowerCase() === 'claude-opus-4-latest';
137
138
  const VALID_EFFORT_LEVELS = new Set(['low', 'medium', 'high', 'max']);
138
139
  function normalizeLegacyManagedBackend(backend, configPath) {
140
+ if (typeof backend === 'string' && backend.toLowerCase() === 'codex-mcp') {
141
+ console.warn(`[GraphAPI] Deprecated backend "codex-mcp" at ${configPath}; using "codex" app-server for compatibility.`);
142
+ return 'codex';
143
+ }
139
144
  if (typeof backend === 'string' && backend.toLowerCase() === 'gemini') {
140
145
  console.warn(`[GraphAPI] Deprecated backend "gemini" at ${configPath}; using "claude" for compatibility.`);
141
146
  return 'claude';
@@ -150,6 +155,9 @@ function normalizeLegacyManagedModel(agent, configPath) {
150
155
  }
151
156
  return false;
152
157
  }
158
+ function isLegacyGeminiBackend(backend) {
159
+ return typeof backend === 'string' && backend.toLowerCase() === 'gemini';
160
+ }
153
161
  function isRecord(value) {
154
162
  return typeof value === 'object' && value !== null && !Array.isArray(value);
155
163
  }
@@ -162,8 +170,11 @@ function migrateLegacyManagedBackends(config) {
162
170
  const agent = { ...next.agent };
163
171
  const backend = normalizeLegacyManagedBackend(agent.backend, 'agent.backend');
164
172
  if (backend !== agent.backend) {
173
+ const migrateModel = isLegacyGeminiBackend(agent.backend);
165
174
  agent.backend = backend;
166
- normalizeLegacyManagedModel(agent, 'agent.model');
175
+ if (migrateModel) {
176
+ normalizeLegacyManagedModel(agent, 'agent.model');
177
+ }
167
178
  next.agent = agent;
168
179
  migrated = true;
169
180
  }
@@ -193,7 +204,9 @@ function migrateLegacyManagedBackends(config) {
193
204
  const inheritedBackendWasNormalized = !hasExplicitBackend && normalizedInheritedBackend !== inheritedBackend;
194
205
  if (normalizedBackend !== priorEffectiveBackend || inheritedBackendWasNormalized) {
195
206
  agent.backend = normalizedBackend;
196
- normalizeLegacyManagedModel(agent, `multi_agent.agents.${agentId}.model`);
207
+ if (isLegacyGeminiBackend(priorEffectiveBackend)) {
208
+ normalizeLegacyManagedModel(agent, `multi_agent.agents.${agentId}.model`);
209
+ }
197
210
  agents[agentId] = agent;
198
211
  agentsMigrated = true;
199
212
  migrated = true;
@@ -2384,39 +2397,12 @@ async function handleGetConfigRequest(_req, res) {
2384
2397
  quiet_start: 23,
2385
2398
  quiet_end: 8,
2386
2399
  },
2387
- roles: config.roles || {
2388
- definitions: {
2389
- os_agent: {
2390
- model: 'claude-sonnet-4-6',
2391
- maxTurns: 20,
2392
- allowedTools: ['*'],
2393
- systemControl: true,
2394
- sensitiveAccess: true,
2395
- },
2396
- chat_bot: {
2397
- model: 'claude-sonnet-4-6',
2398
- maxTurns: 10,
2399
- allowedTools: [
2400
- 'mama_search',
2401
- 'mama_recall',
2402
- 'context_compile',
2403
- 'mama_load_checkpoint',
2404
- 'Read',
2405
- 'discord_send',
2406
- ],
2407
- blockedTools: ['Bash', 'Write', 'mama_save', 'mama_update'],
2408
- systemControl: false,
2409
- sensitiveAccess: false,
2410
- },
2411
- },
2412
- sourceMapping: {
2413
- viewer: 'os_agent',
2414
- discord: 'chat_bot',
2415
- telegram: 'chat_bot',
2416
- slack: 'chat_bot',
2417
- chatwork: 'chat_bot',
2418
- },
2419
- },
2400
+ roles: config.roles
2401
+ ? {
2402
+ definitions: { ...types_js_1.DEFAULT_ROLES.definitions, ...config.roles.definitions },
2403
+ sourceMapping: { ...types_js_1.DEFAULT_ROLES.sourceMapping, ...config.roles.sourceMapping },
2404
+ }
2405
+ : types_js_1.DEFAULT_ROLES,
2420
2406
  multi_agent: config.multi_agent
2421
2407
  ? {
2422
2408
  enabled: config.multi_agent.enabled || false,
@@ -2740,7 +2726,7 @@ function validateConfigUpdate(config) {
2740
2726
  }
2741
2727
  if (config.agent.backend &&
2742
2728
  !supportedManagedBackends.includes(String(config.agent.backend).toLowerCase())) {
2743
- errors.push('agent.backend must be "claude", "codex", or "codex-mcp"');
2729
+ errors.push('agent.backend must be "claude" or "codex"');
2744
2730
  }
2745
2731
  if (config.agent.backend && config.agent.model && typeof config.agent.model === 'string') {
2746
2732
  const backend = String(config.agent.backend).toLowerCase();
@@ -2774,7 +2760,7 @@ function validateConfigUpdate(config) {
2774
2760
  if (backendRaw !== undefined) {
2775
2761
  const backend = String(backendRaw).toLowerCase();
2776
2762
  if (!supportedManagedBackends.includes(backend)) {
2777
- errors.push(`multi_agent.agents.${agentId}.backend must be "claude", "codex", or "codex-mcp"`);
2763
+ errors.push(`multi_agent.agents.${agentId}.backend must be "claude" or "codex"`);
2778
2764
  continue;
2779
2765
  }
2780
2766
  if (typeof modelRaw === 'string' && modelRaw.trim()) {
@@ -2790,12 +2776,48 @@ function validateConfigUpdate(config) {
2790
2776
  }
2791
2777
  return errors;
2792
2778
  }
2779
+ function canonicalRolesJson(value) {
2780
+ if (Array.isArray(value)) {
2781
+ return `[${value.map(canonicalRolesJson).join(',')}]`;
2782
+ }
2783
+ if (value && typeof value === 'object') {
2784
+ const entries = Object.entries(value)
2785
+ .sort(([a], [b]) => a.localeCompare(b))
2786
+ .map(([k, v]) => `${JSON.stringify(k)}:${canonicalRolesJson(v)}`);
2787
+ return `{${entries.join(',')}}`;
2788
+ }
2789
+ return JSON.stringify(value) ?? 'undefined';
2790
+ }
2793
2791
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
2794
2792
  function saveMAMAConfig(config) {
2795
2793
  const configDir = path_1.default.dirname(MAMA_CONFIG_PATH);
2796
2794
  if (!fs_1.default.existsSync(configDir)) {
2797
2795
  fs_1.default.mkdirSync(configDir, { recursive: true });
2798
2796
  }
2797
+ // Prune role entries identical to shipped defaults (review R3-m1): this UI
2798
+ // save path bypasses config-manager.saveConfig, and without the prune it
2799
+ // would freeze default definitions into config.yaml (B1 silent-death class).
2800
+ if (config.roles && types_js_1.DEFAULT_ROLES) {
2801
+ const definitions = {};
2802
+ for (const [name, def] of Object.entries(config.roles.definitions ?? {})) {
2803
+ const defaultDef = types_js_1.DEFAULT_ROLES.definitions[name];
2804
+ if (!defaultDef || canonicalRolesJson(def) !== canonicalRolesJson(defaultDef)) {
2805
+ definitions[name] = def;
2806
+ }
2807
+ }
2808
+ const sourceMapping = {};
2809
+ for (const [source, role] of Object.entries(config.roles.sourceMapping ?? {})) {
2810
+ if (types_js_1.DEFAULT_ROLES.sourceMapping[source] !== role) {
2811
+ sourceMapping[source] = role;
2812
+ }
2813
+ }
2814
+ if (Object.keys(definitions).length === 0 && Object.keys(sourceMapping).length === 0) {
2815
+ delete config.roles;
2816
+ }
2817
+ else {
2818
+ config.roles = { definitions, sourceMapping };
2819
+ }
2820
+ }
2799
2821
  const content = js_yaml_1.default.dump(config, {
2800
2822
  indent: 2,
2801
2823
  lineWidth: 120,
@@ -3090,7 +3112,7 @@ async function handleMultiAgentUpdateAgentRequest(req, res, pathname, options =
3090
3112
  if (body.backend !== undefined &&
3091
3113
  (typeof body.backend !== 'string' ||
3092
3114
  !supportedManagedBackends.includes(String(body.backend).toLowerCase()))) {
3093
- validationErrors.push('backend must be "claude", "codex", or "codex-mcp"');
3115
+ validationErrors.push('backend must be "claude" or "codex"');
3094
3116
  }
3095
3117
  const nextBackend = (body.backend !== undefined ? String(body.backend).toLowerCase() : currentAgent.backend);
3096
3118
  const nextModel = (body.model !== undefined ? body.model : currentAgent.model);