@jungjaehoon/mama-os 0.20.1 → 0.22.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 (264) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +12 -4
  3. package/dist/agent/agent-loop.d.ts.map +1 -1
  4. package/dist/agent/agent-loop.js +76 -11
  5. package/dist/agent/agent-loop.js.map +1 -1
  6. package/dist/agent/code-act/host-bridge.d.ts.map +1 -1
  7. package/dist/agent/code-act/host-bridge.js +88 -3
  8. package/dist/agent/code-act/host-bridge.js.map +1 -1
  9. package/dist/agent/codex-mcp-process.d.ts +1 -0
  10. package/dist/agent/codex-mcp-process.d.ts.map +1 -1
  11. package/dist/agent/codex-mcp-process.js +3 -2
  12. package/dist/agent/codex-mcp-process.js.map +1 -1
  13. package/dist/agent/gateway-tool-executor.d.ts +24 -11
  14. package/dist/agent/gateway-tool-executor.d.ts.map +1 -1
  15. package/dist/agent/gateway-tool-executor.js +349 -30
  16. package/dist/agent/gateway-tool-executor.js.map +1 -1
  17. package/dist/agent/gateway-tools.md +7 -2
  18. package/dist/agent/model-runner.d.ts +8 -0
  19. package/dist/agent/model-runner.d.ts.map +1 -1
  20. package/dist/agent/model-runner.js.map +1 -1
  21. package/dist/agent/os-agent-capabilities.md +13 -12
  22. package/dist/agent/persistent-cli-adapter.d.ts +6 -0
  23. package/dist/agent/persistent-cli-adapter.d.ts.map +1 -1
  24. package/dist/agent/persistent-cli-adapter.js +21 -10
  25. package/dist/agent/persistent-cli-adapter.js.map +1 -1
  26. package/dist/agent/tool-registry.d.ts.map +1 -1
  27. package/dist/agent/tool-registry.js +33 -2
  28. package/dist/agent/tool-registry.js.map +1 -1
  29. package/dist/agent/types.d.ts +30 -2
  30. package/dist/agent/types.d.ts.map +1 -1
  31. package/dist/agent/types.js.map +1 -1
  32. package/dist/api/graph-api.d.ts.map +1 -1
  33. package/dist/api/graph-api.js +78 -5
  34. package/dist/api/graph-api.js.map +1 -1
  35. package/dist/api/index.d.ts +8 -1
  36. package/dist/api/index.d.ts.map +1 -1
  37. package/dist/api/index.js +18 -12
  38. package/dist/api/index.js.map +1 -1
  39. package/dist/api/operator-handler.d.ts +19 -0
  40. package/dist/api/operator-handler.d.ts.map +1 -0
  41. package/dist/api/operator-handler.js +106 -0
  42. package/dist/api/operator-handler.js.map +1 -0
  43. package/dist/api/operator-summary.d.ts +3 -0
  44. package/dist/api/operator-summary.d.ts.map +1 -0
  45. package/dist/api/operator-summary.js +72 -0
  46. package/dist/api/operator-summary.js.map +1 -0
  47. package/dist/api/operator-tasks-handler.d.ts +7 -0
  48. package/dist/api/operator-tasks-handler.d.ts.map +1 -0
  49. package/dist/api/operator-tasks-handler.js +165 -0
  50. package/dist/api/operator-tasks-handler.js.map +1 -0
  51. package/dist/api/report-handler.d.ts +7 -0
  52. package/dist/api/report-handler.d.ts.map +1 -1
  53. package/dist/api/report-handler.js +30 -0
  54. package/dist/api/report-handler.js.map +1 -1
  55. package/dist/api/report-persistence.d.ts +17 -0
  56. package/dist/api/report-persistence.d.ts.map +1 -0
  57. package/dist/api/report-persistence.js +91 -0
  58. package/dist/api/report-persistence.js.map +1 -0
  59. package/dist/cli/commands/start.d.ts.map +1 -1
  60. package/dist/cli/commands/start.js +402 -250
  61. package/dist/cli/commands/start.js.map +1 -1
  62. package/dist/cli/config/config-manager.d.ts.map +1 -1
  63. package/dist/cli/config/config-manager.js +93 -55
  64. package/dist/cli/config/config-manager.js.map +1 -1
  65. package/dist/cli/config/types.d.ts +17 -2
  66. package/dist/cli/config/types.d.ts.map +1 -1
  67. package/dist/cli/config/types.js +4 -0
  68. package/dist/cli/config/types.js.map +1 -1
  69. package/dist/cli/runtime/agent-loop-init.d.ts +3 -1
  70. package/dist/cli/runtime/agent-loop-init.d.ts.map +1 -1
  71. package/dist/cli/runtime/agent-loop-init.js +16 -7
  72. package/dist/cli/runtime/agent-loop-init.js.map +1 -1
  73. package/dist/cli/runtime/api-routes-init.d.ts.map +1 -1
  74. package/dist/cli/runtime/api-routes-init.js +503 -259
  75. package/dist/cli/runtime/api-routes-init.js.map +1 -1
  76. package/dist/cli/runtime/api-server-init.d.ts.map +1 -1
  77. package/dist/cli/runtime/api-server-init.js +12 -7
  78. package/dist/cli/runtime/api-server-init.js.map +1 -1
  79. package/dist/cli/runtime/connector-init.d.ts +19 -1
  80. package/dist/cli/runtime/connector-init.d.ts.map +1 -1
  81. package/dist/cli/runtime/connector-init.js +32 -2
  82. package/dist/cli/runtime/connector-init.js.map +1 -1
  83. package/dist/cli/runtime/gateway-init.d.ts.map +1 -1
  84. package/dist/cli/runtime/gateway-init.js +3 -1
  85. package/dist/cli/runtime/gateway-init.js.map +1 -1
  86. package/dist/cli/runtime/memory-agent-init.d.ts +2 -1
  87. package/dist/cli/runtime/memory-agent-init.d.ts.map +1 -1
  88. package/dist/cli/runtime/memory-agent-init.js +15 -3
  89. package/dist/cli/runtime/memory-agent-init.js.map +1 -1
  90. package/dist/cli/runtime/message-router-config.d.ts +4 -0
  91. package/dist/cli/runtime/message-router-config.d.ts.map +1 -0
  92. package/dist/cli/runtime/message-router-config.js +11 -0
  93. package/dist/cli/runtime/message-router-config.js.map +1 -0
  94. package/dist/cli/runtime/scheduler-init.d.ts.map +1 -1
  95. package/dist/cli/runtime/scheduler-init.js +12 -12
  96. package/dist/cli/runtime/scheduler-init.js.map +1 -1
  97. package/dist/connectors/framework/polling-scheduler.d.ts.map +1 -1
  98. package/dist/connectors/framework/polling-scheduler.js +53 -2
  99. package/dist/connectors/framework/polling-scheduler.js.map +1 -1
  100. package/dist/connectors/framework/types.d.ts +8 -0
  101. package/dist/connectors/framework/types.d.ts.map +1 -1
  102. package/dist/connectors/kagemusha/query-tools.d.ts.map +1 -1
  103. package/dist/connectors/kagemusha/query-tools.js +14 -3
  104. package/dist/connectors/kagemusha/query-tools.js.map +1 -1
  105. package/dist/connectors/slack/index.d.ts.map +1 -1
  106. package/dist/connectors/slack/index.js +3 -1
  107. package/dist/connectors/slack/index.js.map +1 -1
  108. package/dist/connectors/trello/index.d.ts.map +1 -1
  109. package/dist/connectors/trello/index.js +6 -2
  110. package/dist/connectors/trello/index.js.map +1 -1
  111. package/dist/db/agent-store.d.ts +5 -0
  112. package/dist/db/agent-store.d.ts.map +1 -1
  113. package/dist/db/agent-store.js +6 -3
  114. package/dist/db/agent-store.js.map +1 -1
  115. package/dist/db/migrations/agent-activity-tool-name.d.ts +8 -0
  116. package/dist/db/migrations/agent-activity-tool-name.d.ts.map +1 -0
  117. package/dist/db/migrations/agent-activity-tool-name.js +24 -0
  118. package/dist/db/migrations/agent-activity-tool-name.js.map +1 -0
  119. package/dist/db/migrations/wiki-artifacts.d.ts +3 -0
  120. package/dist/db/migrations/wiki-artifacts.d.ts.map +1 -0
  121. package/dist/db/migrations/wiki-artifacts.js +24 -0
  122. package/dist/db/migrations/wiki-artifacts.js.map +1 -0
  123. package/dist/envelope/run-guard.d.ts +10 -0
  124. package/dist/envelope/run-guard.d.ts.map +1 -0
  125. package/dist/envelope/run-guard.js +19 -0
  126. package/dist/envelope/run-guard.js.map +1 -0
  127. package/dist/gateways/message-router.d.ts.map +1 -1
  128. package/dist/gateways/message-router.js +15 -3
  129. package/dist/gateways/message-router.js.map +1 -1
  130. package/dist/gateways/types.d.ts +4 -0
  131. package/dist/gateways/types.d.ts.map +1 -1
  132. package/dist/multi-agent/agent-event-bus.d.ts +14 -0
  133. package/dist/multi-agent/agent-event-bus.d.ts.map +1 -1
  134. package/dist/multi-agent/agent-event-bus.js +34 -0
  135. package/dist/multi-agent/agent-event-bus.js.map +1 -1
  136. package/dist/multi-agent/conductor-persona.js +2 -2
  137. package/dist/multi-agent/dashboard-agent-persona.d.ts +6 -2
  138. package/dist/multi-agent/dashboard-agent-persona.d.ts.map +1 -1
  139. package/dist/multi-agent/dashboard-agent-persona.js +65 -32
  140. package/dist/multi-agent/dashboard-agent-persona.js.map +1 -1
  141. package/dist/multi-agent/memory-agent-persona.d.ts +1 -1
  142. package/dist/multi-agent/memory-agent-persona.d.ts.map +1 -1
  143. package/dist/multi-agent/memory-agent-persona.js +25 -4
  144. package/dist/multi-agent/memory-agent-persona.js.map +1 -1
  145. package/dist/multi-agent/runtime-process.d.ts +4 -2
  146. package/dist/multi-agent/runtime-process.d.ts.map +1 -1
  147. package/dist/multi-agent/runtime-process.js +7 -4
  148. package/dist/multi-agent/runtime-process.js.map +1 -1
  149. package/dist/multi-agent/types.d.ts +1 -1
  150. package/dist/multi-agent/wiki-agent-persona.d.ts +7 -1
  151. package/dist/multi-agent/wiki-agent-persona.d.ts.map +1 -1
  152. package/dist/multi-agent/wiki-agent-persona.js +82 -68
  153. package/dist/multi-agent/wiki-agent-persona.js.map +1 -1
  154. package/dist/operator/action-verifier.d.ts +50 -0
  155. package/dist/operator/action-verifier.d.ts.map +1 -0
  156. package/dist/operator/action-verifier.js +68 -0
  157. package/dist/operator/action-verifier.js.map +1 -0
  158. package/dist/operator/board-reconcile.d.ts +62 -0
  159. package/dist/operator/board-reconcile.d.ts.map +1 -0
  160. package/dist/operator/board-reconcile.js +160 -0
  161. package/dist/operator/board-reconcile.js.map +1 -0
  162. package/dist/operator/board-slot-instructions.d.ts +26 -0
  163. package/dist/operator/board-slot-instructions.d.ts.map +1 -0
  164. package/dist/operator/board-slot-instructions.js +76 -0
  165. package/dist/operator/board-slot-instructions.js.map +1 -0
  166. package/dist/operator/connector-delta-repo.d.ts +33 -0
  167. package/dist/operator/connector-delta-repo.d.ts.map +1 -0
  168. package/dist/operator/connector-delta-repo.js +0 -0
  169. package/dist/operator/connector-delta-repo.js.map +1 -0
  170. package/dist/operator/mama-memory-port.d.ts +13 -0
  171. package/dist/operator/mama-memory-port.d.ts.map +1 -0
  172. package/dist/operator/mama-memory-port.js +35 -0
  173. package/dist/operator/mama-memory-port.js.map +1 -0
  174. package/dist/operator/operator-interfaces.d.ts +136 -0
  175. package/dist/operator/operator-interfaces.d.ts.map +1 -0
  176. package/dist/operator/operator-interfaces.js +15 -0
  177. package/dist/operator/operator-interfaces.js.map +1 -0
  178. package/dist/operator/operator-trigger-loop.d.ts +119 -0
  179. package/dist/operator/operator-trigger-loop.d.ts.map +1 -0
  180. package/dist/operator/operator-trigger-loop.js +267 -0
  181. package/dist/operator/operator-trigger-loop.js.map +1 -0
  182. package/dist/operator/report-run.d.ts +78 -0
  183. package/dist/operator/report-run.d.ts.map +1 -0
  184. package/dist/operator/report-run.js +141 -0
  185. package/dist/operator/report-run.js.map +1 -0
  186. package/dist/operator/report-scheduler.d.ts +66 -0
  187. package/dist/operator/report-scheduler.d.ts.map +1 -0
  188. package/dist/operator/report-scheduler.js +135 -0
  189. package/dist/operator/report-scheduler.js.map +1 -0
  190. package/dist/operator/situation-report.d.ts +90 -0
  191. package/dist/operator/situation-report.d.ts.map +1 -0
  192. package/dist/operator/situation-report.js +221 -0
  193. package/dist/operator/situation-report.js.map +1 -0
  194. package/dist/operator/task-ledger.d.ts +96 -0
  195. package/dist/operator/task-ledger.d.ts.map +1 -0
  196. package/dist/operator/task-ledger.js +277 -0
  197. package/dist/operator/task-ledger.js.map +1 -0
  198. package/dist/operator/trigger-author.d.ts +45 -0
  199. package/dist/operator/trigger-author.d.ts.map +1 -0
  200. package/dist/operator/trigger-author.js +217 -0
  201. package/dist/operator/trigger-author.js.map +1 -0
  202. package/dist/operator/trigger-evolve.d.ts +31 -0
  203. package/dist/operator/trigger-evolve.d.ts.map +1 -0
  204. package/dist/operator/trigger-evolve.js +51 -0
  205. package/dist/operator/trigger-evolve.js.map +1 -0
  206. package/dist/operator/trigger-fire.d.ts +29 -0
  207. package/dist/operator/trigger-fire.d.ts.map +1 -0
  208. package/dist/operator/trigger-fire.js +41 -0
  209. package/dist/operator/trigger-fire.js.map +1 -0
  210. package/dist/operator/trigger-matcher.d.ts +19 -0
  211. package/dist/operator/trigger-matcher.d.ts.map +1 -0
  212. package/dist/operator/trigger-matcher.js +61 -0
  213. package/dist/operator/trigger-matcher.js.map +1 -0
  214. package/dist/operator/trigger-registry.d.ts +36 -0
  215. package/dist/operator/trigger-registry.d.ts.map +1 -0
  216. package/dist/operator/trigger-registry.js +135 -0
  217. package/dist/operator/trigger-registry.js.map +1 -0
  218. package/dist/operator/trigger-review.d.ts +23 -0
  219. package/dist/operator/trigger-review.d.ts.map +1 -0
  220. package/dist/operator/trigger-review.js +127 -0
  221. package/dist/operator/trigger-review.js.map +1 -0
  222. package/dist/operator/trigger-types.d.ts +84 -0
  223. package/dist/operator/trigger-types.d.ts.map +1 -0
  224. package/dist/operator/trigger-types.js +14 -0
  225. package/dist/operator/trigger-types.js.map +1 -0
  226. package/dist/scheduler/cron-worker.d.ts.map +1 -1
  227. package/dist/scheduler/cron-worker.js +3 -1
  228. package/dist/scheduler/cron-worker.js.map +1 -1
  229. package/dist/security/security-monitor.d.ts.map +1 -1
  230. package/dist/security/security-monitor.js +1 -0
  231. package/dist/security/security-monitor.js.map +1 -1
  232. package/dist/wiki/obsidian-writer.d.ts +1 -1
  233. package/dist/wiki/obsidian-writer.d.ts.map +1 -1
  234. package/dist/wiki/obsidian-writer.js +67 -27
  235. package/dist/wiki/obsidian-writer.js.map +1 -1
  236. package/dist/wiki/path-safety.d.ts +2 -0
  237. package/dist/wiki/path-safety.d.ts.map +1 -0
  238. package/dist/wiki/path-safety.js +40 -0
  239. package/dist/wiki/path-safety.js.map +1 -0
  240. package/dist/wiki/types.d.ts +4 -2
  241. package/dist/wiki/types.d.ts.map +1 -1
  242. package/dist/wiki/types.js +1 -1
  243. package/dist/wiki/types.js.map +1 -1
  244. package/dist/wiki-artifacts/normalization.d.ts +8 -0
  245. package/dist/wiki-artifacts/normalization.d.ts.map +1 -0
  246. package/dist/wiki-artifacts/normalization.js +41 -0
  247. package/dist/wiki-artifacts/normalization.js.map +1 -0
  248. package/dist/wiki-artifacts/types.d.ts +52 -0
  249. package/dist/wiki-artifacts/types.d.ts.map +1 -0
  250. package/dist/wiki-artifacts/types.js +3 -0
  251. package/dist/wiki-artifacts/types.js.map +1 -0
  252. package/dist/wiki-artifacts/wiki-publish-adapter.d.ts +14 -0
  253. package/dist/wiki-artifacts/wiki-publish-adapter.d.ts.map +1 -0
  254. package/dist/wiki-artifacts/wiki-publish-adapter.js +71 -0
  255. package/dist/wiki-artifacts/wiki-publish-adapter.js.map +1 -0
  256. package/package.json +5 -3
  257. package/public/ui/assets/index-CKOJQYXA.css +1 -0
  258. package/public/ui/assets/index-OSgiwL24.js +62 -0
  259. package/public/ui/index.html +14 -0
  260. package/public/ui/theme-init.js +20 -0
  261. package/public/viewer/js/utils/api.js +2 -2
  262. package/public/viewer/src/utils/api.ts +9 -2
  263. package/public/viewer/sw.js +1 -1
  264. package/public/viewer/viewer.html +17 -27
@@ -44,6 +44,9 @@ var __importStar = (this && this.__importStar) || (function () {
44
44
  return result;
45
45
  };
46
46
  })();
47
+ var __importDefault = (this && this.__importDefault) || function (mod) {
48
+ return (mod && mod.__esModule) ? mod : { "default": mod };
49
+ };
47
50
  Object.defineProperty(exports, "__esModule", { value: true });
48
51
  exports.GatewayToolExecutor = void 0;
49
52
  const fs_1 = require("fs");
@@ -58,6 +61,7 @@ const mama_core_1 = require("@jungjaehoon/mama-core");
58
61
  const security_monitor_js_1 = require("../security/security-monitor.js");
59
62
  const scope_context_js_1 = require("../memory/scope-context.js");
60
63
  const types_js_1 = require("./types.js");
64
+ const sqlite_js_1 = __importDefault(require("../sqlite.js"));
61
65
  const mama_tool_handlers_js_1 = require("./mama-tool-handlers.js");
62
66
  const browser_tool_js_1 = require("../tools/browser-tool.js");
63
67
  const role_manager_js_1 = require("./role-manager.js");
@@ -68,6 +72,7 @@ const managed_agent_runtime_sync_js_1 = require("./managed-agent-runtime-sync.js
68
72
  const managed_agent_validation_js_1 = require("./managed-agent-validation.js");
69
73
  const delegation_executor_js_1 = require("./delegation-executor.js");
70
74
  const index_js_1 = require("../envelope/index.js");
75
+ const wiki_publish_adapter_js_1 = require("../wiki-artifacts/wiki-publish-adapter.js");
71
76
  const { DebugLogger } = debugLogger;
72
77
  const securityLogger = new DebugLogger('SecurityAudit');
73
78
  const TRUTHY_ENV_VALUES = new Set(['1', 'true', 'yes', 'on']);
@@ -80,6 +85,24 @@ const AGENT_DETAIL_TABS = new Set([
80
85
  'validation',
81
86
  'history',
82
87
  ]);
88
+ const RECALL_TEXT_REDACTION_PATTERNS = [
89
+ /MAMA_SYNTHETIC_[A-Z0-9_]+_DO_NOT_LEAK/g,
90
+ /synthetic:\/\/raw[^\s"']*/g,
91
+ /raw:[^\s"']*/g,
92
+ /\bhttps?:\/\/[^\s"'<>()]+/gi,
93
+ /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi,
94
+ /\b(?:Bearer|Token|Authorization)\s*[:=]?\s*[A-Za-z0-9._~+/=-]{8,}/gi,
95
+ /\b(?:api[_-]?key|token|secret|password)\s*[:=]\s*[^\s"']{8,}/gi,
96
+ /(?:ghp|gho|ghu|ghs|ghr|github_pat)_[A-Za-z0-9_]{8,}\b/g,
97
+ /xox[baprs]-[A-Za-z0-9-]{10,}\b/g,
98
+ /sk-[A-Za-z0-9_-]{20,}\b/g,
99
+ /\b[CU][A-Z0-9]{8,}\b/g,
100
+ /\b[0-9]{17,20}\b/g,
101
+ /(?:\/Users|\/home|\/tmp)\/[^\s"']*/g,
102
+ /[A-Za-z]:\\Users\\[^\s"']*/g,
103
+ ];
104
+ const MAX_RECALL_TEXT_LENGTH = 280;
105
+ const RECALL_TEXT_REDACTION_SCAN_LIMIT = MAX_RECALL_TEXT_LENGTH + 2048;
83
106
  const managedAgentMutationTails = new Map();
84
107
  const MEMORY_SCOPE_AUDIT_TOOLS = new Set([
85
108
  'mama_save',
@@ -103,6 +126,112 @@ const ENVELOPE_REQUIRED_SURFACES = new Set([
103
126
  ]);
104
127
  class ContextPacketProvenanceError extends Error {
105
128
  }
129
+ function asRecord(value) {
130
+ return value && typeof value === 'object' && !Array.isArray(value)
131
+ ? value
132
+ : null;
133
+ }
134
+ function stringField(record, field) {
135
+ const value = record[field];
136
+ return typeof value === 'string' ? value : undefined;
137
+ }
138
+ function numberField(record, field) {
139
+ const value = record[field];
140
+ return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
141
+ }
142
+ function sanitizeRecallText(value) {
143
+ if (!value) {
144
+ return undefined;
145
+ }
146
+ let sanitized = value.length > RECALL_TEXT_REDACTION_SCAN_LIMIT
147
+ ? value.slice(0, RECALL_TEXT_REDACTION_SCAN_LIMIT)
148
+ : value;
149
+ for (const pattern of RECALL_TEXT_REDACTION_PATTERNS) {
150
+ sanitized = sanitized.replace(pattern, '[redacted]');
151
+ }
152
+ const wasTruncated = value.length > MAX_RECALL_TEXT_LENGTH || sanitized.length > MAX_RECALL_TEXT_LENGTH;
153
+ if (sanitized.length > MAX_RECALL_TEXT_LENGTH) {
154
+ sanitized = sanitized.slice(0, MAX_RECALL_TEXT_LENGTH);
155
+ }
156
+ if (wasTruncated) {
157
+ sanitized = `${sanitized} [truncated]`;
158
+ }
159
+ return sanitized;
160
+ }
161
+ function sanitizeRecallMemory(value) {
162
+ const record = asRecord(value);
163
+ if (!record) {
164
+ return null;
165
+ }
166
+ const safe = {};
167
+ const topic = sanitizeRecallText(stringField(record, 'topic'));
168
+ const kind = sanitizeRecallText(stringField(record, 'kind'));
169
+ const summary = sanitizeRecallText(stringField(record, 'summary'));
170
+ const status = sanitizeRecallText(stringField(record, 'status'));
171
+ const confidence = numberField(record, 'confidence');
172
+ if (topic) {
173
+ safe.topic = topic;
174
+ }
175
+ if (kind) {
176
+ safe.kind = kind;
177
+ }
178
+ if (summary) {
179
+ safe.summary = summary;
180
+ }
181
+ if (status) {
182
+ safe.status = status;
183
+ }
184
+ if (confidence !== undefined) {
185
+ safe.confidence = confidence;
186
+ }
187
+ return Object.keys(safe).length > 0 ? safe : null;
188
+ }
189
+ function sanitizeRecallMemories(value) {
190
+ if (!Array.isArray(value)) {
191
+ return [];
192
+ }
193
+ return value
194
+ .map((memory) => sanitizeRecallMemory(memory))
195
+ .filter((memory) => memory !== null);
196
+ }
197
+ function sanitizeProfileEvidence(value) {
198
+ if (!Array.isArray(value)) {
199
+ return [];
200
+ }
201
+ return value
202
+ .map((item) => {
203
+ const record = asRecord(item);
204
+ if (!record) {
205
+ return null;
206
+ }
207
+ const evidence = {};
208
+ const topic = sanitizeRecallText(stringField(record, 'topic'));
209
+ if (topic) {
210
+ evidence.topic = topic;
211
+ }
212
+ return Object.keys(evidence).length > 0 ? evidence : null;
213
+ })
214
+ .filter((evidence) => evidence !== null);
215
+ }
216
+ function sanitizeMamaRecallBundle(bundle) {
217
+ const record = asRecord(bundle) ?? {};
218
+ const profile = asRecord(record.profile) ?? {};
219
+ const graphContext = asRecord(record.graph_context) ?? {};
220
+ const edges = Array.isArray(graphContext.edges) ? graphContext.edges : [];
221
+ return {
222
+ profile: {
223
+ static: sanitizeRecallMemories(profile.static),
224
+ dynamic: sanitizeRecallMemories(profile.dynamic),
225
+ evidence: sanitizeProfileEvidence(profile.evidence),
226
+ },
227
+ memories: sanitizeRecallMemories(record.memories),
228
+ graph_context: {
229
+ primary: sanitizeRecallMemories(graphContext.primary),
230
+ expanded: sanitizeRecallMemories(graphContext.expanded),
231
+ edge_count: edges.length,
232
+ },
233
+ };
234
+ }
106
235
  async function withManagedAgentMutationLock(agentId, fn) {
107
236
  const previous = managedAgentMutationTails.get(agentId) ?? Promise.resolve();
108
237
  let release;
@@ -164,9 +293,19 @@ class GatewayToolExecutor {
164
293
  disallowedGatewayTools = new Set();
165
294
  reportPublisher = null;
166
295
  wikiPublisher = null;
296
+ wikiPublishAdapter = null;
167
297
  obsidianVaultPath = null;
168
- setObsidianVaultPath(vaultPath) {
298
+ obsidianVaultName = null;
299
+ setObsidianVaultPath(vaultPath, vaultName) {
169
300
  this.obsidianVaultPath = vaultPath;
301
+ this.obsidianVaultName = vaultName ?? null;
302
+ }
303
+ taskLedger = null;
304
+ setTaskLedger(ledger) {
305
+ this.taskLedger = ledger;
306
+ }
307
+ getTaskLedger() {
308
+ return this.taskLedger;
170
309
  }
171
310
  agentEventBus = null;
172
311
  setAgentEventBus(bus) {
@@ -236,6 +375,7 @@ class GatewayToolExecutor {
236
375
  modelRunId: executionContext?.modelRunId ?? null,
237
376
  gatewayCallId: executionContext?.gatewayCallId,
238
377
  backgroundTasks: executionContext?.backgroundTasks,
378
+ disallowedGatewayTools: executionContext?.disallowedGatewayTools,
239
379
  };
240
380
  }
241
381
  getExecutionState() {
@@ -267,6 +407,8 @@ class GatewayToolExecutor {
267
407
  gatewayCallId: active.gatewayCallId ?? fallback.gatewayCallId,
268
408
  parentToolName: active.parentToolName ?? fallback.parentToolName,
269
409
  backgroundTasks: active.backgroundTasks ?? fallback.backgroundTasks,
410
+ // Never merged from fallback - blocks are strictly per-call.
411
+ disallowedGatewayTools: active.disallowedGatewayTools,
270
412
  };
271
413
  }
272
414
  getActiveContext() {
@@ -394,6 +536,9 @@ class GatewayToolExecutor {
394
536
  setWikiPublisher(fn) {
395
537
  this.wikiPublisher = fn;
396
538
  }
539
+ setWikiPublishAdapter(adapter) {
540
+ this.wikiPublishAdapter = adapter;
541
+ }
397
542
  /** Check if a memory agent is available for routing memory writes. */
398
543
  hasMemoryAgent() {
399
544
  return this.memoryAgentProcessManager !== null;
@@ -431,6 +576,7 @@ class GatewayToolExecutor {
431
576
  this.envelopeIssuanceMode = options.envelopeIssuanceMode ?? 'enabled';
432
577
  this.metricsStore = options.metricsStore ?? null;
433
578
  this.contextCompileService = options.contextCompileService;
579
+ this.wikiPublishAdapter = options.wikiPublishAdapter ?? null;
434
580
  this.browserTool = (0, browser_tool_js_1.getBrowserTool)({
435
581
  screenshotDir: (0, path_1.join)(process.env.HOME || '', '.mama', 'workspace', 'media', 'outbound'),
436
582
  });
@@ -485,6 +631,11 @@ class GatewayToolExecutor {
485
631
  setContextCompileService(service) {
486
632
  this.contextCompileService = service;
487
633
  }
634
+ /** Wire the shared MAMA API built at boot (initMamaCore) so the executor never
635
+ * lazily constructs a second API/adapter stack against the same DB. */
636
+ setMamaApi(api) {
637
+ this.mamaApi = api;
638
+ }
488
639
  /**
489
640
  * Initialize the MAMA API by importing from mcp-server package
490
641
  * Called lazily on first tool execution if not provided in constructor
@@ -883,6 +1034,52 @@ class GatewayToolExecutor {
883
1034
  projectId: process.env.MAMA_WORKSPACE || process.cwd(),
884
1035
  });
885
1036
  }
1037
+ resolveMamaRecallScopes(input) {
1038
+ const ctx = this.getExecutionState();
1039
+ const requestedScopes = normalizeMemoryScopes(input.scopes);
1040
+ const callerProvidedScopes = input.scopes !== undefined;
1041
+ const allowedScopes = ctx.envelope?.scope.memory_scopes ?? this.deriveMemoryScopesFromActiveContext(ctx) ?? [];
1042
+ const hasActiveScopeBoundary = Boolean(ctx.envelope || ctx.agentContext);
1043
+ if (callerProvidedScopes && !requestedScopes) {
1044
+ return {
1045
+ scopes: [],
1046
+ denial: {
1047
+ success: false,
1048
+ code: 'memory_scope_invalid',
1049
+ error: 'mama_recall scopes must be valid memory scope objects.',
1050
+ },
1051
+ };
1052
+ }
1053
+ if (!hasActiveScopeBoundary) {
1054
+ if (callerProvidedScopes) {
1055
+ return {
1056
+ scopes: [],
1057
+ denial: {
1058
+ success: false,
1059
+ code: 'memory_scope_denied',
1060
+ error: 'mama_recall requires an active session or envelope for caller-supplied scopes.',
1061
+ },
1062
+ };
1063
+ }
1064
+ return { scopes: [] };
1065
+ }
1066
+ if (!requestedScopes || requestedScopes.length === 0) {
1067
+ return { scopes: allowedScopes };
1068
+ }
1069
+ const allowedScopeKeys = new Set(allowedScopes.map(memoryScopeKey));
1070
+ const hasUnauthorizedScope = requestedScopes.some((scope) => !allowedScopeKeys.has(memoryScopeKey(scope)));
1071
+ if (hasUnauthorizedScope) {
1072
+ return {
1073
+ scopes: [],
1074
+ denial: {
1075
+ success: false,
1076
+ code: 'memory_scope_denied',
1077
+ error: 'mama_recall requested scopes outside the active session or envelope.',
1078
+ },
1079
+ };
1080
+ }
1081
+ return { scopes: requestedScopes };
1082
+ }
886
1083
  applyEnvelopeScopedReadDefaults(toolName, input, ctx) {
887
1084
  // Memory read tools must inherit envelope scopes consistently when the
888
1085
  // caller omits scopes. Otherwise recall can fall back to active-context
@@ -1003,6 +1200,8 @@ class GatewayToolExecutor {
1003
1200
  agent_version: 0,
1004
1201
  type: 'gateway_tool_call',
1005
1202
  input_summary: toolName,
1203
+ tool_name: toolName,
1204
+ normalized_tool_name: toolName,
1006
1205
  duration_ms: durationMs,
1007
1206
  execution_status: executionStatus,
1008
1207
  trigger_reason: 'gateway_tool_executor',
@@ -1058,8 +1257,10 @@ class GatewayToolExecutor {
1058
1257
  if (!VALID_TOOLS.includes(toolName)) {
1059
1258
  throw new types_js_1.AgentError(`Unknown tool: ${toolName}. Valid tools: ${VALID_TOOLS.join(', ')}`, 'UNKNOWN_TOOL', undefined, false);
1060
1259
  }
1061
- // Check structurally disallowed tools (e.g., OS agent can't use sub-agent tools)
1062
- if (this.disallowedGatewayTools.has(toolName)) {
1260
+ // Structurally disallowed tools are per-call policy carried by the execution
1261
+ // context (a shared executor serves many agents with different blocks).
1262
+ const activeDisallowed = this.getExecutionState()?.disallowedGatewayTools;
1263
+ if (activeDisallowed?.includes(toolName) || this.disallowedGatewayTools.has(toolName)) {
1063
1264
  return {
1064
1265
  success: false,
1065
1266
  error: `Tool "${toolName}" is not available. Use delegate() to assign this work to the appropriate sub-agent.`,
@@ -1466,24 +1667,21 @@ class GatewayToolExecutor {
1466
1667
  if (!pagesInput || !Array.isArray(pagesInput)) {
1467
1668
  throw new types_js_1.AgentError('wiki_publish requires pages array', 'TOOL_ERROR', undefined, false);
1468
1669
  }
1469
- if (this.wikiPublisher) {
1470
- const now = new Date().toISOString();
1471
- const wikiPages = pagesInput.map((p) => ({
1472
- path: p.path,
1473
- title: p.title,
1474
- type: p.type || 'entity',
1475
- content: p.content,
1476
- sourceIds: [],
1477
- compiledAt: now,
1478
- confidence: p.confidence || 'medium',
1479
- }));
1480
- this.wikiPublisher(wikiPages);
1670
+ const adapter = this.wikiPublishAdapter ??
1671
+ (0, wiki_publish_adapter_js_1.createWikiPublishAdapter)({
1672
+ publisher: this.wikiPublisher,
1673
+ });
1674
+ try {
1675
+ const publishResult = adapter.publish({ pages: pagesInput });
1481
1676
  return {
1482
1677
  success: true,
1483
- message: `Wiki published: ${wikiPages.length} pages`,
1678
+ message: `Wiki published: ${publishResult.pagesPublished} pages`,
1679
+ artifactsStored: publishResult.artifactsStored,
1484
1680
  };
1485
1681
  }
1486
- throw new types_js_1.AgentError('Wiki publisher not configured', 'TOOL_ERROR', undefined, false);
1682
+ catch (error) {
1683
+ throw new types_js_1.AgentError(error instanceof Error ? error.message : 'Wiki publish failed', 'TOOL_ERROR', undefined, false);
1684
+ }
1487
1685
  }
1488
1686
  // Kagemusha query tools — progressive business data exploration
1489
1687
  case 'kagemusha_overview': {
@@ -1508,6 +1706,59 @@ class GatewayToolExecutor {
1508
1706
  }
1509
1707
  return { success: true, messages: queryMessages(msgInput) };
1510
1708
  }
1709
+ case 'task_list': {
1710
+ if (!this.taskLedger) {
1711
+ return { success: false, error: 'Task ledger not configured' };
1712
+ }
1713
+ const listInput = input;
1714
+ return {
1715
+ success: true,
1716
+ tasks: this.taskLedger.list({
1717
+ status: listInput.status,
1718
+ channel: listInput.channel,
1719
+ search: listInput.search,
1720
+ limit: listInput.limit,
1721
+ order: listInput.order ?? 'deadline_priority',
1722
+ }),
1723
+ };
1724
+ }
1725
+ case 'task_create': {
1726
+ if (!this.taskLedger) {
1727
+ return { success: false, error: 'Task ledger not configured' };
1728
+ }
1729
+ return {
1730
+ success: true,
1731
+ task: this.taskLedger.create(input),
1732
+ };
1733
+ }
1734
+ case 'task_update': {
1735
+ if (!this.taskLedger) {
1736
+ return { success: false, error: 'Task ledger not configured' };
1737
+ }
1738
+ const { id: rawId, ...patch } = input;
1739
+ // Agents routinely pass "12"; coerce, reject non-numeric with a typed error.
1740
+ const id = typeof rawId === 'string' ? Number(rawId.trim()) : rawId;
1741
+ if (!Number.isInteger(id) || id <= 0) {
1742
+ throw new types_js_1.AgentError(`task_update requires a numeric id, got: ${String(rawId)}`, 'TOOL_ERROR', undefined, false);
1743
+ }
1744
+ return {
1745
+ success: true,
1746
+ task: this.taskLedger.update(id, patch),
1747
+ };
1748
+ }
1749
+ case 'schedule_upcoming': {
1750
+ return this.executeScheduleUpcoming(input);
1751
+ }
1752
+ case 'contract_no_update': {
1753
+ if (!this.taskLedger) {
1754
+ return { success: false, error: 'Task ledger not configured' };
1755
+ }
1756
+ const { reason, scope } = input;
1757
+ if (!reason || !scope) {
1758
+ throw new types_js_1.AgentError('contract_no_update requires both reason and scope', 'TOOL_ERROR', undefined, false);
1759
+ }
1760
+ return { success: true, note: this.taskLedger.recordNoUpdate(scope, reason) };
1761
+ }
1511
1762
  case 'agent_notices': {
1512
1763
  const rawLimit = Number(input.limit);
1513
1764
  const limit = Number.isFinite(rawLimit)
@@ -2628,6 +2879,76 @@ class GatewayToolExecutor {
2628
2879
  };
2629
2880
  }
2630
2881
  }
2882
+ /**
2883
+ * schedule_upcoming (M8 P4): read the calendar connector's raw store and
2884
+ * return events in [now, now+days] plus a compact text digest. Lazy readonly
2885
+ * open (operator-handler pattern); prefers metadata JSON start when present.
2886
+ * v1 limits (documented in the tool description): no recurrence expansion,
2887
+ * no cancellation tracking.
2888
+ */
2889
+ scheduleDb = null;
2890
+ executeScheduleUpcoming(input) {
2891
+ const rawDays = Number(input.days);
2892
+ const days = Number.isFinite(rawDays) ? Math.max(1, Math.min(60, Math.floor(rawDays))) : 14;
2893
+ const dbPath = process.env.MAMA_CALENDAR_RAW_DB ??
2894
+ (0, path_1.join)((0, os_1.homedir)(), '.mama', 'connectors', 'calendar', 'raw.db');
2895
+ if (!this.scheduleDb) {
2896
+ if (!(0, fs_1.existsSync)(dbPath)) {
2897
+ return {
2898
+ success: false,
2899
+ error: 'Calendar connector raw store not found (is the calendar connector enabled?)',
2900
+ };
2901
+ }
2902
+ // Wrapper takes only (path); this handle is used for reads only.
2903
+ this.scheduleDb = new sqlite_js_1.default(dbPath);
2904
+ this.scheduleDb.prepare('PRAGMA busy_timeout = 5000').get();
2905
+ }
2906
+ const now = Date.now();
2907
+ const until = now + days * 86_400_000;
2908
+ let rows;
2909
+ try {
2910
+ rows = this.scheduleDb
2911
+ .prepare(`SELECT source_id, channel, content, timestamp, metadata
2912
+ FROM raw_items
2913
+ WHERE timestamp >= ? AND timestamp <= ?
2914
+ ORDER BY timestamp ASC
2915
+ LIMIT 50`)
2916
+ .all(now, until);
2917
+ }
2918
+ catch (err) {
2919
+ // Corrupt/locked store or missing table: fail closed with a readable
2920
+ // error and drop the cached handle so the next call can retry fresh.
2921
+ this.scheduleDb = null;
2922
+ return {
2923
+ success: false,
2924
+ error: `Calendar raw store unreadable: ${err instanceof Error ? err.message : String(err)}`,
2925
+ };
2926
+ }
2927
+ const events = rows.map((row) => {
2928
+ let start = row.timestamp;
2929
+ try {
2930
+ const meta = row.metadata ? JSON.parse(row.metadata) : null;
2931
+ const metaStart = meta?.start ?? meta?.startTime ?? meta?.start_time;
2932
+ if (typeof metaStart === 'string' || typeof metaStart === 'number') {
2933
+ const parsed = new Date(metaStart).getTime();
2934
+ if (Number.isFinite(parsed))
2935
+ start = parsed;
2936
+ }
2937
+ }
2938
+ catch {
2939
+ /* metadata is best-effort */
2940
+ }
2941
+ return {
2942
+ title: (row.content ?? '').split('\n')[0]?.slice(0, 120) ?? '',
2943
+ start: new Date(start).toISOString(),
2944
+ channel: row.channel,
2945
+ };
2946
+ });
2947
+ const text = events.length === 0
2948
+ ? `(no calendar events in the next ${days} days)`
2949
+ : events.map((e) => `- ${e.start.slice(0, 16)} ${e.title} (${e.channel})`).join('\n');
2950
+ return { success: true, events, text };
2951
+ }
2631
2952
  /**
2632
2953
  * Execute Obsidian CLI command on the wiki vault.
2633
2954
  */
@@ -2640,8 +2961,12 @@ class GatewayToolExecutor {
2640
2961
  };
2641
2962
  }
2642
2963
  // Obsidian CLI syntax: obsidian <command> key=value ... [flags]
2643
- // Vault is not passed as path Obsidian uses the default/focused vault
2964
+ // Without vault=<name> the CLI targets the FOCUSED vault, so wiki writes
2965
+ // could land in whatever vault the owner has open. Pin it when configured.
2644
2966
  const cliArgs = [command];
2967
+ if (this.obsidianVaultName) {
2968
+ cliArgs.push(`vault=${this.obsidianVaultName}`);
2969
+ }
2645
2970
  for (const [key, value] of Object.entries(args || {})) {
2646
2971
  if (value === 'true' && ['silent', 'overwrite', 'total'].includes(key)) {
2647
2972
  cliArgs.push(key);
@@ -2875,17 +3200,11 @@ class GatewayToolExecutor {
2875
3200
  error: 'query is required and recallMemory API must be available',
2876
3201
  };
2877
3202
  }
2878
- const context = this.getActiveContext();
2879
- const fallbackScopes = context
2880
- ? (0, scope_context_js_1.deriveMemoryScopes)({
2881
- source: context.source,
2882
- channelId: context.session.channelId,
2883
- userId: context.session.userId,
2884
- projectId: process.env.MAMA_WORKSPACE || process.cwd(),
2885
- })
2886
- : [];
2887
- const inputScopes = Array.isArray(input.scopes) ? input.scopes : [];
2888
- const scopes = inputScopes.length > 0 ? inputScopes : fallbackScopes;
3203
+ const scopeResolution = this.resolveMamaRecallScopes(input);
3204
+ if (scopeResolution.denial) {
3205
+ return scopeResolution.denial;
3206
+ }
3207
+ const scopes = scopeResolution.scopes;
2889
3208
  if (scopes.length === 0) {
2890
3209
  return {
2891
3210
  success: false,
@@ -2897,7 +3216,7 @@ class GatewayToolExecutor {
2897
3216
  scopes,
2898
3217
  includeProfile: true,
2899
3218
  });
2900
- return { success: true, bundle };
3219
+ return { success: true, bundle: sanitizeMamaRecallBundle(bundle) };
2901
3220
  }
2902
3221
  catch (err) {
2903
3222
  return {